Player API


Player interface

FPlayer

FPlayer fplayer = FPlayer();

Creating fplayer also brings up the native player on Android/iOS/macOS/Windows/OpenHarmony and the fplayercore C layer underneath. You have to release those resources with release().

release

Future<void> release() async
// usage
fplayer.release();

Inside, release checks the current player state and decides whether it needs to call stop first. That means you can call release from any state to free the underlying resources.

Playback control

setDataSource

Future<void> setDataSource(
  String path, {
  Map<String, String?>? headers,
  bool autoPlay = false,
  bool showCover = false,
})
/// usage
/// autoPlay: true is equivalent to calling setDataSource, prepareAsync and start
fplayer.setDataSource("http://samplevideo.com/sample.flv", autoPlay: true);
///
/// Set a local asset as the media source.
/// Declare the asset in pubspec.yml:
///   assets:
///     - assets/butterfly.mp4
///
/// The scheme is `asset`; `://` separates the scheme and `/` starts the path.
fplayer.setDataSource("asset:///assets/butterfly.mp4", autoPlay: true);

Sets the media source. The call works out the resource type itself, whether that's a network stream, a local file or something else.
Setting the optional autoPlay flag to true calls prepareAsync and start after the source is set, so playback begins on its own. It's equivalent to:

await setDataSource(url);
await setOption(FOption.playerCategory, "start-on-prepared", 1);
await prepareAsync();

Setting the optional showCover flag to true makes the player render the first video frame once it finishes parsing, then pause. The player keeps loading data into its buffers while paused. It's equivalent to:

await setDataSource(url);
await setOption(FOption.playerCategory, "cover-after-prepared", 1);
await prepareAsync();

prepareAsync

Future<void> prepareAsync() async
// usage
fplayer.prepareAsync();

Kicks the player into action: it spins up its resources, parses the media and gets ready to play. When the call returns, the player is in asyncPreparing; after preparation completes it moves to prepared. You must call setDataSource before this.

start

Future<void> start() async
// usage
fplayer.start();

Starts playback.

pause

Future<void> pause() async
// usage
fplayer.pause();

Pauses the player.

stop

Future<void> stop() async
// usage
fplayer.stop();

Stops playback. After stop you can't return to playing by calling start directly.

reset

Future<void> reset() async
// usage
fplayer.reset();

Resets the player to idle, after which you can call setDataSource again.

seekTo

Future<void> seekTo(int msec)
// usage
fplayer.seekTo(3000);

Moves playback to a new position. The argument is in milliseconds and must be 0 or greater. Only callable from a playable state.

Every playback control method is async. When you need to chain several of them, wait on each one with await or Future.then(). Calling the next method before the previous one finishes can leave the player in the wrong state.

Other methods

setVolume

Future<void> setVolume(double volume)
fplayer.setVolume(0.5);

Volume ranges from 0.0 to 1.0. Anything outside that range returns a parameter error.

setLoop

Future<void> setLoop(int loopCount) async
fplayer.setLoop(10);

The default loop count is 1, meaning no looping. Set it to 0 to loop forever.

setSpeed

Future<void> setSpeed(double speed) async
fplayer.setSpeed(1.5);

Don't push the rate too far. Pick a multiplier that feels right for the content you're playing.

Audio tracks

Once the player is prepared, call getAudioTracks for the track list of the current media, then setAudioTrack to switch. Works on Android, iOS, macOS, Windows and OpenHarmony.

FAudioTrack

FieldTypeDescription
indexintStream index of the track, used when switching
languageString?Track language
codecString?Short codec name, for example aac
codecLongNameString?Full codec name
sampleRateint?Sample rate in Hz
channelLayoutint?FFmpeg channel layout mask
selectedboolWhether this is the currently selected track

getAudioTracks

Future<List<FAudioTrack>> getAudioTracks() async
final tracks = await fplayer.getAudioTracks();
for (final track in tracks) {
  print('${track.index} ${track.language} ${track.codec} ${track.selected}');
}

Returns the audio tracks of the current media. You get an empty list when the player hasn't finished preparing or the media has no audio tracks.

setAudioTrack

Future<void> setAudioTrack(FAudioTrack track) async
final tracks = await fplayer.getAudioTracks();
if (tracks.isNotEmpty) {
  await fplayer.setAudioTrack(tracks.first);
}

track.index must be one of the indexes returned by getAudioTracks. After switching, call getAudioTracks again to confirm the selected flag moved where you expected.

Subtitles

Subtitle tracks follow the same discovery and switching flow as audio tracks, and the player decodes subtitles by default. Works on Android, iOS, macOS, Windows and OpenHarmony. FView draws the current subtitle at the bottom of the video by default; pass showSubtitles: false to turn the built-in subtitle layer off.

FSubtitleTrack

FieldTypeDescription
indexintStream index of the subtitle track, used when switching
languageString?Subtitle language
codecString?Short codec name, for example subrip
codecLongNameString?Full codec name
selectedboolWhether this is the currently selected subtitle track

getSubtitleTracks

Future<List<FSubtitleTrack>> getSubtitleTracks() async
final tracks = await fplayer.getSubtitleTracks();
for (final track in tracks) {
  print('${track.index} ${track.language} ${track.codec} ${track.selected}');
}

Returns the subtitle tracks of the current media. You get an empty list when the player hasn't finished preparing or the media has no subtitle tracks.

setSubtitleTrack

Future<void> setSubtitleTrack(FSubtitleTrack? track) async
final tracks = await fplayer.getSubtitleTracks();
if (tracks.isNotEmpty) {
  await fplayer.setSubtitleTrack(tracks.first);
}
// Turn subtitles off
await fplayer.setSubtitleTrack(null);

track.index must be one of the indexes returned by getSubtitleTracks. Passing null clears the current subtitle selection.

Subtitle text

FView displays subtitle text by default. If you're building your own subtitle layer, listen to onSubtitleTextUpdate or read subtitleText:

final subscription = fplayer.onSubtitleTextUpdate.listen((text) {
  print(text ?? '');
});

An empty text in the event means the current subtitle has ended, so hide your subtitle layer.

enterFullScreen

void enterFullScreen()

These two methods only flip a flag on the player. The actual fullscreen UI lives in FView, which watches that flag and reworks its layout when it changes.

exitFullScreen

void exitFullScreen()