zeroratehls 1.0.5 copy "zeroratehls: ^1.0.5" to clipboard
zeroratehls: ^1.0.5 copied to clipboard

A comprehensive Flutter SDK for seamless HLS (HTTP Live Streaming) video playback. This package provides a robust, feature-rich player with advanced capabilities including adaptive bitrate streaming, [...]

zeroratehls #

A robust HLS video player SDK with built-in quality switching, live stream support for flutter.

Features #

  • Cross-platform support: Android, iOS, and Linux
  • Supports HLS & MP4 video and audio playback
  • Adaptive bitrate streaming
  • Handles live and on-demand streaming
  • Preview frames while seeking through the video(Android, iOS,)
  • Live stream support with DVR
  • Customizable UI components
  • Dynamic source switching
  • Linux optimization for TV platforms

Platform Support #

Platform Video Playback Audio Playback Seek Preview Picture-in-Picture
Android
iOS
Linux

Installation #

Add zeroratehls to your pubspec.yaml file:

dependencies:
  zeroratehls: ^1.0.5

Run the install command:

flutter pub get

Setup #

Basic Setup #

All platforms require SDK initialization in your main function:

import 'package:zeroratehls/zerorate_hls_player.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  ZerorateHlsSDK.initialize(); // Required for cross-platform support
  
  runApp(MyApp());
}

Android Setup #

For Android, add the following to your AndroidManifest.xml file (required for HTTP streams):

<application
    android:usesCleartextTraffic="true"
    ...>

Linux Setup #

Linux support is automatically configured when you call ZerorateHlsSDK.initialize(). No additional setup required.

Note: On Linux, seek preview thumbnails are disabled for optimal performance on TV platforms.

Basic Usage #

Video Player

import 'package:zeroratehls/zerorate_hls_player.dart.dart';

ZerorateHlsPlayer(
  options: ZerorateHlsPlayerOptions(
    appId: 'your-app-id',
    region: 'region-code',
    src: 'https://example.com/video.m3u8',
    type: MediaType.video,
    aspectRatio: 16 / 9,
    autoplay: true,
  ),
)

Audio Player

ZerorateHlsPlayer(
  options: ZerorateHlsPlayerOptions(
    appId: 'your-app-id',
    region: 'region-code',
    src: 'https://example.com/audio.m3u8',
    type: MediaType.audio,
    poster: 'https://example.com/poster.jpg',
    autoplay: false,
  ),
)

Configuration Options #

Video Configuration

