esite_flutter_player 0.2.0
esite_flutter_player: ^0.2.0 copied to clipboard
Secure DRM-enabled video playback plugin for Flutter using Android Media3 ExoPlayer with Widevine DRM support.
esite_flutter_player #
A secure, production-ready Flutter plugin for DRM-protected video playback on Android using Media3 ExoPlayer with Widevine DRM support.
๐ Quick Start - Testing the Example #
The example app includes 7 comprehensive test scenarios! To run it:
cd example
flutter clean && rm -rf build/ .dart_tool/ android/.gradle/
flutter pub get
flutter run
Then tap "โ Valid Auth (Should Work)" to test DRM-protected video playback!
๐ See QUICK_START.md for detailed instructions ๐ See CHANGES_SUMMARY.md for recent updates
Features #
- โ DRM Support: Widevine DRM via Axinom integration
- โ Security: Automatic screenshot and screen recording blocking (FLAG_SECURE)
- โ Playback Controls: Play, pause, seek, speed control (0.5x-4x)
- โ Track Selection: Video quality selection
- โ Subtitle Support: Enable/disable subtitles
- โ Volume Control: Volume adjustment and mute
- โ Playlist Support: Next/previous media item navigation
- โ Event Streams: Real-time playback state, DRM events, and error handling
- โ Production Ready: Secure, no DRM data logging, proper lifecycle management
Platform Support #
- โ Android: Full support (Media3 ExoPlayer)
- โ iOS: Not yet implemented (planned for future release)
Installation #
Add esite_flutter_player to your pubspec.yaml:
dependencies:
esite_flutter_player: ^0.1.0
Then run:
flutter pub get
Quick Start #
1. Basic Setup #
import 'package:esite_flutter_player/esite_flutter_player.dart';
// Create player configuration
final config = ESitePlayerConfig(
sourceUrl: 'https://your-cdn.com/video.mpd',
drm: ESiteDrmConfig(
licenseUrl: 'https://license.axinom.com/widevine',
scheme: ESiteDrmScheme.widevine,
licenseHeaders: {
'X-AxDRM-Message': 'your-license-header',
},
),
autoPlay: false,
);
// Create controller
final controller = ESitePlayerController(config);
// Initialize player
await controller.initialize();
2. Display Video Player #
ESitePlayerView(controller: controller)
3. Control Playback #
// Play
await controller.play();
// Pause
await controller.pause();
// Seek to position
await controller.seekTo(Duration(seconds: 30));
// Seek forward/backward
await controller.seekForward(Duration(seconds: 10));
await controller.seekBackward(Duration(seconds: 10));
// Set playback speed (0.5x to 4x)
await controller.setPlaybackSpeed(1.5);
// Volume control
await controller.setVolume(0.8);
await controller.setMuted(true);
// Track selection
final tracks = await controller.getAvailableVideoTracks();
await controller.setVideoTrack(tracks[0]['id']);
// Subtitle control
await controller.setSubtitleEnabled(true);
// Playlist navigation
if (await controller.hasNext()) {
await controller.next();
}
4. Listen to Events #
// Playback state
controller.stateStream.listen((state) {
print('Player state: $state');
// States: idle, initializing, buffering, ready, playing, paused, completed, error
});
// DRM events
controller.drmStream.listen((event) {
print('DRM event: ${event.type}');
// Types: licenseRequested, licenseAcquired, licenseFailed
});
// Errors
controller.errorStream.listen((error) {
print('Error: ${error.code} - ${error.message}');
});
5. Cleanup #
@override
void dispose() {
controller.dispose();
super.dispose();
}
Complete Example #
See the example app for a full implementation with:
- Embedded player view
- Playback controls UI
- State monitoring
- Error handling
- Track selection
- Volume control
Documentation #
- ๐ Getting Started Guide - Step-by-step setup and usage
- ๐ API Reference - Complete API documentation
- ๐ Security Notes - Security best practices and DRM details
- ๐งช Test Plan - Comprehensive testing strategy and test cases
- โ Test Checklist - Quick reference for test execution
Security Features #
Screenshot & Screen Recording Protection #
The plugin automatically enables FLAG_SECURE when playback starts, preventing:
- Screenshots
- Screen recording
- Recent apps preview capture
Security is automatically:
- Enabled when playback starts
- Disabled when playback pauses or ends
- Disabled when the player is disposed
This ensures security is only active during actual playback, not affecting the rest of your app.
DRM Configuration #
Axinom Widevine Setup #
ESiteDrmConfig(
licenseUrl: 'https://license.axinom.com/widevine',
scheme: ESiteDrmScheme.widevine,
licenseHeaders: {
'X-AxDRM-Message': 'your-license-header',
'Authorization': 'Bearer your-token',
},
)
Supported DRM Schemes #
ESiteDrmScheme.widevine- Widevine DRM (Axinom)
API Reference #
ESitePlayerController #
Main controller for video playback.
Methods
Future<void> initialize()- Initialize the player with configurationFuture<void> play()- Start playbackFuture<void> pause()- Pause playbackFuture<void> seekTo(Duration position)- Seek to specific positionFuture<void> seekForward(Duration offset)- Seek forward by offsetFuture<void> seekBackward(Duration offset)- Seek backward by offsetFuture<void> setPlaybackSpeed(double speed)- Set speed (0.5-4.0)Future<void> setVolume(double volume)- Set volume (0.0-1.0)Future<void> setMuted(bool muted)- Mute/unmuteFuture<bool> isMuted()- Check if mutedFuture<double> getVolume()- Get current volumeFuture<List<Map<String, dynamic>>> getAvailableVideoTracks()- Get video tracksFuture<void> setVideoTrack(String trackId)- Select video trackFuture<void> setSubtitleEnabled(bool enabled)- Enable/disable subtitlesFuture<bool> isSubtitleEnabled()- Check subtitle statusFuture<bool> hasNext()- Check if next item availableFuture<bool> hasPrevious()- Check if previous item availableFuture<void> next()- Go to next media itemFuture<void> previous()- Go to previous media itemFuture<void> dispose()- Dispose player and cleanup
Properties
ESitePlayerState currentState- Current playback stateStream<ESitePlayerState> stateStream- Playback state streamStream<ESiteDrmEvent> drmStream- DRM events streamStream<ESitePlayerError> errorStream- Error stream
ESitePlayerConfig #
Player configuration.
ESitePlayerConfig({
required String sourceUrl,
required ESiteDrmConfig drm,
Map<String, String>? headers,
bool autoPlay = false,
bool preventScreenshots = false,
bool preventScreenRecording = false,
})
ESiteDrmConfig #
DRM configuration.
ESiteDrmConfig({
required String licenseUrl,
required ESiteDrmScheme scheme,
Map<String, String>? licenseHeaders,
})
ESitePlayerState #
Playback state enum:
idle- Initial stateinitializing- Player initializingbuffering- Buffering contentready- Ready to playplaying- Currently playingpaused- Pausedcompleted- Playback completederror- Error occurred
ESiteDrmEvent #
DRM event with type and optional message:
licenseRequested- License request initiatedlicenseAcquired- License successfully acquiredlicenseFailed- License acquisition failed
ESitePlayerError #
Error with code and message:
invalidSource- Invalid source URLdrmFailure- DRM-related failurenetworkError- Network errorplaybackError- Playback errorunknown- Unknown error
Limitations #
Emulator Support #
DRM-protected content may not work on Android emulators due to:
- Lack of Widevine L1 support
- Missing hardware security features
Recommendation: Test on physical Android devices.
iOS Support #
iOS support is planned for a future release. The plugin currently throws UnsupportedError on iOS.
Testing #
This plugin includes comprehensive test coverage across multiple levels:
Running Tests #
# Run all unit tests
flutter test
# Run with coverage report
flutter test --coverage
# Run integration tests (requires device/emulator)
cd example
flutter test integration_test/
# Run Android native tests
cd example/android
./gradlew test
# Generate HTML coverage report
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html
Test Coverage #
The plugin maintains high test coverage across:
- โ Unit Tests (70%): Controller, configuration, events, platform layer
- โ Widget Tests (20%): Player view and UI components
- โ Integration Tests (10%): End-to-end playback, DRM, security
Coverage Goals:
- Overall: >85%
- Controller: >95%
- Configuration: 100%
- Events/Errors: 100%
Test Documentation #
For detailed testing information, see:
- Test Plan - Complete testing strategy with all test cases
- Test Checklist - Quick reference for test execution
Test Categories #
- Configuration Tests: Player and DRM configuration validation
- Controller Tests: Playback control, state management, streams
- Platform Tests: Method channel and event channel communication
- Widget Tests: UI component rendering
- Integration Tests: Complete workflows, DRM license acquisition, security
- Native Tests: Android ExoPlayer and SecurityManager
- Error Handling: All error scenarios and recovery
- Edge Cases: Boundary conditions and unusual inputs
Troubleshooting #
DRM License Fails #
- Verify license URL is correct
- Check license headers (especially Axinom headers)
- Ensure device supports Widevine L1 or L3
- Test on physical device (not emulator)
Playback Doesn't Start #
- Check network connectivity
- Verify source URL is accessible
- Check DRM configuration
- Monitor error stream for details
Security Not Working #
- Security (FLAG_SECURE) is only enabled during active playback
- Ensure player is in playing state
- Check that activity is properly attached
Contributing #
Contributions are welcome! Please ensure:
- Code follows Dart/Flutter style guidelines
- Tests are included for new features
- Documentation is updated
License #
See LICENSE file for details.
Support #
For issues and questions:
- Open an issue on GitHub
- Check the example app for usage patterns
---Note: This plugin is designed for production use with secure DRM content. Always test thoroughly on physical devices before deploying.