media_kit 0.0.3+1 media_kit: ^0.0.3+1 copied to clipboard
A complete video & audio playback library for Flutter & Dart. Performant, stable, feature-proof & modular.
package:media_kit #
A complete video & audio playback library for Flutter & Dart. Performant, stable, feature-proof & modular.
Sponsored with 💖 by
Try the Flutter Chat tutorial
Clever Apps for Film Professionals
Installation #
Add in your pubspec.yaml
:
dependencies:
media_kit: ^0.0.3
# For video rendering.
media_kit_video: ^0.0.2
# Enables support for higher number of concurrent instances. Optional.
media_kit_native_event_loop: ^1.0.2
# Pick based on your requirements / platform:
media_kit_libs_windows_video: ^1.0.1 # Windows package for video (& audio) native libraries.
media_kit_libs_ios_video: ^1.0.1 # iOS package for video (& audio) native libraries.
media_kit_libs_macos_video: ^1.0.1 # macOS package for video (& audio) native libraries.
media_kit_libs_linux: ^1.0.1 # Linux dependency package.
Platforms #
Platform | Audio | Video |
---|---|---|
Windows | Ready | Ready |
Linux | Ready | Ready |
macOS | Ready | Ready |
iOS | Ready | Ready |
Android | WIP | WIP |
Web | WIP | WIP |
Docs #
Brief Start #
import 'package:media_kit/media_kit.dart';
final player = Player();
...
player.streams.playlist.listen((e) => print(e));
player.streams.playing.listen((e) => print(e));
player.streams.completed.listen((e) => print(e));
player.streams.position.listen((e) => print(e));
player.streams.duration.listen((e) => print(e));
player.streams.volume.listen((e) => print(e));
player.streams.rate.listen((e) => print(e));
player.streams.pitch.listen((e) => print(e));
player.streams.buffering.listen((e) => print(e));
player.streams.audioParams.listen((e) => print(e));
player.streams.audioBitrate.listen((e) => print(e));
player.streams.audioDevice.listen((e) => print(e));
player.streams.audioDevices.listen((e) => print(e));
...
await player.open(Media('file:///C:/Users/Hitesh/Music/Sample.mp3'));
await player.open(Media('file:///C:/Users/Hitesh/Video/Sample.mkv'));
await player.open(
Playlist(
[
Media('https://www.example.com/sample.mp4'),
Media('rtsp://www.example.com/live'),
],
),
);
...
await player.play();
await player.pause();
await player.playOrPause();
await player.seek(const Duration(seconds: 10));
...
await player.next();
await player.previous();
await player.jump(2);
await player.add(Media('https://www.example.com/sample.mp4'));
await player.move(0, 2);
...
await player.setRate(1.0);
await player.setPitch(1.2);
await player.setVolume(50.0);
await player.setShuffle(false);
await player.setPlaylistMode(PlaylistMode.loop);
await player.setAudioDevice(AudioDevice.auto());
...
await player.dispose();
Rendering Video #
Performant & H/W accelerated, automatically fallbacks to S/W rendering if system does not support it.
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
class MyScreen extends StatefulWidget {
const MyScreen({Key? key}) : super(key: key);
@override
State<MyScreen> createState() => _MyScreenState();
}
class MyScreenState extends State<MyScreen> {
// Create a [Player] instance from `package:media_kit`.
final Player player = Player();
// Reference to the [VideoController] instance from `package:media_kit_video`.
VideoController? controller;
@override
void initState() {
super.initState();
Future.microtask(() async {
// Create a [VideoController] instance from `package:media_kit_video`.
// Pass the [handle] of the [Player] from `package:media_kit` to the [VideoController] constructor.
controller = await VideoController.create(player.handle);
// Must be created before opening any media. Otherwise, a separate window will be created.
setState(() {});
});
}
@override
void dispose() {
Future.microtask(() async {
// Release allocated resources back to the system.
await controller?.dispose();
await player.dispose();
});
super.dispose();
}
@override
Widget build(BuildContext context) {
return Video(
/// Pass the [controller] to display the video output.
controller: controller,
);
}
}
Performance #
Although package:media_kit is already fairly performant, you can further optimize things as follows:
Note
- You can limit size of the video output by specifying
width
&height
. - By default, both
height
&width
arenull
i.e. output is based on video's resolution.
final controller = await VideoController.create(
player.handle,
width: 640, // default: null
height: 360, // default: null
);
Note
- You can switch between GPU & CPU rendering by specifying
enableHardwareAcceleration
. - By default,
enableHardwareAcceleration
istrue
i.e. GPU (Direct3D/OpenGL/METAL) is utilized.
final controller = await VideoController.create(
player.handle,
enableHardwareAcceleration: false, // default: true
);
Note
- You can disable event callbacks for a
Player
& save yourself few CPU cycles. - By default,
events
istrue
i.e. event streams & states are updated.
final player = Player(
configuration: PlayerConfiguration(
events: false, // default: true
),
);
Detailed Guide #
TODO: documentation
Try out the test application for now.
Setup #
Windows #
Everything ready. Just add one of the following packages to your pubspec.yaml
.
dependencies:
...
media_kit_libs_windows_video: ^1.0.0 # Windows package for video (& audio) native libraries.
media_kit_libs_windows_audio: ^1.0.1 # Windows package for audio (only) native libraries.
Linux #
System shared libraries from distribution specific user-installed packages are used by-default. You can install these as follows.
Ubuntu / Debian
sudo apt install libmpv-dev mpv
Packaging
There are other ways to bundle these within your app package e.g. within Snap or Flatpak. Few examples:
macOS #
Everything ready. Just add one of the following packages to your pubspec.yaml
.
dependencies:
...
media_kit_libs_macos_video: ^1.0.0 # macOS package for video (& audio) native libraries.
The minimum supported macOS version is 11.0 (#libmpv-darwin-build).
Also, during the build phase, the following warnings are not critical and cannot be silenced:
#import "Headers/media_kit_video-Swift.h"
^
/path/to/media_kit/media_kit_test/build/macos/Build/Products/Debug/media_kit_video/media_kit_video.framework/Headers/media_kit_video-Swift.h:270:31: warning: 'objc_ownership' only applies to Objective-C object or block pointer types; type here is 'CVPixelBufferRef' (aka 'struct __CVBuffer *')
- (CVPixelBufferRef _Nullable __unsafe_unretained)copyPixelBuffer SWIFT_WARN_UNUSED_RESULT;
# 1 "<command line>" 1
^
<command line>:20:9: warning: 'POD_CONFIGURATION_DEBUG' macro redefined
#define POD_CONFIGURATION_DEBUG 1 DEBUG=1
^
#define POD_CONFIGURATION_DEBUG 1
^
iOS #
Everything ready. Just add one of the following packages to your pubspec.yaml
.
dependencies:
...
media_kit_libs_ios_video: ^1.0.0 # iOS package for video (& audio) native libraries.
The minimum supported iOS version is 13.0 (#libmpv-darwin-build).
Also, software rendering is forced in the iOS simulator due to an incompatibility with OpenGL ES.
Goals #
The primary goal of package:media_kit is to become a strong, performant, stable, feature-proof & modular media playback library for Flutter. The idea is to support both audio & video playback.
Since, targetting multiple features at once & bundling redundant native libraries can result in increased bundle size of the application, you can manually select the native libraries you want to bundle, depending upon your use-case. The code is architectured to support multiple platforms & features. Support for more platforms will be added in future.
Fund Development #
If you find package:media_kit package(s) useful, please consider sponsoring me.
Since this is first of a kind project, it takes a lot of time to experiment & develop. It's a very tedious process to write code, document, maintain & provide support for free. Your support can ensure the quality of the package your project depends upon. I will feel rewarded for my hard-work & research.
Thanks!
License #
Copyright © 2021 & onwards, Hitesh Kumar Saini <saini123hitesh@gmail.com>
This project & the work under this repository is governed by MIT license that can be found in the LICENSE file.