ZerorateHlsPlayerOptions(
  // Required parameters
  appId: 'your-app-id',
  region: 'region-code',
  src: 'https://example.com/video.m3u8',
  type: MediaType.video,

  // ⭐ IMPORTANT: 
  // 🔒 User Authentication for Protected Content
  // - subscriberId and authUrl are REQUIRED for paid/protected content
  // - If accessing a paid or protected stream, you MUST provide these
  // - Omitting these for protected content will prevent the stream from loading

  // - subscriberId: A unique identifier for the user accessing the stream
  //   * This is typically a user-specific ID from your authentication system
  //   * Helps track and validate individual user access
  //   * Example: user's email, internal user ID, or generated unique token
  subscriberId: 'unique-user-identifier', 
  
  // - authUrl: The authentication endpoint provided by the content provider
  //   * This URL is used to validate the user's access to the stream
  //   * The backend will use the subscriberId to check user permissions
  //   * Provided by the content/streaming service developer
  authUrl: 'https://your-content-provider-auth-endpoint', 
  
  // Optional parameters
  mediaType: StreamType.onDemand, // or StreamType.live
  autoplay: true,
  muted: false,
  aspectRatio: 16 / 9,

  // The placeholder is a widget displayed before video playback begins. It serves multiple purposes:
  // - Provides visual feedback while the video is loading
  // - Shows a preview or poster image
  // - Improves user experience during initial load
  
  // Placeholder Hierarchy

  // 1. **Explicitly Provided Placeholder**
  //    - Highest priority
  //    - Custom widget you define

  // 2. **Poster Image**
  //    - Used if no custom placeholder is provided
  //    - Static image representing the video

  // 3. **Automatic PlaceHolder which could take a few seconds to come up**
  //    - Automatically extracts a placeholder from thw provided video source
  //    - Provides a dynamic preview of the video content

  // Custom placeholder widget
  placeholder: YourCustomWidget(),

  // Or use a poster image
  poster: 'https://example.com/poster.jpg',
  placeholderOnTop: true,
  
  // Video specific controls
  videoControlsConfig: VideoControlsConfig(
    enableSeekPreview: true,  // Enable thumbnail preview during seeking
    enablePlayPause: true,
    enableProgressBar: true,
    progressBarColor: Colors.red,
    useDefaultControls: true, // Set to false to use your own controls

    // You can add multiple subtitle files to your video configuration:
    // Subtitle Source Types
    // - Supports local asset files
    // - Supports network subtitle files
    subtitles: [
      SubtitleSource(
        path: 'assets/subtitles/movie_en.srt', 
        languageCode: 'en',
        name: 'English Subtitles'
        type: SubtitleSourceType.asset,
      ),
      SubtitleSource(
        path: 'http/link_to_subtitle', 
        languageCode: 'es',
        name: 'Spanish Subtitles'
        type: SubtitleSourceType.network,
      ),
    ],

    /// Video Resolution Configuration
    /// 
    /// You can add multiple video resolutions to your video configuration:
    /// 
    /// - Specify resolution name and corresponding URL

    resolutions: [
      VideoResolution(
        url: 'https://example.com/video_720p.m3u8', 
        name: '720p'
      ),
      VideoResolution(
        url: 'https://example.com/video_1080p.m3u8', 
        name: '1080p'
      ),
    ]
  ),
)

Audio Configuration

ZerorateHlsPlayerOptions(
  // Required parameters
  appId: 'your-app-id',
  region: 'region-code',
  src: 'https://example.com/audio.m3u8',
  type: MediaType.audio,
  
  // Optional parameters
  mediaType: StreamType.onDemand,
  autoplay: false,
  aspectRatio: 16 / 9,
  poster: 'https://example.com/poster.jpg',
  
  // Audio specific controls
  audioControlsConfiguration: AudioControlsConfiguration(
    enableProgressBar: true,
    enableProgressText: true,
    enableVolumeControl: true,
    enableSpeedControl: true,    // Allow changing playback speed
    progressBarColor: Colors.blue,
    textColor: Colors.white,
    useDefaultControls: true,    // Set to false to use your own controls
  ),
)

Event Handling #

Listen to player events to respond to changes in playback state:

ZerorateHlsPlayerEventType Enum #

Event Type Description Payload Type Typical Use Case
play Triggered when media starts playing null Track when playback begins
pause Triggered when media is paused null Monitor pause interactions
seeked Triggered after seeking to a new position Duration Track user navigation
bufferingStart Indicates the start of buffering null Handle loading states
bufferingEnd Indicates buffering has completed null Resume UI interactions
error Occurs when a playback error happens Exception Error handling and logging
loaded Media source successfully loaded Duration? Prepare player after loading
positionChanged Periodic update of playback position Duration Progress tracking
completed Media playback finished null Handle end of media
thumbnailGenerated Thumbnail created during seek preview Map<String, dynamic> Custom thumbnail handling
controlsVisibilityChanged Controls visibility toggled bool UI state management
qualityChanged Stream quality changed dynamic Quality tracking
volumeChanged Volume level modified double Volume control tracking
audioStateChanged Audio-specific state changes Map<String, dynamic> Audio playback monitoring
ZerorateHlsPlayerOptions(
  // Basic options
  appId: 'your-app-id',
  region: 'region-code',
  src: 'https://example.com/video.m3u8',
  type: MediaType.video,
  
  // Event listeners
  eventListeners: {
    ZerorateHlsPlayerEventType.play: (event) {
      print('Video started playing');
    },
    ZerorateHlsPlayerEventType.pause: (event) {
      print('Video paused');
    },
    ZerorateHlsPlayerEventType.seeked: (event) {
      print('Seeked to position: ${event.data}');
    },
    ZerorateHlsPlayerEventType.error: (event) {
      print('Error occurred: ${event.data}');
    },
    ZerorateHlsPlayerEventType.completed: (event) {
      print('Playback completed');
    },
    // Only for video with seek preview enabled
    ZerorateHlsPlayerEventType.thumbnailGenerated: (event) {
      print('Thumbnail generated: ${event.data}');
    },
  },
  
  // Custom error UI
  errorBuilder: (error) => Center(
    child: Text('Error: ${error.toString()}'),
  ),
)

