flutter_native_player 2.0.0 copy "flutter_native_player: ^2.0.0" to clipboard
flutter_native_player: ^2.0.0 copied to clipboard

A Flutter plugin for Android, iOS for playing back video on a Widget surface with full customization support.

Flutter Native Player #

A Flutter plugin for Android and iOS for playing back video on a Widget surface with full customization support. Build your own video player UI with complete control over the player, OR use our pre-built controls for instant integration!

20220406_163756

Features #

  • ✅ Native video playback (ExoPlayer on Android, AVPlayer on iOS)
  • ✅ HLS streaming support
  • ✅ Subtitle support (SRT format)
  • ✅ Quality selection
  • ✅ Playback speed control
  • Pre-built controls - Use ready-made UI in seconds ⚡
  • Full customization - Build your own controls if needed
  • ✅ External controller for programmatic control
  • ✅ Custom loading indicators

Installation #

Add to your pubspec.yaml:

dependencies:
  flutter_native_player: ^2.0.0

Note: iOS requires 9.0 or higher and Android requires SDK 16 or higher

Quick Start (NEW! 🎉) #

1. Full Controls (11 lines - Everything included!) #

The easiest way to get started! Includes play/pause, seek, progress bar, quality selector, speed control, and subtitle selector.

import 'package:flutter_native_player/flutter_native_player.dart';
import 'package:flutter_native_player/model/player_resource.dart';

FlutterNativePlayer.withFullControls(
  playerResource: PlayerResource(
    videoUrl: 'https://example.com/video.m3u8',
    playerSubtitleResources: subtitles, // Optional
  ),
  width: double.infinity,
  height: 250,
  primaryColor: Colors.blue,
  showQualitySelector: true,
  showSpeedSelector: true,
  showSubtitleSelector: true,
)

2. Basic Controls (7 lines - Simple & Clean) #

Just play/pause and progress bar - perfect for most use cases.

FlutterNativePlayer.withBasicControls(
  playerResource: PlayerResource(
    videoUrl: 'https://example.com/video.m3u8',
  ),
  width: double.infinity,
  height: 250,
  primaryColor: Colors.blue,
)

3. Minimal Controls (5 lines - Ultra Simple) #

Only a play/pause button - cleanest option.

FlutterNativePlayer.withMinimalControls(
  playerResource: PlayerResource(
    videoUrl: 'https://example.com/video.m3u8',
  ),
  width: double.infinity,
  height: 250,
)

That's it! 🎉 You now have a fully functional video player with professional controls in just a few lines of code!


Advanced Usage #

No Controls (Bare Video) #

If you want just the video without any controls:

FlutterNativePlayer(
  playerResource: PlayerResource(
    videoUrl: 'https://example.com/video.m3u8',
  ),
  playWhenReady: true,
  width: double.infinity,
  height: 250,
)

Custom Controls with overlayBuilder #

If you need completely custom UI, build your own using the overlayBuilder:

import 'package:flutter_native_player/flutter_native_player.dart';
import 'package:flutter_native_player/flutter_native_player_controller.dart';
import 'package:flutter_native_player/method_manager/playback_state.dart';
import 'package:flutter_native_player/model/duration_state.dart';

FlutterNativePlayer(
  playerResource: PlayerResource(videoUrl: videoUrl),
  width: double.infinity,
  height: 250,
  overlayBuilder: (context, controller, playbackState, durationState) {
    return Stack(
      children: [
        // Your custom UI here
        Center(
          child: IconButton(
            icon: Icon(
              playbackState == PlaybackState.play
                  ? Icons.pause
                  : Icons.play_arrow,
            ),
            onPressed: () => controller.playOrPause(),
          ),
        ),
      ],
    );
  },
)

External Controller #

Control the player programmatically from anywhere in your app:

class MyPlayerScreen extends StatefulWidget {
  @override
  State<MyPlayerScreen> createState() => _MyPlayerScreenState();
}

class _MyPlayerScreenState extends State<MyPlayerScreen> {
  final _controller = FlutterNativePlayerController();

