Better Player

repository·master·Indexed 21 days ago

https://github.com/jhomlala/betterplayer

An advanced Flutter video player plugin built upon the Chewie plugin. It supports complex media requirements including HLS/DASH streaming, DRM, subtitles, and playlists. The library provides flexible implementation patterns via BetterPlayerController and BetterPlayerDataSource, with extensive configuration options for buffering (Android), caching, and UI customization through BetterPlayerControlsConfiguration.

Tokens
28.4K
Snippets
88
Records
108
Agent score
75%

What's inside betterplayer

  1. Overview of Better Player features

    master

    Better Player is a Flutter plugin based on Chewie, designed to fix common bugs and provide advanced configuration options for video playback. It is suitable for complex use cases requiring high levels of control over the player experience.

    Key Capabilities:

    • Format Support: HLS and DASH (including track, subtitle, and audio track selection), and standard video formats.
    • Subtitles: Supports SRT and WEBVTT (with HTML tag support), HLS-embedded subtitles, and multiple subtitle tracks.
    • Advanced Playback: Playback speed control, alternative resolution selection, playlist support, and Video in ListView support.
    • Media Handling: HTTP Headers support, BoxFit configuration, and Cache support.
    • Advanced Features: DRM support (Widevine, FairPlay EZDRM, and token-based), Picture in Picture (PiP), and Notifications support.
  2. Optimize video lists for performance and memory

    master

    When displaying lists of videos, consider the following performance and stability guidelines:

    Resource Management

    Each BetterPlayerController instance consumes significant device resources. On low-end hardware, creating too many instances can lead to crashes.

    • Short Lists: If the list is short, BetterPlayerListVideoPlayer is sufficient.
    • Long Lists: For long lists, you must use recycling/reusable techniques. Instead of creating a new controller for every item, create a small pool of 2-3 BetterPlayerController instances and reuse them as the user scrolls through the list.

    Preventing Out-of-Memory (OOM) issues

    If you encounter random OOM (Out-of-Memory) errors, try lowering the values in the bufferingConfiguration within your BetterPlayerDataSource to reduce the memory footprint of the video buffer.

  3. Understand default language behavior in Better Player

    master

    Better Player includes 8 pre-built languages:

    • EN (English)
    • PL (Polish)
    • ZH (Chinese Simplified)
    • HI (Hindi)
    • AR (Arabic)
    • TR (Turkish)
    • VI (Vietnamese)
    • ES (Spanish)

    If you do not provide a custom translations list, the player will default to EN translations. If a user's current locale matches one of the pre-built languages, that language will be used automatically.

  4. How BetterPlayerDataSource and BetterPlayerController work together

    master

    For advanced control and detailed configuration, use the 'Normal usage' pattern involving two main components:

    1. BetterPlayerDataSource: Defines the video source. This is where you specify the video URL, the BetterPlayerDataSourceType (e.g., .network), subtitles, and other media-specific metadata.
    2. BetterPlayerController: Acts as the manager for the video widget. It follows Flutter conventions to allow you to programmatically control the player, such as starting/stopping playback or adjusting volume.

    To use this pattern, you typically initialize both in the initState of your StatefulWidget and then pass the controller to a BetterPlayer widget in the build method.

    // 1. Initialize in initState
    @override
    void initState() {
      super.initState();
      BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
          BetterPlayerDataSourceType.network,
          "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4");
      _betterPlayerController = BetterPlayerController(
          BetterPlayerConfiguration(),
          betterPlayerDataSource: betterPlayerDataSource);
    }
    
    // 2. Use in build
    @override
    Widget build(BuildContext context) {
      return AspectRatio(
        aspectRatio: 16 / 9,
        child: BetterPlayer(
          controller: _betterPlayerController,
        ),
      );
    }
  5. Important information regarding Better Player development

    master

    Better Player is an actively developed plugin. Users should be aware that:

    • Breaking Changes: Development is in progress, and you may encounter breaking changes between versions.
    • Contributions: The project is developed part-time. If a feature you need is missing, you are encouraged to contribute via Pull Requests.
  6. How BetterPlayerController and BetterPlayerDataSource work together

    master

    For advanced control and detailed configuration, you must use the BetterPlayerController and BetterPlayerDataSource pattern instead of the basic factory methods.

    Core Abstractions

    • BetterPlayerDataSource: Defines the video source. This is where you specify the video URL, the BetterPlayerDataSourceType (e.g., .network), subtitles, and other media-specific metadata.
    • BetterPlayerController: Acts as the manager for the video widget. It follows Flutter conventions to allow you to programmatically control the player, such as starting/stopping playback, adjusting volume, and more.

    Implementation Workflow

    1. Initialize both the BetterPlayerDataSource and the BetterPlayerController within the initState() method of your StatefulWidget.
    2. Pass the initialized BetterPlayerController to the BetterPlayer widget inside your build() method.
    BetterPlayerController _betterPlayerController;
    
    @override
    void initState() {
      super.initState();
      BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
          BetterPlayerDataSourceType.network,
          "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4");
      _betterPlayerController = BetterPlayerController(
          BetterPlayerConfiguration(),
          betterPlayerDataSource: betterPlayerDataSource);
    }
    
    @override
    Widget build(BuildContext context) {
      return AspectRatio(
        aspectRatio: 16 / 9,
        child: BetterPlayer(
          controller: _betterPlayerController,
        ),
      );
    }
  7. Get started with Better Player

    master

    To begin using Better Player, follow the documentation hierarchy starting from the core setup and moving through specific usage patterns:

    1. Setup: Follow the Install guide.
    2. Core Usage: Choose a player pattern based on your needs:
      • General player usage: For standard single-video playback.
      • Playlist player usage: For playing a sequence of videos.
      • List player usage: For managing video lists.
    3. Customization: Configure specific aspects of the player such as controls, subtitles, cache, DRM, or buffering.
  8. Configure iOS for Better Player

    master

    The following settings are required for Better Player to run on iOS:

    • Set the project deployment target to min. iOS 11.0.
    • Set the Swift version to 5.

    Optional: Enable Full Screen Rotation To allow Better Player to rotate the screen to a horizontal position when full screen is enabled, add the following to your info.plist:

    <key>UISupportedInterfaceOrientations</key>
    <array>
       <string>UIInterfaceOrientationPortrait</string>
       <string>UIInterfaceOrientationLandscapeLeft</string>
       <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
  9. Customize the iOS launch screen assets

    master

    To change the image displayed during the app's launch on iOS, you can replace the existing image files in the example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.

    Alternatively, you can manage these assets using Xcode:

    1. Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace
  10. Override the video fit aspect ratio at runtime

    master

    You can change the video''s aspect ratio fitting behavior after the player has been initialized by using the setOverriddenFit method on the BetterPlayerController instance. This allows you to switch between different BoxFit values (such as BoxFit.contain, BoxFit.cover, etc.) dynamically during playback.

    betterPlayerController.setOverriddenFit(BoxFit.contain);
  11. Configure translations with BetterPlayerTranslations

    master

    To support multiple languages in the player UI, provide a list of BetterPlayerTranslations objects to the translations property within BetterPlayerConfiguration.

    Each BetterPlayerTranslations instance requires a languageCode (e.g., "pl", "cz") and allows you to override specific UI strings such as error messages, menu items, and control labels.

    Note: You must first set up Flutter's standard localization in your app for these translations to function correctly. Refer to the official Flutter internationalization guide for setup instructions.

    BetterPlayerConfiguration( 
      translations: [
        BetterPlayerTranslations(
          languageCode: "pl",
          generalDefaultError: "translated text",
          generalNone: "translated text",
          generalDefault: "translated text",
          playlistLoadingNextVideo: "translated text",
          controlsLive: "translated text",
          controlsNextVideoIn: "translated text",
          overflowMenuPlaybackSpeed: "translated text",
          overflowMenuSubtitles: "translated text",
          overflowMenuQuality: "translated text",
        ),
        BetterPlayerTranslations(
          languageCode: "cz",
          generalDefaultError: "translated text",
          // ... other fields
        ),
      ],
    )