Packages like youtube_player_flutter
and youtube_player_iframe
don't play youtube videos on windows flutter application. The first package says it support windows, but we have always got controller is not ready for method calls and video never plays.
yt-dlp
which converts youtube video links to direct video linksfor example: if you wanna play some youtube video that has this link : https://www.youtube.com/watch?v=lllllllllll
Note the above youtube link is an arbitrary link and it may be wrong link, this program can take this link and converts it to a direct video link, generally direct video links end with valid video extensions like .mp4
.
You can find this program on its repo right here.
go to release section and download the .exe
installer to install it on your windows machine.
remember to add the path of the program (where .exe
file exists) to the System Environment variables of your OS
, so the OS
can recognize the program's commands when used on cmd.
Now you can run the program through cmd and convert youtube links to direct video links.
You should ensure the yt-dlp
program correctly works on OS
cmd before making your flutter app interact with it.
So far so good, it's just a program.
How will the flutter windows app deal with this program to play youtube videos?
The answer is simple, your flutter app should encapsulate this program within its assets to use it when needed, it's a utility program for your app.
in your assets
directory, create a directory called programs
and put yt-dlp.exe within, and for sure add it to your yaml
file.
run flutter pub get
command
Now the flutter app sees the yt-dpl
program.
Suppose you have a button when pressed it goes to a video screen to play a youtube video:
the video screen should make sure firstly the yt-dlp
exists to use it through this function, the function just stores the program within the temp directory of the OS
, finally it saves the path of the program to run it later.
Future<void> _prepareYtDlp() async {
final tempDir = Directory.systemTemp;
final file = File('${tempDir.path}/yt-dlp.exe');
if (!file.existsSync()) {
final bytes = await rootBundle.load('assets/programs/yt-dlp.exe');
await file.writeAsBytes(bytes.buffer.asUint8List(), flush: true);
await Process.run('chmod', ['+x', file.path]).catchError((e) {
print('i caught an error: $e');
});
}
ytDlpPath = file.path;
}
Now, you have the yt-dlp exists on the machine (user machine), your flutter app should call this program to get the direct video link through this method:
Future<String?> _getYoutubeDirectUrl(String youtubeVideoLink) async {
final result = await Process.run(ytDlpPath, [
'-f',
'best[ext=mp4][height<=720]', // decide required video quality
'-g',
youtubeVideoLink,
]);
if (result.exitCode == 0) {
return result.stdout.toString().trim();
} else {
debugPrint('yt-dlp failed: ${result.stderr}');
return null;
}
}
this method runs the yt-dlp within the cmd and passes arguments such as youtubeVideoLink
and the required video quality within the convert command.
Generally it takes around 10 seconds to return the direct video link.
Now you are ready, you have a direct video link not a youtube link, you can use any media player package that support windows app just like media-kit
and media_kit_video
to play the video through its link.
This's just a demo exmple from the package docs:
class MyScreen extends StatefulWidget {
const MyScreen({Key? key}) : super(key: key);
@override
State<MyScreen> createState() => MyScreenState();
}
class MyScreenState extends State<MyScreen> {
late final player = Player();
late final controller = VideoController(player);
@override
void initState() {
super.initState();
player.open(Media(ytdlpVideoLink));
}
@override
void dispose() {
player.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width * 9.0 / 16.0,
// Use [Video] widget to display video output.
child: Video(controller: controller),
),
);
}
}
All you need to do, is to merge the 2 methods _prepareYtDlp()
and _getYoutubeDirectUrl(String youtubeVideoLink)
within the above MyScreen
class to play the video, and you are done.
Important Note:
I have tried this scenario with windows
OS
and it worked, if you are targeting linux or macOSOS
s through flutter and you didn't find a direct way to play youtube videos on these platforms, you should download theyt-dlp
program that's compatible with thoseOS
s and follow the same idea. it should work.