Skip to content

Flutter & Dart 🎞 media playback, broadcast, recording & chromecast library for Windows & Linux. Written in C++ using libVLC & libVLC++. (Both audio & video)

License

Notifications You must be signed in to change notification settings

mohamadlounnas/dart_vlc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Flutter media playback, broadcast, recording & chromecast library for Windows & Linux.

Written in C++ using libVLC & libVLC++.

Installation

Flutter

dependencies:
  ...
  dart_vlc: ^0.1.4

Dart CLI

dependencies:
  ...
  dart_vlc_ffi: ^0.1.2

More on Dart CLI implementation here.

Feel free to open issue, incase you find something to be not working.

Support

Consider supporting the project by starring the repository or buying me a coffee.

Thanks a lot for your support.

Documentation

Initialize the library

void main() {
  DartVLC.initialize();
  runApp(MyApp());
}

Create a new player instance.

Player player = Player(id: 69420);

For passing VLC CLI arguments, use commandlineArguments argument.

Player player = Player(
  id: 69420,
  commandlineArguments: ['--no-video']
);

Create a media for playback.

Media media0 = Media.file(
  File('C:/music.mp3')
);

Media media1 = Media.network(
  'https://www.example.com/music.aac'
);

Create a list of medias using playlist.

Playlist playlist = new Playlist(
  medias: [
    Media.file(File('C:/music.mp3')),
    Media.file(File('C:/audio.mp3')),
    Media.network('https://www.example.com/music.aac'),
  ],
);

Open a media or playlist into a player.

player.open(
  Media.file(File('C:/music0.mp3')),
  autoStart: true, // default
);
player.open(
  Playlist(
    medias: [
      Media.file(new File('C:/music0.mp3')),
      Media.file(new File('C:/music1.mp3')),
      Media.file(new File('C:/music2.mp3')),
    ],
  ),
  autoStart: false,
);

Control playback.

player.play();

player.seek(Duration(seconds: 30));

player.pause();

player.playOrPause();

player.stop();

Traverse through the playlist.

player.next();

player.back();

player.jump(10);

Manipulate an already playing playlist.

player.add(
  Media.file(File('C:/music0.mp3')),
);

player.remove(4);

player.insert(
  2,
  Media.file(File('C:/music0.mp3')),
);

player.move(0, 4);

Set playback volume & rate.

player.setVolume(0.5);

player.setRate(1.25);

Get & change playback device.

List<Device> devices = Devices.all;

player.setDevice(
  devices[0],
);

Show the video inside widget tree.

Show Video in the Widget tree.

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)
);

Thanks to @tomassasovsky for adding visual controls to Video widget.

Change user agent

player.setUserAgent(userAgent);

Retrieve metadata of media.

Media media = Media.network(
  'https://www.example.com/media.mp3',
  parse: true,
  timeout: Duration(seconds: 10),
);

Map<String, String> metas = media.metas;

Listen to playback events.

(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;
});

Set an equalizer.

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;

Broadcast a media.

Broadcasting to localhost.

Broadcast 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();

Record a media.

Thanks to @DomingoMG for adding Record and Chromecast classes.

Record record = Record.create(
  id: 205, 
  media: Media.network('https://www.example.com/streaming-media.MP3'), 
  pathFile: '/home/alexmercerind/recording.MP3',
);
record.start();

Setup

Windows

Everything is already set up.

Linux

For using this plugin on Linux, you must have VLC & libVLC installed.

On debian based distros:

sudo apt-get install vlc
sudo apt-get install libvlc-dev

On Fedora:

sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install vlc
sudo dnf install vlc-devel

Example

You can see an example project here.

dart_vlc running on Ubuntu Linux.

Workings

The repository contains a C++ wrapper based on libVLC++. This makes handling of events and controls a lot easier & has additional features in it. I preferred to do majority of handling in C++ itself, thus Dart code is minimal & very slight mapping to it.

This project might seem like a Flutter plugin, but it is based on FFI instead. Here are the FFI bindings to C++ wrapper, which are shared by all platforms & same can be used in Dart CLI apps aswell. Platform channel interface is only used for [flutter]

Progress

Done

  • Media playback from File.
  • Media playback from network.
  • Media playback from assets.
  • play/pause/playOrPause/stop.
  • Multiple Player instances.
  • Playlist.
  • next/back/jump for playlists.
  • setVolume.
  • setRate.
  • seek.
  • Events.
  • Automatic fetching of headers, libs & shared libraries.
  • Changing VLC version from CMake.
  • Event streams.
    • Player.currentState
      • index: Index of current media in Playlist.
      • medias: List of all opened Medias.
      • media: Currently playing Media.
      • isPlaylist: Whether a single Media is loaded or a Playlist.
    • Player.positionState
      • position: Position of currently playing media in Duration.
      • duration: Position of currently playing media in Duration.
    • Player.playbackState
      • isPlaying.
      • isSeekable.
      • isCompleted.
    • Player.generalState
      • volume: Volume of current Player instance.
      • rate: Rate of current Player instance.
  • add/insert/remove/move Media inside Playlist during playback.
  • Device enumeration & changing.
  • Retrieving Meta of a Media.
  • Embedding Video inside the Flutter window.
  • Supporting live streaming links.
  • Broadcast class for broadcasting Media.
  • Record class for recording Media.
  • Chromecast class.
  • Equalizer support.
  • Adding headers for Media.network (Not possible, added user agent).
  • Switching to FFI for more cross platform freedom.
  • Changing Video's frame size according to video.

Under progress or planned features (irrespective of order)...

  • Removing libVLC++ dependency. (Maybe).
  • Subtitle control.
  • Audio track control.
  • Writing metadata tags.
  • Making things more efficient.
  • Supporting native volume control/lock screen notifications (Maybe).
  • Bringing project on other platforms like Android/iOS (Maybe).
  • D-Bus MPRIS controls for Media playback control (Maybe).

Acknowledgements

First of all, thanks to the VideoLAN team for creating libVLC & libVLC++. Really great guys really great at their work.

Thanks to @jnschulze for his awesome contributions to this project & to Flutter engine like adding texture support.

Thanks to @namniav for working on macOS support.

Thanks to @stuartmorgan from The Flutter Team for helping out the project with his opinions.

Thanks to following members of libVLC community (irrespective of the order) for giving general ideas about libVLC APIs:

Contributions

The code in the project is nicely arranged (I guess), I have added comments wherever I felt necessary.

Contributions to the project are open, it will be appreciated if you discuss the bug-fix/feature-addition in the issues first.

License

Copyright (C) 2021, Hitesh Kumar Saini [email protected].

This library & work under this repository is licensed under GNU Lesser General Public License v2.1.

Vision

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.

Support for other platforms is also under progress.

About

Flutter & Dart 🎞 media playback, broadcast, recording & chromecast library for Windows & Linux. Written in C++ using libVLC & libVLC++. (Both audio & video)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Dart 49.7%
  • C++ 37.9%
  • CMake 9.0%
  • Ruby 1.3%
  • C 1.1%
  • Swift 0.7%
  • Shell 0.3%