flutter_smart_video_player 1.0.0
flutter_smart_video_player: ^1.0.0 copied to clipboard
A fully customizable YouTube video player using WebView and IFrame API. Works seamlessly inside dynamic UI rendering systems.
flutter_smart_video_player #
A production-ready, fully customizable YouTube video player Flutter package built on WebView + YouTube IFrame API. Designed for dynamic UI rendering systems.
โจ Features #
- ๐ฌ YouTube playback from any standard YouTube URL
- ๐บ Flutter-controlled fullscreen (landscape lock, smooth transition)
- ๐ฎ Custom controls โ play/pause, seek bar, time labels, fullscreen toggle
- ๐ Dynamic rendering safe โ survives rebuilds, no unnecessary restarts
- ๐ Multiple instances โ isolated controllers, no WebView conflicts
- ๐๏ธ External controller API โ programmatically control playback
- ๐ง Custom controls builder โ replace the default UI entirely
- โก Lifecycle aware โ pauses on app background/dispose
- โ Graceful error handling โ invalid URLs, unavailable videos
๐ Installation #
Add to your pubspec.yaml:
dependencies:
flutter_smart_video_player: ^1.0.0
Android setup #
In android/app/src/main/AndroidManifest.xml, add inside <application>:
<application
android:usesCleartextTraffic="true"
...>
Also ensure minSdkVersion is at least 19 in android/app/build.gradle.
iOS setup #
In ios/Runner/Info.plist, add:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
๐ Usage #
Basic โ just a URL #
import 'package:flutter_smart_video_player/flutter_smart_video_player.dart';
SmartVideoPlayer(
url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
)
Supports all YouTube URL formats:
https://www.youtube.com/watch?v=VIDEO_IDhttps://youtu.be/VIDEO_IDhttps://www.youtube.com/embed/VIDEO_IDhttps://www.youtube.com/shorts/VIDEO_ID- Raw
VIDEO_ID(11 chars)
With configuration #
SmartVideoPlayer(
url: 'https://youtu.be/dQw4w9WgXcQ',
config: const SmartVideoConfig(
autoPlay: true,
showControls: true,
aspectRatio: 16 / 9,
backgroundColor: Colors.black,
allowFullscreen: true,
),
)
With external controller #
final controller = SmartVideoController();
@override
void dispose() {
controller.dispose();
super.dispose();
}
// In your widget:
SmartVideoPlayer(
url: 'https://youtu.be/dQw4w9WgXcQ',
controller: controller,
)
// Control from anywhere:
controller.play();
controller.pause();
controller.seekTo(const Duration(seconds: 30));
React to state changes #
ValueListenableBuilder<SmartVideoState>(
valueListenable: controller,
builder: (context, state, _) {
return Text('${state.positionLabel} / ${state.durationLabel}');
},
)
Custom controls UI #
SmartVideoPlayer(
url: url,
config: const SmartVideoConfig(showControls: false),
customControlsBuilder: (context, controller, state) {
return MyCustomControls(controller: controller, state: state);
},
)
Dynamic rendering system (your use case) #
Widget buildComponent(Map<String, dynamic> item) {
switch (item['type']) {
case 'ytVideo':
return SmartVideoPlayer(url: item['data']);
case 'text':
return Text(item['data']);
// ...other types
}
}
๐๏ธ API Reference #
SmartVideoPlayer #
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
String |
required | YouTube URL |
controller |
SmartVideoController? |
auto | External controller |
config |
SmartVideoConfig |
default | Player configuration |
customControlsBuilder |
Widget Function(...)? |
null | Custom controls overlay |
SmartVideoConfig #
| Property | Type | Default | Description |
|---|---|---|---|
autoPlay |
bool |
false |
Auto-start on ready |
showControls |
bool |
true |
Show built-in controls |
backgroundColor |
Color |
Colors.black |
BG behind WebView |
aspectRatio |
double |
16/9 |
Player container ratio |
allowFullscreen |
bool |
true |
Enable fullscreen button |
showAnnotations |
bool |
false |
YouTube annotations |
showRelatedVideos |
bool |
false |
Related videos on end |
SmartVideoController #
| Method | Description |
|---|---|
play() |
Start/resume playback |
pause() |
Pause playback |
seekTo(Duration) |
Jump to position |
enterFullscreen() |
Enter fullscreen |
exitFullscreen() |
Exit fullscreen |
dispose() |
Cleanup resources |
SmartVideoState #
| Property | Type | Description |
|---|---|---|
isPlaying |
bool |
Currently playing |
isReady |
bool |
Player initialized |
isBuffering |
bool |
Currently buffering |
isFullscreen |
bool |
In fullscreen mode |
position |
Duration |
Current position |
duration |
Duration |
Total duration |
progress |
double |
Progress 0.0โ1.0 |
positionLabel |
String |
mm:ss position |
durationLabel |
String |
mm:ss duration |
error |
String? |
Error message or null |
๐ Architecture #
lib/
โโโ flutter_smart_video_player.dart # Public exports
โโโ src/
โโโ controller/
โ โโโ smart_video_controller.dart # ValueNotifier controller + JS bridge
โโโ models/
โ โโโ smart_video_state.dart # Immutable state object
โ โโโ smart_video_config.dart # Configuration options
โโโ js/
โ โโโ player_html.dart # YouTube IFrame HTML+JS builder
โโโ view/
โ โโโ smart_video_view.dart # InAppWebView + JS handler registration
โโโ player/
โ โโโ flutter_smart_video_player.dart # Public widget (composes all layers)
โโโ fullscreen/
โ โโโ fullscreen_page.dart # Fullscreen navigator page
โโโ widgets/
โ โโโ controls.dart # Default controls overlay UI
โโโ utils/
โโโ youtube_parser.dart # YouTube URL โ video ID parser
๐ง How It Works #
- URL Parsing:
YoutubeParserextracts the video ID from any YouTube URL format - HTML Generation:
PlayerHtmlbuilds a self-contained HTML page embedding the YouTube IFrame API - WebView:
SmartVideoViewhosts the WebView, loads the HTML, and registers JS message handlers - JS Bridge: Events from the IFrame (
onReady,onStateChange,onProgress,onError) are sent to Flutter viaflutter_inappwebview.callHandler() - Controller:
SmartVideoControllerexposes state viaValueNotifierand dispatches JS commands back to the WebView - Fullscreen: Uses
Navigator.push()to a dedicated page, reusing the same controller โ no video restart
๐งช Testing #
flutter test
๐ Manual Testing Checklist #
- โ Android real device โ play/pause/seek
- โ iOS real device โ play/pause/seek
- โ Fullscreen enter/exit (portrait restore)
- โ Back button in fullscreen
- โ Multiple players on same screen
- โ Scroll list โ players don't restart
- โ Dynamic rebuild โ players survive
- โ Invalid URL โ error shown gracefully
- โ Private video โ error shown gracefully
- โ App background โ video pauses
๐ฆ Publishing #
dart pub publish --dry-run # Check for issues
dart pub publish # Publish to pub.dev
๐ License #
MIT โ see LICENSE