  @override
  void initState() {
    super.initState();
    
    // Listen to playback state
    _controller.playbackStateStream.listen((state) {
      print('Playback state: $state');
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // Video player (use any of the factory constructors)
        FlutterNativePlayer.withBasicControls(
          playerResource: PlayerResource(videoUrl: videoUrl),
          controller: _controller,
          playWhenReady: true,
          width: double.infinity,
          height: 250,
        ),
        
        // External controls
        Row(
          children: [
            ElevatedButton(
              onPressed: () => _controller.play(),
              child: Text('Play'),
            ),
            ElevatedButton(
              onPressed: () => _controller.pause(),
              child: Text('Pause'),
            ),
            ElevatedButton(
              onPressed: () => _controller.seekForward(),
              child: Text('+10s'),
            ),
          ],
        ),
      ],
    );
  }
          width: double.infinity,
          height: 250,
        ),
        
        // External controls (anywhere in your widget tree)
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              icon: Icon(Icons.replay_10),
              onPressed: () => _controller.seekBackward(),
            ),
            IconButton(
              icon: Icon(Icons.play_arrow),
              onPressed: () => _controller.play(),
            ),
            IconButton(
              icon: Icon(Icons.pause),
              onPressed: () => _controller.pause(),
            ),
            IconButton(
              icon: Icon(Icons.forward_10),
              onPressed: () => _controller.seekForward(),
            ),
          ],
        ),
      ],
    );
  }
}

Controller API Reference #

The FlutterNativePlayerController provides complete player control:

Playback Control #

controller.play();                              // Start playback
controller.pause();                             // Pause playback
controller.playOrPause();                       // Toggle play/pause
controller.restart();                           // Restart from beginning
controller.seekTo(Duration(seconds: 30));       // Seek to specific position
controller.seekForward();                       // Forward 10 seconds (default)
controller.seekBackward();                      // Backward 10 seconds (default)

Speed Control #

controller.setPlaybackSpeed(1.5);               // 0.25x to 2.0x speed
double speed = controller.currentSpeed;         // Get current speed

Quality Selection #

List<QualityModel> qualities = controller.getAvailableQualities();
controller.changeQuality(qualities[0]);         // Change quality
String url = controller.currentQualityUrl;      // Current quality URL

Subtitle Control #

List<PlayerKidSubtitlesSource> subs = controller.getAvailableSubtitles();
controller.changeSubtitle(subs[0]);             // Enable subtitle
controller.disableSubtitle();                   // Turn off subtitles
PlayerKidSubtitlesSource? current = controller.currentSubtitle;

State Monitoring #

// Listen to playback state changes
controller.playbackStateStream.listen((state) {
  // PlaybackState.play, .pause, .loading, .finish
});

// Listen to position updates
controller.durationStateStream.listen((state) {
  Duration progress = state.progress;
  Duration total = state.total;
  Duration buffered = state.buffered;
});

// Get current values
PlaybackState state = controller.playbackState;
DurationState? duration = controller.durationState;
Duration position = controller.currentPosition;
Duration total = controller.totalDuration;
bool loading = controller.isLoading;

Customization Options #

Pre-built Controls Configuration #

All factory constructors support customization:

FlutterNativePlayer.withFullControls(
  playerResource: PlayerResource(videoUrl: url),
  width: double.infinity,
  height: 250,
  primaryColor: Colors.purple,              // Accent color for controls
  controlsBackgroundColor: Colors.black54,  // Background overlay color
  autoHide: true,                           // Auto-hide controls
  autoHideDuration: Duration(seconds: 3),   // Hide after 3 seconds
  showQualitySelector: true,                // Show quality button
  showSpeedSelector: true,                  // Show speed button
  showSubtitleSelector: true,               // Show subtitle button
  backgroundColor: Colors.black,            // Player background
)

Custom Loading Indicator #

FlutterNativePlayer.withBasicControls(
  playerResource: PlayerResource(videoUrl: url),
  width: double.infinity,
  height: 250,
  loadingBuilder: (context, controller) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          CircularProgressIndicator(color: Colors.blue),
          SizedBox(height: 16),
          Text('Loading...', style: TextStyle(color: Colors.white)),
        ],
      ),
    );
  },
)

With Subtitles #

import 'package:flutter_native_player/model/player_subtitle_resource.dart';

