youtube_player_iframe 6.0.0
youtube_player_iframe: ^6.0.0 copied to clipboard
Flutter port of the official YouTube iFrame player API. Supports Android, iOS, macOS & Web.
Youtube Player iFrame
๐ฌ Embed YouTube videos in your Flutter app โ inline, silky smooth, and with zero API key hassle. Powered by the official iFrame Player API, this plugin gives you near-complete control over playback without any of the headaches.
โจ Features #
| ๐ฏ | What it does |
|---|---|
| ๐บ Inline Playback | Videos play right inside your app โ no pop-outs, no surprises |
| ๐ No API Key | Just plug and play. Seriously, no keys needed |
| ๐ฌ Caption Support | Full subtitle/caption support for accessibility |
| ๐ฎ Custom Controls | Build your own UI with YoutubeValueBuilder |
| ๐ Metadata Retrieval | Fetch detailed info about any video |
| ๐ด Live Stream Support | Works with live streams too |
| โฉ Adjustable Playback Speed | Slow-mo or 2ร speed โ your call |
| ๐ Playlist Support | Native YouTube playlists + custom ones |
| ๐ฅ๏ธ Smooth Fullscreen | Auto-enters on landscape rotation, swipe up/down gesture support |
| ๐ผ๏ธ Lazy Thumbnail Widget | Shows a thumbnail first, creates the WebView only on tap โ perfect for lists |
| ๐ต๏ธ Privacy-Enhanced Mode | Uses youtube-nocookie.com by default so YouTube doesn't track your users |
| ๐ Multi-Platform | Android, iOS, macOS, and Web โ all covered |
๐ก Under the hood, this package uses webview_flutter.
๐ ๏ธ Setup #
Before diving in, check out the webview_flutter docs for any platform-specific setup (Android permissions, iOS config, etc.).
๐ Quick Start #
1๏ธโฃ Create a controller #
final _controller = YoutubePlayerController(
params: YoutubePlayerParams(
mute: false,
showControls: true,
showFullscreenButton: true,
privacyEnhancedMode: true, // uses youtube-nocookie.com (default)
),
);
_controller.loadVideoById(videoId: '<video-id>'); // โถ๏ธ auto-play
_controller.cueVideoById(videoId: '<video-id>'); // โธ๏ธ ready but paused
_controller.loadPlaylist(list: [...]); // โถ๏ธ auto-play playlist
_controller.cuePlaylist(list: [...]); // โธ๏ธ playlist, paused
๐ฌ Shortcut: For a single video, use the convenience constructor:
final _controller = YoutubePlayerController.fromVideoId(
videoId: '<video-id>',
autoPlay: false,
params: const YoutubePlayerParams(showFullscreenButton: true),
);
2๏ธโฃ Drop the player in your widget tree #
No wrapper widgets, no special scaffolding โ just drop it in and go. Fullscreen is handled internally. ๐
YoutubePlayer(
controller: _controller,
aspectRatio: 16 / 9,
autoFullScreen: true, // ๐ฑ auto-enters fullscreen on landscape rotation
)
3๏ธโฃ Clean up when done #
@override
void dispose() {
_controller.close();
super.dispose();
}
๐ฅ๏ธ Fullscreen #
Fullscreen is smooth and just works on all platforms. The player intercepts the fullscreen button and handles the whole transition inside Flutter.
| ๐ฌ Trigger | ๐ What happens |
|---|---|
| Tap fullscreen button | Animates to fullscreen |
| Rotate device to landscape | Auto-enters fullscreen (autoFullScreen: true) |
| Swipe up in player | Enters fullscreen |
| Swipe down in fullscreen | Exits fullscreen |
| Back button / system gesture | Exits fullscreen |
๐ผ๏ธ Lazy Thumbnail (Great for Lists!) #
Got a list of videos? Don't create a WebView for every item โ that's expensive! ๐ธ
YoutubePlayerThumbnail shows a crisp thumbnail image and only spins up the WebView when the user taps. Smooth scrolling, happy users. ๐
YoutubePlayerThumbnail(
controller: YoutubePlayerController.fromVideoId(videoId: '<video-id>'),
aspectRatio: 16 / 9,
thumbnailQuality: ThumbnailQuality.high,
thumbnailFormat: ThumbnailFormat.webp,
// Optional: bring your own play icon ๐จ
// playIcon: const Icon(Icons.play_circle, size: 64, color: Colors.white),
)
Need just the thumbnail URL? No problem:
final url = YoutubePlayerController.getThumbnail(
videoId: '<video-id>',
quality: ThumbnailQuality.high,
format: ThumbnailFormat.webp,
);
๐ฒ Expose the Controller Down the Tree #
Use YoutubePlayerControllerProvider to make the controller available to any descendant widget via context.ytController. No prop drilling needed! ๐
YoutubePlayerControllerProvider(
controller: _controller,
child: Scaffold(
body: Column(
children: [
YoutubePlayer(controller: _controller),
const Controls(), // ๐๏ธ can call context.ytController inside
],
),
),
);
๐๏ธ Custom Controls #
YoutubeValueBuilder rebuilds whenever the player state changes โ making it super easy to build any custom playback control you dream up.
YoutubeValueBuilder(
controller: _controller, // omit if using YoutubePlayerControllerProvider
builder: (context, value) {
return IconButton(
icon: Icon(
value.playerState == PlayerState.playing
? Icons.pause
: Icons.play_arrow,
),
onPressed: value.isReady
? () {
value.playerState == PlayerState.playing
? context.ytController.pause()
: context.ytController.play();
}
: null,
);
},
);
โ๏ธ Player Parameters #
Tweak everything to match your app's vibe:
| Parameter | Type | Default | Description |
|---|---|---|---|
mute |
bool |
false |
๐ Start muted |
showControls |
bool |
true |
๐ฎ Show YouTube's built-in controls |
showFullscreenButton |
bool |
false |
โถ Show YouTube's fullscreen button |
privacyEnhancedMode |
bool |
true |
๐ต๏ธ Use youtube-nocookie.com |
loop |
bool |
false |
๐ Loop the video |
strictRelatedVideos |
bool |
false |
๐ Related videos from same channel only |
enableCaption |
bool |
true |
๐ฌ Show captions by default |
captionLanguage |
String |
'en' |
๐ Caption language (ISO 639-1) |
interfaceLanguage |
String |
'en' |
๐ Player UI language (ISO 639-1) |
color |
String |
'white' |
๐จ Progress bar colour ('red' or 'white') |
enableKeyboard |
bool |
web only | โจ๏ธ Keyboard shortcuts |
playsInline |
bool |
true |
๐ฑ Inline playback on iOS |
userAgent |
String? |
null |
๐ค Custom WebView user agent |
pointerEvents |
PointerEvents |
initial |
๐ CSS pointer-events on the player |
origin |
String? |
null |
๐ Security origin for the iFrame API |
Use copyWith to tweak an existing config without rebuilding from scratch:
final params = const YoutubePlayerParams(showControls: false);
final updated = params.copyWith(mute: true);
๐ Migrating from YoutubePlayerScaffold #
YoutubePlayerScaffold is deprecated โ YoutubePlayer handles fullscreen on its own now. Here's how to update:
// โ Before (old way)
YoutubePlayerScaffold(
controller: _controller,
builder: (context, player) {
return Scaffold(
body: Column(children: [player, const Controls()]),
);
},
)
// โ
After (new way)
YoutubePlayerControllerProvider(
controller: _controller,
child: Scaffold(
body: Column(
children: [
YoutubePlayer(controller: _controller),
const Controls(),
],
),
),
)
๐งช Try the Example App #
See everything in action โ check out the example app for complete working code.

