Better Player
The most advanced and feature-rich video player for Flutter.
Better Player is a powerful video player for Flutter, originally based on the official video_player plugin but now fully independent. It solves common playback issues, provides extensive configuration options, and handles complex media use cases out of the box.
IMPORTANTMigrating from 0.0.84 to 1.x.x? See the Migration Guide to learn how to upgrade your project.
📱 Visual Showcase
![]() |
![]() |
![]() |
![]() |
| Default Controls | Settings Menu | Audio Tracks | Event Listener |
🚀 Key Features
🎬 Advanced Playback
- Adaptive Streaming: Full support for HLS (Android & iOS), DASH (Android), and Smooth Streaming (Android) with track selection.
- Resolution Control: Easy switching between alternative video resolutions.
- Smart Caching: Seamlessly cache videos for high-performance offline playback.
- Customizable UI: Refactored controls that are highly customizable via configuration.
🛡️ Content Protection & Security
- DRM Support: Industry-standard protection with Widevine, FairPlay, and ClearKey.
- Secured Requests: Full support for custom HTTP Headers for authenticated streams.
📱 User Experience
- Picture in Picture (PiP): Native PiP support for multitasking on Android and iOS.
- Background Notifications: Rich media notifications for background control.
- Subtitle Engine: Advanced support for SRT and WebVTT with HTML tags.
- Playlist Support: Built-in support for multiple videos and continuous playback.
- Playback Speed: Native support for changing playback speed.
🛠️ Developer Friendly
- ListView Integration: Optimized for smooth playback within scrolling lists.
- Lifecycle Aware: Automatically handles player disposal and lifecycle changes.
- Event System: Comprehensive event listener for tracking every player state.
📦 Quick Start
1. Add dependency
Add Better Player to your pubspec.yaml:
dependencies:
better_player: ^1.10.0
2. Basic Usage
The simplest way to play a video is using the network factory:
import 'package:better_player/better_player.dart';
// Inside your build method
AspectRatio(
aspectRatio: 16 / 9,
child: BetterPlayer.network(
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
betterPlayerConfiguration: PlayerConfiguration(
aspectRatio: 16 / 9,
looping: true,
autoPlay: true,
),
),
)
4. Web Setup
To use Better Player on the web, you must include the Shaka Player library in your web/index.html file before the closing </body> tag:
<script src="https://cdn.jsdelivr.net/npm/shaka-player@4/dist/shaka-player.compiled.js"></script>
5. Advanced Controller Usage
For full control, use the BetterPlayerController:
BetterPlayerController _controller = BetterPlayerController(
const PlayerConfiguration(),
betterPlayerDataSource: PlayerDataSource(
DataSourceType.network,
"https://example.com/video.mp4",
),
);
BetterPlayer(controller: _controller)
🏆 vs Competitors
| Feature | Better Player | video_player | chewie | media_kit |
|---|---|---|---|---|
| Underlying Engine | ExoPlayer/AVPlayer/Shaka | ExoPlayer/AVPlayer | video_player | libmpv |
| All-in-one Controls | ✅ Built-in & Customizable | ❌ No UI | ✅ Built-in | ✅ Built-in |
| HLS / DASH Support | ✅ Native | ⚠️ Basic | ⚠️ Basic | ✅ Native |
| DRM Support | ✅ Widevine/FairPlay/ClearKey | ❌ None | ❌ None | ❌ None |
| Subtitle Parsing | ✅ Advanced (WebVTT, HTML, SRT) | ⚠️ Basic (SRT only) | ⚠️ Basic | ✅ Advanced |
| Caching/Pre-caching | ✅ Built-in | ❌ None | ❌ None | ❌ None |
| Playlists | ✅ Built-in | ❌ None | ❌ None | ✅ Built-in |
🤖 AI Agent Quick Reference
If you are an AI coding assistant, use this quick reference when generating code for Better Player:
- Initialization: Always initialize
BetterPlayerControllerininitState()and provide aPlayerConfigurationandPlayerDataSource. - Core Classes:
BetterPlayerController: Manages state and configuration.PlayerDataSource: Wraps video URL, DRM config, subtitles, headers.PlayerConfiguration: UI, looping, autoPlay, aspect ratio.PlayerControlsConfiguration: Colors, icons, padding for the control bar.
- Subtitles: Pass
PlayerSubtitlesSourcedirectly intoPlayerDataSource. - Disposal: Avoid using
controller.dispose()manually unless you setautoDispose: false. It disposes automatically by default.
🔄 Migration Guides
Switching from another package? Check out our step-by-step migration guides:
📖 Resources
🤝 Contributing
Valuable contributions are welcome! Better Player is a community-driven project. If you encounter bugs or have feature requests, please open an issue. If you want to contribute code, feel free to submit a Pull Request.
💼 Custom Integrations & Enterprise Support
Better Player has been the go-to Flutter video player since its first release, powering countless applications. If your team needs something beyond what's available out of the box — a custom video source adapter, bespoke DRM implementations, tailored UI controls, specialized caching architectures, or anything else — I'm available for consulting.



