Better Player

The most advanced and feature-rich video player for Flutter.

pub package pub package pub package

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.

IMPORTANT Migrating 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 BetterPlayerController in initState() and provide a PlayerConfiguration and PlayerDataSource.
  • 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 PlayerSubtitlesSource directly into PlayerDataSource.
  • Disposal: Avoid using controller.dispose() manually unless you set autoDispose: 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.

Let's talk on LinkedIn →

Libraries

better_player