UI Customization #

Custom Video Controls For complete control over the video player UI:

ZerorateHlsPlayerOptions(
  // Basic setup
  appId: 'your-app-id',
  region: 'region-code',
  src: 'https://example.com/video.m3u8',
  type: MediaType.video,
  
  // Disable default controls
  videoControlsConfig: VideoControlsConfig(
    useDefaultControls: false,
  ),
)

// Then build your own controls using player methods:
IconButton(
  icon: Icon(Icons.play_arrow),
  onPressed: () => yourPlayerReference.play(),
),
IconButton(
  icon: Icon(Icons.pause),
  onPressed: () => yourPlayerReference.pause(),
),

Custom Audio Controls For custom audio player UI:

ZerorateHlsPlayerOptions(
  // Basic setup
  appId: 'your-app-id',
  region: 'region-code',
  src: 'https://example.com/audio.m3u8',
  type: MediaType.audio,
  
  // Option 1: Custom component builders
  audioControlsConfiguration: AudioControlsConfiguration(
    playPauseBuilder: (player, onTap) {
      return CustomPlayButton(
        isPlaying: player.playing,
        onTap: onTap,
      );
    },
    progressBarBuilder: (player, current, total) {
      return CustomProgressBar(
        current: current,
        total: total,
        onSeek: (position) => player.seek(position),
      );
    },
  ),
  
  // Option 2: Disable default controls completely
  audioControlsConfiguration: AudioControlsConfiguration(
    useDefaultControls: false,
  ),
)

You can provide custom widgets for different playback states:

ZerorateHlsPlayerOptions(
  // ... other configurations
  audioControlsConfiguration: AudioControlsConfiguration(
    // Custom widget when audio is in default/idle state
    audioDefaultStateWidget: MyCustomIdleWidget(),
    
    // Custom widget when audio is playing
    audioPlayingStateWidget: MyCustomPlayingWidget(),
    
    // Set to false to use completely custom controls
    useDefaultControls: false,
  ),
)

Usage Scenarios:

  1. Default Controls (useDefaultControls: true)
  • Built-in UI with standard controls
  • Minimal configuration required
  • Quick setup for standard use cases
  1. Custom Controls (useDefaultControls: false)
  • Full control over player UI
  • Implement your own play/pause, progress tracking
  • Recommended for branded or complex UIs

Picture-in-Picture (PiP) Support #

Android Configuration #

To enable Picture-in-Picture mode for your Android app, you need to make two key modifications:

  1. Update AndroidManifest.xml:
<activity
    android:name=".MainActivity"
    android:supportsPictureInPicture="true"
    ... other configurations>
</activity>
  1. Minimum SDK Requirements:
  • Requires Android 8.0 (API level 26) or higher
  • Update android/app/build.gradle:
android {
    defaultConfig {
        minSdkVersion 26 // Minimum SDK for PiP support
    }
}

API Reference #

ZerorateHlsPlayer Methods #

