Flutter audio/video playback, broadcast & recording library for Windows & Linux.
I have recently started to work on a better, stable & more performant media playback library with hardware accelerated video rendering library for Flutter Windows & Linux. Other than just hardware-accelerated video embedding, it has things like pitch shifting support, tag/metadata reader, dynamic playlist support, native OS controls on Windows/Linux & volume boost feature out-of-the-box along side basic features. Currently, audio-only support is 100% ready & used in production inside Harmonoid: A Material Design-led music player to play & manage music library, video support needs to be written (although POC video is attached below).
It has very little expense on GPU & CPU during video playback (compared to package:dart_vlc). See the video for more details:
Since, I have no personal requirements for video support, I need sponsor / funding to continue my work. π Trust me, it's a very tedious process with very-little clear direction. Your support can ensure timely maintenance & stability of library that you can depend upon.
You may sponsor my work on my GitHub Sponsors profile & get updates/early-access.
Video support for Windows will be implemented with Direct3D-OpenGL interop with the help of ANGLE, since libmpv has a performant OpenGL API. More details about initial setup my be found on my following repositories:
- OpenGL-Direct3D interop with ANGLE.
- package:media_engine with complete audio playback API (leftover support for video rendering).
If enough support is received, I may even add support to the official package:video_player, give you personal support & help.
libmpv+flutter.mp4
pub.dev
dependencies:
...
dart_vlc: ^0.1.9GitHub
dependencies:
dart_vlc:
git:
url: https://github.com/alexmercerind/dart_vlc.git
ref: master
dependency_overrides:
dart_vlc_ffi:
git:
url: https://github.com/alexmercerind/dart_vlc.git
ref: master
path: ffiFeel free to open a new issue or discussion, if you found a bug or need assistance.
Consider supporting the project by buying me a coffee or starring the repository.
Thanks a lot for your support.
macOS support has been removed due to lack of maintainers & not having macOS running hardware.
Checkout Setup section to configure plugin on your platform.
Future<void> main() async {
await DartVLC.initialize();
runApp(MyApp());
}final player = Player(id: 69420);For passing VLC CLI arguments, use commandlineArguments argument.
final player = Player(
id: 69420,
commandlineArguments: ['--no-video']
);final media0 = Media.file(
File('C:/music.mp3')
);
final media1 = Media.asset(
'assets/audio/example.mp3'
);
final media2 = Media.network(
'https://www.example.com/music.aac'
);
// Clip the media.
final media2 = Media.network(
'https://www.example.com/music.aac',
startTime: Duration(seconds: 20), // Start media from 20 seconds from the beginning.
stopTime: Duration(seconds: 60), // End media at 60 seconds from the beginning.
);final playlist = Playlist(
medias: [
Media.file(File('C:/music.mp3')),
Media.file(File('C:/audio.mp3')),
Media.asset('assets/audio/example.mp3'),
Media.network('https://www.example.com/music.aac'),
],
);player.open(
Media.file(File('C:/music0.mp3')),
autoStart: true, // default
);player.open(
Playlist(
medias: [
Media.file(File('C:/music0.mp3')),
Media.file(File('C:/music1.mp3')),
Media.file(File('C:/music2.mp3')),
],
),
autoStart: false,
);player.play();
player.seek(Duration(seconds: 30));
player.pause();
player.playOrPause();
player.stop();player.next();
player.previous();
player.jumpToIndex(10);player.add(
Media.file(File('C:/music0.mp3')),
);
player.remove(4);
player.insert(
2,
Media.file(File('C:/music0.mp3')),
);
player.move(0, 4);player.setVolume(0.5);
player.setRate(1.25);List<Device> devices = Devices.all;
player.setDevice(
devices[0],
);player.takeSnapshot(file, 1920, 1080);Show Video in the Widget tree.
NOTE: This will cause additional CPU-load due to conversion of video frames to RGBA/BGRA pixel-buffers & Texture interop. For better performance, use NativeVideo instead.
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Video(
player: player,
height: 1920.0,
width: 1080.0,
scale: 1.0, // default
showControls: false, // default
),
);
}
}By default, Video widget's frame size will adapt to the currently playing video.
To override this & define custom video frame size, pass videoDimensions argument while instanciating Player class as follows.
Player player = Player(
id: 69420,
videoDimensions: const VideoDimensions(640, 360),
);A more performant Widget for showing video inside the Widget tree.
This Widget is more performant compared to Video & uses flutter_native_view
to embed the video output directly without any texture interop or pixel-buffer copy calls.
But, it is highly dependent on platform & other limitations apply. In general, this widget is more performant & should be used if possible.
-
Edit your
windows/runner/main.cppas required here. -
Register the plugin with
useFlutterNativeViewastrue.
void main() {
DartVLC.initilize(useFlutterNativeView: true);
runApp(MyApp());
}- Pass
registerTextureasfalsewhen creatingPlayer& useNativeVideowidget.
class _MyAppState extends State<MyApp> {
Player player = Player(id: 0, registerTexture: false);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: NativeVideo(
player: player,
height: 420.0,
width: 320.0
),
),
);
}
}player.setUserAgent(userAgent);Media media = Media.network(
'https://www.example.com/media.mp3',
parse: true,
timeout: Duration(seconds: 10),
);
Map<String, String> metas = media.metas;(Same can be retrieved directly from Player instance without having to rely on stream).
Listen to currently loaded media & playlist index changes.
player.currentStream.listen((CurrentState state) {
state.index;
state.media;
state.medias;
state.isPlaylist;
});Listen to playback position & media duration.
player.positionStream.listen((PositionState state) {
state.position;
state.duration;
});Listen to playback states.
player.playbackStream.listen((PlaybackState state) {
state.isPlaying;
state.isSeekable;
state.isCompleted;
});Listen to volume & rate of the Player.
player.generalStream.listen((GeneralState state) {
state.volume;
state.rate;
});Listen to dimensions of currently playing Video.
player.videoDimensionsStream.listen((VideoDimensions video) {
video.width;
video.height;
});Listen to buffering progress of the playing Media.
player.bufferingProgressStream.listen(
(double event) {
this.setState(() {
this.bufferingProgress = event;
});
},
);Create using preset.
Equalizer equalizer = Equalizer.createMode(EqualizerMode.party);
player.setEqualizer(equalizer);Create custom equalizer.
Equalizer equalizer = Equalizer.createEmpty();
equalizer.setPreAmp(10.0);
equalizer.setBandAmp(31.25, -10.0);
equalizer.setBandAmp(100.0, -10.0);
player.setEqualizer(equalizer);Get equalizer state.
equalizer.preAmp;
equalizer.bandAmps;Broadcasting to localhost.
final broadcast = Broadcast.create(
id: 0,
media: Media.file(File('C:/video.mp4')),
configuration: BroadcastConfiguration(
access: 'http',
mux: 'mpeg1',
dst: '127.0.0.1:8080',
vcodec: 'mp1v',
vb: 1024,
acodec: 'mpga',
ab: 128,
),
);
broadcast.start();Dispose the Broadcast instance to release resources.
broadcast.dispose();final record = Record.create(
id: 205,
media: Media.network('https://www.example.com/streaming-media.MP3'),
pathFile: '/home/alexmercerind/recording.MP3',
);
record.start();Everything is already set up.
For using this plugin on Linux, you must have VLC & libVLC installed.
On Ubuntu/Debian:
sudo apt-get install vlcsudo apt-get install libvlc-devOn Fedora:
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpmsudo dnf install vlcsudo dnf install vlc-devel-
BIG thanks to @jnschulze for his awesome contributions to this project & to the Flutter engine itself like adding texture support & adding macOS support here. I have learnt a lot about modern C++ & good-practices when writing code from you, thanks a lot for your guidances, reviews, work & donation. I'm really really thankful to you.
-
BIG thanks to @DomingoMG for adding
RecordandChromecastclasses. Also, thanks a lot for donation to the project & giving me motivation to start building this. I would've never attempted this if you didn't motivate me. And now that it started,dart_vlchas grown a lot. -
Thanks to @tomassasovsky for adding visual controls to
Videowidget. -
Thanks to following members of libVLC community (irrespective of the order) for giving general ideas about libVLC APIs:
-
Finally, thanks to the VideoLAN team for creating libVLC & libVLC++. Really great guys really great at their work.
The code in the project is nicely arranged and follows the clean architecture.
Contributions to the project are open, it will be appreciated if you discuss the bug-fix/feature-addition in the issues first.
Copyright (C) 2021, Hitesh Kumar Saini [email protected].
This library & work under this repository is licensed under GNU Lesser General Public License v2.1.
There aren't any media (audio or video) playback libraries for Flutter or Dart on Windows/Linux yet. So, this project is all about that. As one might be already aware, VLC is one of the best media playback tools out there.
So, now you can use it to play audio or video files from Flutter or Dart apps.
As the project has grown, awesome people from community have added support for iOS & macOS aswell.
You can see an example project here.
dart_vlc running on Ubuntu Linux.
Done
Mediaplayback fromFile.Mediaplayback from network.Mediaplayback from assets.play/pause/playOrPause/stop.- Multiple
Playerinstances. Playlist.next/back/jumpfor playlists.setVolume.setRate.seek.- Event streams.
add/insert/remove/moveMediainsidePlaylistduring playback with no interruption.- Device enumeration & changing.
- Retrieving metadata/tags of a
Media. - Embedding
Videoinside the Flutter window (using texture or natively). - Supporting live streaming links.
Broadcastclass for broadcastingMedia.Recordclass for recordingMedia.Chromecastclass.Equalizerconfiguration & presets.- Changing user agent.
- Changing
Video's frame size according to video. - Saving screenshot of the video.
- Changing/retrieving audio track.
- Media clipping.
- Support for Windows, Linux or macOS.
Under progress or planned features (irrespective of order)...
- Bringing project on Android and iOS.
- Removing libVLC++ dependency.
- Subtitle control.