FlutterNativePlayer.withFullControls(
  playerResource: PlayerResource(
    videoUrl: url,
    playerSubtitleResources: [
      PlayerSubtitleResource(
        language: "English",
        subtitleUrl: "https://example.com/subtitles_en.srt",
      ),
      PlayerSubtitleResource(
        language: "Spanish",
        subtitleUrl: "https://example.com/subtitles_es.srt",
      ),
    ],
  ),
  width: double.infinity,
  height: 250,
  showSubtitleSelector: true,  // Show subtitle picker
  showSubtitles: true,          // Display subtitles
)

Migration from Old API #

If you have existing code using overlayBuilder, it continues to work! But consider migrating:

Before (200+ lines):

class MyPlayer extends StatefulWidget {
  // Complex state management
  // Custom control UI
  // Stream listeners
  // 200+ lines of code...
}
}

After (11 lines):

FlutterNativePlayer.withFullControls(
  playerResource: PlayerResource(videoUrl: url),
  width: double.infinity,
  height: 250,
)

✨ Result: 95% less code, same features!


Why Use This Package? #

⚡ Instant Integration #

// From zero to fully-functional player in 30 seconds
FlutterNativePlayer.withFullControls(
  playerResource: PlayerResource(videoUrl: url),
  width: double.infinity,
  height: 250,
)

🎨 Flexible Design #

  • Pre-built controls - Ready to use out of the box
  • Customizable - Change colors, hide features you don't need
  • Fully custom - Build your own UI with overlayBuilder

🚀 Native Performance #

  • Uses ExoPlayer on Android
  • Uses AVPlayer on iOS
  • Hardware-accelerated video decoding
  • Optimized for battery life

📦 Feature-Rich #

  • HLS streaming with automatic quality switching
  • SRT subtitle support with multi-language
  • Playback speed control (0.25x to 2.0x)
  • Manual quality selection
  • Programmatic control API

Examples #

Check out the example folder for complete demonstrations:


Platform Support #

Platform Status
Android ✅ SDK 16+
iOS ✅ iOS 9.0+
Web ❌ Not supported
Desktop ❌ Not supported

Contributing #

Contributions are welcome! Please read our contributing guidelines before submitting a PR.


License #

This project is licensed under the MIT License - see the LICENSE file for details.


Support #

If you find this package helpful, please give it a ⭐ on GitHub! Duration total = controller.totalDuration; // Total duration Duration buffered = controller.bufferedDuration; // Buffered amount bool loading = controller.isLoading; // Loading state


### Streams (for reactive updates)

```dart
controller.playbackStateStream.listen((state) { });
controller.durationStateStream.listen((duration) { });
controller.loadingStream.listen((isLoading) { });
controller.downloadStateStream.listen((state) { });
controller.downloadProgressStream.listen((progress) { });

Other #

Future<bool> isPlaying = controller.isPlaying();
controller.showDevices();                       // Show available devices
controller.release();                           // Release player resources
controller.dispose();                           // Dispose controller

Widget Parameters #

Parameter Type Default Description
playerResource PlayerResource required Video URL and subtitle resources
width double required Player width
height double required Player height
playWhenReady bool true Auto-play when ready
controller FlutterNativePlayerController? null External controller
overlayBuilder PlayerOverlayBuilder? null Custom controls builder
loadingBuilder PlayerLoadingBuilder? null Custom loading indicator
showSubtitles bool true Show/hide subtitles
backgroundColor Color Colors.black Background color

Supported Formats #

Migration from v1.x #

Version 2.0 removes the predefined UI controls in favor of full customization. If you were using the default controls, you'll need to build your own using the overlayBuilder parameter.

Before (v1.x):

FlutterNativePlayer(
  playerResource: resource,
  progressColors: PlayerProgressColors(...),  // Removed
  playWhenReady: true,
  width: double.infinity,
  height: 250,
)

After (v2.0):

FlutterNativePlayer(
  playerResource: resource,
  playWhenReady: true,
  width: double.infinity,
  height: 250,
  overlayBuilder: (context, controller, playbackState, durationState) {
    return YourCustomControls(...);
  },
)

See the example project for complete implementations of custom controls.

License #

MIT License

10
likes
150
points
22
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for Android, iOS for playing back video on a Widget surface with full customization support.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

collection, flutter, flutter_widget_from_html_core, plugin_platform_interface

More

Packages that depend on flutter_native_player

Packages that implement flutter_native_player