Method Description
play() Start playback
pause() Pause playback
seekTo(Duration position) Seek to a position
setVolume(double volume) Set volume (0.0 to 1.0)
setPlaybackSpeed(double speed) Set audio playback speed
toggleFullscreen() Toggle fullscreen mode (video only)
resetToBeginning() Reset player duration to the start position
seekForward10Seconds() Skip forward 10 seconds
seekBackward10Seconds() Skip backward 10 seconds
toggleMute() Mute/unmute the player
enterPictureInPicture Activate Picture-in-Picture mode
exitPictureInPicture Exit Picture-in-Picture mode

ZerorateHlsPlayer Properties #

Property Description
currentPosition Current playback position
duration Total duration of the media
isPlaying Whether playback is currently playing
isBuffering Whether playback is currently buffering
isFullscreen Whether playback is currently in fullscreen
currentVolume Current volume level
isCompleted Has media playback finished
currentSpeed Current playback speed

Important Notes #

  • The seek preview feature only works when using the built-in video controlson supported platforms (Android, iOS,)

Example #

A complete example with event handling and custom controls:

class PlayerScreen extends StatefulWidget {
  @override
  State<PlayerScreen> createState() => _PlayerScreenState();
}

class _PlayerScreenState extends State<PlayerScreen> {
  ZerorateHlsPlayer? _player;

  @override
  void initState() {
    super.initState();
    _initializePlayer();
  }

  void _initializePlayer() {
    setState(() {
      _player = ZerorateHlsPlayer(
        options: ZerorateHlsPlayerOptions(
          appId: 'my-app-id',
          region: 'us-01',
          src: 'https://example.com/video.m3u8',
          type: MediaType.video,
          autoplay: false,
          aspectRatio: 16 / 9,
          videoControlsConfig: VideoControlsConfig(
            enableSeekPreview: true,
          ),
          eventListeners: {
            ZerorateHlsPlayerEventType.play: (event) => print('Playing'),
            ZerorateHlsPlayerEventType.error: (event) => print('Error: ${event.data}'),
          },
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Video Player')),
      body: Column(
        children: [
          if (_player != null)
            AspectRatio(
              aspectRatio: 16 / 9,
              child: _player!,
            ),
          
          // Custom controls below the player
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              IconButton(
                icon: Icon(Icons.replay_10),
                onPressed: () {
                  final position = _player?.currentPosition;
                  if (position != null) {
                    _player?.seekTo(
                      Duration(seconds: position.inSeconds - 10),
                    );
                  }
                },
              ),
              IconButton(
                icon: Icon(Icons.forward_10),
                onPressed: () {
                  final position = _player?.currentPosition;
                  if (position != null) {
                    _player?.seekTo(
                      Duration(seconds: position.inSeconds + 10),
                    );
                  }
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}

Troubleshooting #

HTTP streams not loading on Android

Make sure you've added android:usesCleartextTraffic="true" to your AndroidManifest.xml file.

Missing thumbnails in seek preview

The thumbnail generation runs in the background. On first run, thumbnails may take a moment to appear.

Contact Us #

Contributions are not accepted at this time. For any feature requests, bug fixes, or inquiries regarding licensing and reuse, please contact us at hi@freepass.africa.

0
likes
120
points
237
downloads

Publisher

verified publishersoa.live

Weekly Downloads

A comprehensive Flutter SDK for seamless HLS (HTTP Live Streaming) video playback. This package provides a robust, feature-rich player with advanced capabilities including adaptive bitrate streaming, seek preview, custom controls, subtitle support, picture-in-picture mode, and quality selection.

Homepage

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

better_player_plus, device_info_plus, ffmpeg_kit_flutter_new, flutter, gif_view, just_audio, media_kit, media_kit_libs_video, media_kit_video, package_info_plus, path_provider, plugin_platform_interface

More

Packages that depend on zeroratehls