multimedia_player 0.1.0
multimedia_player: ^0.1.0 copied to clipboard
A production-grade, cross-platform Flutter video player package supporting network URLs, local files, assets, RTSP, HLS, DASH with customizable controls and memory-efficient playback.
Multimedia Player #
A production-grade, cross-platform Flutter video player package supporting network URLs, local files, assets, RTSP, HLS, DASH with customizable controls and memory-efficient playback.
Features #
🎥 Comprehensive Video Source Support #
- Network URLs (HTTP/HTTPS)
- Local Files from device storage
- Asset Videos bundled with your app
- RTSP Streams for real-time streaming
- HLS (.m3u8) adaptive streaming
- DASH adaptive streaming
- Custom HTTP headers for authenticated sources
🎮 Rich Controls & Customization #
- Default Beautiful Controls - Play/pause, seek, volume, fullscreen out-of-the-box
- Fully Customizable UI - Replace controls with your own design
- Playback Speed Control - 0.5x to 2.0x with custom speeds
- Volume Control - Slider and mute toggle
- Seek Controls - Forward/backward with configurable duration
- Fullscreen Mode - Native fullscreen support
- Auto-hide Controls - Configurable timeout
⚡ Performance & Memory Efficiency #
- Automatic Resource Management - Proper disposal and lifecycle handling
- Visibility-based Auto-pause - Pause videos when scrolled out of view
- Memory-efficient List Support - Optimized for ListView/PageView
- Lazy Initialization - Load players only when needed
- Concurrent Player Limits - Prevent memory issues with multiple players
🎨 Developer Experience #
- Beginner-Friendly - Simple API for quick integration
- Expert-Ready - Deep customization hooks for advanced use cases
- Event Callbacks - Listen to play, pause, buffering, completion, errors
- Type-Safe - Full null safety support
- Well Documented - Comprehensive API documentation and examples
Platform Support #
| Platform | Supported | Notes |
|---|---|---|
| Android | ✅ | Uses ExoPlayer for optimal performance |
| iOS | ✅ | Uses AVPlayer |
| Web | ✅ | HTML5 video element |
| macOS | ✅ | AVPlayer |
| Windows | ✅ | Media Foundation |
| Linux | ✅ | GStreamer |
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
multimedia_player: ^0.1.0
Then run:
flutter pub get
Quick Start #
Basic Usage #
import 'package:flutter/material.dart';
import 'package:multimedia_player/multimedia_player.dart';
class SimpleVideoPlayer extends StatefulWidget {
@override
State<SimpleVideoPlayer> createState() => _SimpleVideoPlayerState();
}
class _SimpleVideoPlayerState extends State<SimpleVideoPlayer> {
late MultimediaVideoController _controller;
@override
void initState() {
super.initState();
_controller = MultimediaVideoController(
source: VideoSource.network(
'https://example.com/video.mp4',
),
config: const VideoPlayerConfig(
autoPlay: true,
looping: true,
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AspectRatio(
aspectRatio: 16 / 9,
child: MultimediaVideoPlayer(
controller: _controller,
),
),
),
);
}
}
Usage Examples #
Different Video Sources #
Network Video
final controller = MultimediaVideoController(
source: VideoSource.network(
'https://example.com/video.mp4',
headers: {'Authorization': 'Bearer token'}, // Optional headers
),
);
Local File
final controller = MultimediaVideoController(
source: VideoSource.file(File('/path/to/video.mp4')),
);
Asset Video
final controller = MultimediaVideoController(
source: VideoSource.asset('assets/videos/intro.mp4'),
);
HLS Stream
final controller = MultimediaVideoController(
source: VideoSource.hls('https://example.com/stream.m3u8'),
);
RTSP Stream
final controller = MultimediaVideoController(
source: VideoSource.rtsp('rtsp://example.com:8554/stream'),
);
Advanced Configuration #
final controller = MultimediaVideoController(
source: VideoSource.network('https://example.com/video.mp4'),
config: VideoPlayerConfig(
autoPlay: true,
looping: false,
volume: 0.8,
playbackSpeed: 1.0,
muted: false,
fit: BoxFit.cover,
controlsTimeout: Duration(seconds: 5),
showPlaybackSpeed: true,
showVolumeControl: true,
doubleTapToSeek: true,
seekDuration: Duration(seconds: 10),
backgroundColor: Colors.black,
),
);
Custom Controls #
MultimediaVideoPlayer(
controller: controller,
controlsBuilder: (controller) {
return MyCustomControls(controller: controller);
},
)
Event Handling #
controller.onPlay(() {
print('Video started playing');
});
controller.onPause(() {
print('Video paused');
});
controller.onBuffering(() {
print('Buffering...');
});
controller.onCompleted(() {
print('Playback completed');
});
controller.onError((error) {
print('Error: $error');
});
controller.onPositionChanged((position) {
print('Position: ${position.inSeconds}s');
});
Video List with Auto-Pause #
Perfect for social media feeds or video galleries:
class VideoListItem extends StatefulWidget {
final String videoUrl;
const VideoListItem({required this.videoUrl});
@override
State<VideoListItem> createState() => _VideoListItemState();
}
class _VideoListItemState extends State<VideoListItem> {
late MultimediaVideoController _controller;
@override
void initState() {
super.initState();
_controller = MultimediaVideoController(
source: VideoSource.network(widget.videoUrl),
config: VideoPlayerConfig.forList(
autoPlay: false,
pauseOnInvisible: true, // Auto-pause when scrolled out
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MultimediaVideoPlayer(
controller: _controller,
enableVisibilityTracking: true,
visibilityKey: ValueKey(widget.videoUrl),
);
}
}
Programmatic Control #
// Play/Pause
await controller.play();
await controller.pause();
await controller.togglePlayPause();
// Seeking
await controller.seekTo(Duration(seconds: 30));
await controller.seekForward(Duration(seconds: 10));
await controller.seekBackward(Duration(seconds: 10));
// Playback Speed
await controller.setPlaybackSpeed(1.5);
// Volume
await controller.setVolume(0.5);
await controller.setMuted(true);
await controller.toggleMute();
// Looping
await controller.setLooping(true);
// Fullscreen
controller.toggleFullscreen();
controller.setFullscreen(true);
State Management #
// Listen to state changes
AnimatedBuilder(
animation: controller,
builder: (context, child) {
final state = controller.state;
return Column(
children: [
Text('Status: ${state.status}'),
Text('Position: ${FormatHelper.formatDuration(state.position)}'),
Text('Duration: ${FormatHelper.formatDuration(state.duration)}'),
Text('Buffered: ${state.bufferPercentage * 100}%'),
Text('Playing: ${state.isPlaying}'),
],
);
},
)
// Or use StreamBuilder
StreamBuilder<PlaybackState>(
stream: controller.stateStream,
builder: (context, snapshot) {
final state = snapshot.data;
if (state == null) return SizedBox();
return Text('${state.position} / ${state.duration}');
},
)
API Reference #
MultimediaVideoController #
Main controller for video playback.
Constructor:
MultimediaVideoController({
required VideoSource source,
VideoPlayerConfig? config,
})
Methods:
Future<void> initialize()- Initialize the playerFuture<void> play()- Start playbackFuture<void> pause()- Pause playbackFuture<void> togglePlayPause()- Toggle play/pauseFuture<void> seekTo(Duration position)- Seek to positionFuture<void> seekForward([Duration? duration])- Seek forwardFuture<void> seekBackward([Duration? duration])- Seek backwardFuture<void> setPlaybackSpeed(double speed)- Set playback speedFuture<void> setVolume(double volume)- Set volume (0.0-1.0)Future<void> setMuted(bool muted)- Mute/unmuteFuture<void> toggleMute()- Toggle muteFuture<void> setLooping(bool looping)- Enable/disable loopingvoid toggleFullscreen()- Toggle fullscreenvoid dispose()- Clean up resources
Properties:
PlaybackState state- Current playback stateStream<PlaybackState> stateStream- Stream of state changesbool isInitialized- Whether initializedDuration position- Current positionDuration duration- Total durationdouble aspectRatio- Video aspect ratio
Event Callbacks:
void onPlay(VideoEventCallback callback)void onPause(VideoEventCallback callback)void onBuffering(VideoEventCallback callback)void onCompleted(VideoEventCallback callback)void onError(VideoErrorCallback callback)void onPositionChanged(VideoPositionCallback callback)
VideoSource #
Factory constructors for different video sources:
VideoSource.network(String url, {Map<String, String>? headers})
VideoSource.file(File file)
VideoSource.asset(String assetPath, {String? package})
VideoSource.rtsp(String url, {Map<String, String>? headers})
VideoSource.hls(String url, {Map<String, String>? headers})
VideoSource.dash(String url, {Map<String, String>? headers})
VideoPlayerConfig #
Configuration options for the player. See source for all available options.
Factory Constructors:
VideoPlayerConfig.forList()- Optimized for listsVideoPlayerConfig.minimal()- Minimal UI
Performance Best Practices #
-
Always dispose controllers when done:
@override void dispose() { _controller.dispose(); super.dispose(); } -
Use visibility tracking for lists:
config: VideoPlayerConfig.forList(pauseOnInvisible: true) -
Limit concurrent players - Avoid more than 3 simultaneous video players
-
Use appropriate video formats:
- HLS for adaptive streaming
- MP4 for compatibility
- Lower resolutions for mobile networks
-
Preload strategically - Initialize players just before needed
Known Limitations #
| Feature | Android | iOS | Web | Notes |
|---|---|---|---|---|
| RTSP Streams | ✅ | ✅ | ❌ | Not supported on web |
| Background Playback | ⚠️ | ⚠️ | ✅ | Requires additional configuration |
| Picture-in-Picture | ⚠️ | ⚠️ | ✅ | Platform-specific implementation needed |
| DRM | ❌ | ❌ | ❌ | Not currently supported |
| Subtitles | ⚠️ | ⚠️ | ⚠️ | Planned for future release |
Troubleshooting #
Video not playing #
- Check network connectivity
- Verify video URL is accessible
- Check CORS headers for web
- Ensure video format is supported
Memory issues #
- Limit concurrent players to 3 or fewer
- Always dispose controllers
- Use
pauseOnInvisiblefor lists
Controls not showing #
- Check
showControlsparameter - Verify
controlsTimeoutisn't too short - Tap video to toggle controls
Contributing #
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
- 📫 Report issues on GitHub Issues
- 📖 Read the API documentation
- 💬 Join discussions on GitHub Discussions
Acknowledgments #
Built on top of the excellent video_player package by the Flutter team.