omni_video_player
一个用于从 YouTube、Vimeo、资源文件和网络源播放视频的 Flutter 小部件——完全可自定义且易于集成。
一个用于从 YouTube、Vimeo、资源和网络源播放视频的 Flutter 小部件 — 完全可自定义且易于集成
{"sdk":"flutter"}^2.11.1^2.9.5^1.4.0^3.4.0+1^0.4.0+2^3.5.0^1.6.0^1.1.1^3.1.0^6.1.5{"sdk":"flutter"}^6.0.0^6.9.0^9.0.2以下为英文项目原文快照,最新内容请访问 GitHub。
The ultimate All-in-One Flutter video solution. Stream YouTube, Vimeo, HLS, and local files with a single, unified controller.
pub version pub points pub popularity
Stop juggling multiple packages for different video sources. omni_video_player wraps the complexity of specialized extractors and webviews into a single, powerful widget.
youtube_explode_dart with an automatic WebView fallback. The player seamlessly switches to WebView if the primary method fails, ensuring uninterrupted playback and no black screens for your users.| Source / Format | Android | iOS | WebView (Android & iOS - alt/fallback) | Web | Notes |
|---|---|---|---|---|---|
| YouTube | ✅ | ✅ | ✅ | ✅ | Auto-fallback to WebView on primary method fails. |
| Vimeo | - | - | ✅ | ✅ | High stability via WebView. |
| HLS (.m3u8) | ✅ | ✅ | - | ✅ | Multi-quality switching supported. |
| Network (.mp4/etc) | ✅ | ✅ | - | ✅ | Standard streaming. |
| Assets/Files | ✅ | ✅ | - | ✅ | Local storage & bundle support. |
| AVI | ✅ | ❌ | - | ✅ | Not supported on iOS (OS limitation). |
| WebM | ✅ | ❌ | ✅ | ✅ | Requires WebView on iOS (no native support); seeking is disabled on iOS (WebKit can't seek WebM without freezing). |
| YouTube | YouTube Live |
| YouTube | YouTube Live |
| M3U8 Network Link | Vimeo |
| M3U8 | Vimeo |
Add this to your pubspec.yaml:
dependencies:
omni_video_player: ^latest_version
Configure these only if your use case requires it:
AndroidManifest.xml)http links.<manifest>
<uses-permission android:name="android.permission.INTERNET"/> <application android:usesCleartextTraffic="true"> ...
</application>
</manifest>
Info.plist)http links.<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/> </dict>
Note: If you use only
https(standard for YouTube/Vimeo) and local assets, you can skip the Cleartext/Arbitrary Loads settings.
OmniVideoPlayer(
sourceConfiguration: VideoSourceConfiguration.youtube(
videoUrl: Uri.parse('https://www.youtube.com/watch?v=dQw4w9WgXcQ'),
preferredQualities: [OmniVideoQuality.high720],
),
)
Want to see the player in action with all its features? We have provided a comprehensive example project.
example/ folder.lib/main.dart on your device or emulator.This demo showcases everything the library supports: quality switching, source transitions, custom controls, and more. It is the best way to understand the full potential of omni_video_player.
Control the player from anywhere in your widget tree:
OmniPlaybackController? _controller;
// Listen to state changes (play/pause, buffering, etc.)
void _onUpdate() => setState(() {});
OmniVideoPlayer(
callbacks: VideoPlayerCallbacks(
onControllerCreated: (controller) {
_controller = controller..addListener(_onUpdate);
},
),
);
@override
void dispose() {
_controller?.removeListener(_onUpdate);
super.dispose();
}
Play an ordered queue of videos with on-video previous/next buttons. Set autoAdvance to move to the next video automatically when one finishes, and loop to wrap around the ends:
OmniVideoPlaylist(
playlistConfiguration: PlaylistConfiguration(
autoAdvance: true,
loop: true,
items: [
VideoSourceConfiguration.youtube(
videoUrl: Uri.parse('https://www.youtube.com/watch?v=djV11Xbc914'),
),
VideoSourceConfiguration.youtube(
videoUrl: Uri.parse('https://www.youtube.com/watch?v=Zi_XLOBDo_Y'),
),
VideoSourceConfiguration.youtube(
videoUrl: Uri.parse('https://www.youtube.com/watch?v=fJ9rUzIMcZQ'),
),
],
),
playerConfiguration: VideoPlayerConfiguration(
videoSourceConfiguration: VideoSourceConfiguration.youtube(
videoUrl: Uri.parse('https://www.youtube.com/watch?v=djV11Xbc914'),
),
),
callbacks: VideoPlayerCallbacks(),
playlistCallbacks: PlaylistCallbacks(
onVideoChanged: (index) => debugPrint('Playlist: now at $index'),
onPlaylistCompleted: () => debugPrint('Playlist: completed'),
),
)
Only one audible player plays at a time: starting an audible player pauses the audible one before it. Muted players sit outside that rule — any number of them play together, and unmuting one makes it join the rule, pausing whoever was audible at that moment. Muting a playing video releases it from the rule without stopping it.
A player holds the wakelock while it is audible or fullscreen, so a list of decorative muted loops does not keep the device awake, while a video you muted and kept watching full screen still does.
For a row or list of muted looping videos, set autoPlay: true and autoMuteOnStart: true, and leave pauseWhenOutOfView at its default: playback starts when the player is fully visible and stops when it scrolls away. onFinished fires once at the real end of every playback and re-arms afterwards, so it can drive a "play N times" counter.
A player given an explicit initialVolume keeps it. The shared volume no longer overwrites it when the player is created, and later changes to the shared volume still reach it unless synchronizeMuteAcrossPlayers is false. When both are set, autoMuteOnStart wins and initialVolume becomes the level the player returns to once unmuted.
| Feature | Description | Status |
|---|---|---|
| Picture-in-Picture | Play in floating overlay (OS level). | 🏗️ Researching |
| Playlist Support | Queue system for multiple videos. | ✅ (4.0.0) |
| Download Mode | Cache management for offline viewing. | 🔜 Planned |
| Cast Support | Google Cast & AirPlay integration. | 🔜 Planned |
Youtube videos marked as "Made for Kids" in YouTube Studio cannot be played using the default extraction method on mobile platforms (iOS/Android) due to API restrictions.
forceYoutubeWebViewOnly: true. This bypasses the default extraction and plays the video via WebView.On Android, we can handle separate Audio and Video streams provided by the API, allowing for multiple quality options.
WebM has no native iOS support, so it plays through a WebView. WebKit, however, cannot seek a WebM stream without freezing the decoder (the frame stalls and can't recover). To avoid a broken state, seeking is disabled for WebM on iOS: the seek bar and skip gestures are turned off, while play/pause and duration work normally. WebM seeking works on Android (native playback).
Released under the BSD 3-Clause License. See LICENSE for details.
Built with ❤️ by Leonard Matasel Found a bug? Open an issue or submit a PR!