open method
Opens a Media or Playlist into the Player.
Passing play
as true
starts the playback immediately.
await player.open(Media('asset:///assets/videos/sample.mp4'));
await player.open(Media('file:///C:/Users/Hitesh/Music/Sample.mp3'));
await player.open(
Playlist(
[
Media('file:///C:/Users/Hitesh/Music/Sample.mp3'),
Media('file:///C:/Users/Hitesh/Video/Sample.mkv'),
Media('https://www.example.com/sample.mp4'),
Media('rtsp://www.example.com/live'),
],
),
);
Implementation
@override
Future<void> open(
Playable playable, {
bool play = true,
bool synchronized = true,
}) {
Future<void> function() async {
if (disposed) {
throw AssertionError('[Player] has been disposed');
}
await waitForPlayerInitialization;
await waitForVideoControllerInitializationIfAttached;
final int index;
final List<Media> playlist = <Media>[];
if (playable is Media) {
index = 0;
playlist.add(playable);
} else if (playable is Playlist) {
index = playable.index;
playlist.addAll(playable.medias);
} else {
index = -1;
}
// Keep these [Media] objects in memory.
current.clear();
current.addAll(playlist);
final commands = [
// Clear existing playlist & change currently playing index to none.
// This causes playback to stop & player to enter the idle state.
'stop',
'playlist-clear',
'playlist-play-index none',
];
for (final command in commands) {
final args = command.toNativeUtf8();
mpv.mpv_command_string(
ctx,
args.cast(),
);
calloc.free(args);
}
// Enter paused state.
{
final name = 'pause'.toNativeUtf8();
final value = calloc<Uint8>();
mpv.mpv_get_property(
ctx,
name.cast(),
generated.mpv_format.MPV_FORMAT_FLAG,
value.cast(),
);
if (value.value == 0) {
// We are using `cycle pause` because it waits & prevents the race condition.
final command = 'cycle pause'.toNativeUtf8();
mpv.mpv_command_string(
ctx,
command.cast(),
);
}
calloc.free(name);
calloc.free(value);
state = state.copyWith(playing: false);
if (!playingController.isClosed) {
playingController.add(false);
}
}
isShuffleEnabled = false;
isPlayingStateChangeAllowed = false;
for (int i = 0; i < playlist.length; i++) {
await _command(
[
'loadfile',
playlist[i].uri,
'append',
],
);
}
// If [play] is `true`, then exit paused state.
if (play) {
isPlayingStateChangeAllowed = true;
final name = 'pause'.toNativeUtf8();
final value = calloc<Uint8>();
mpv.mpv_get_property(
ctx,
name.cast(),
generated.mpv_format.MPV_FORMAT_FLAG,
value.cast(),
);
if (value.value == 1) {
// We are using `cycle pause` because it waits & prevents the race condition.
final command = 'cycle pause'.toNativeUtf8();
mpv.mpv_command_string(
ctx,
command.cast(),
);
}
calloc.free(name);
calloc.free(value);
state = state.copyWith(playing: true);
if (!playingController.isClosed) {
playingController.add(true);
}
}
// Jump to the specified [index] (in both cases either [play] is `true` or `false`).
{
final name = 'playlist-pos'.toNativeUtf8();
final value = calloc<Int64>()..value = index;
mpv.mpv_set_property(
ctx,
name.cast(),
generated.mpv_format.MPV_FORMAT_INT64,
value.cast(),
);
calloc.free(name);
calloc.free(value);
}
}
if (synchronized) {
return lock.synchronized(function);
} else {
return function();
}
}