Support locks for background playback and action buttons - specifically media control buttons (play, pause, next, previous)
Problem to solve
To provide flawless playback and streaming, on some platforms it might be necessary to active some locks and hooks to prevent them from falling asleep or just disable playback by turning of wifi.
More details on this on a pretty outdated but still useful blog post with additional code examples for Xamarin.
Most platforms also provide ways to control the playback of media with specific buttons or keys in locked mode. Some of them are:
- Headphone remotes (like Apple Earpods or 1MORE E1010)
- Keyboard Bindings
- Specific media keys (play, pause, etc.)
- Infrared remotes
- Bluetooth controls (double tap, etc.)
These are extra useful on mobile platforms, because you don't have to take out your mobile device to change volume or skip to the next track.
Currently, I did not see any possibility to hook into these background services and media events via libvlc sharp, on any platform.
Intended users
I think it would be great for all users of LibVLCSharp, if there was a possibility to just activate support for these background playback and media keys in a sane default behaviour. As an extra goal it would be great to add support to change the default behaviour in a flexible way.
Proposal
I think the most intuitive way to implement this is to take a look at the XamarinMediaManager Project, where everything is handled more or less automatically in the background with sane defaults.
Like stated in https://github.com/Baseflow/XamarinMediaManager/wiki/Initialize-and-setup#important
This library will automatically request the following permissions: AccessWifiState, AccessNetworkState, Internet, ForegroundService and WakeLock. You do not need to add them to your AndroidManifest.
Code example:
public enum KeyInput {
PlayPause,
Next,
Previous
}
public class MediaPlayerService: IDisposable
{
private readonly MediaPlayer _mediaPlayer;
private readonly LibVLC _libVlc;
public MediaPlayerService(LibVLC libVlc, MediaPlayer mediaPlayer)
{
_libVlc = libVlc;
_mediaPlayer = mediaPlayer;
_mediaPlayer.EnableKeyInput = true; // maybe this existing property can be extended to support native
_mediaPlayer.KeyInputEmitted += OnKeyInputEmitted;
}
public void Play() => _mediaPlayer.Play();
public void Pause() => _mediaPlayer.Pause();
public void NextChapter() => _mediaPlayer.NextChapter();
public void PreviousChapter() => _mediaPlayer.PreviousChapter();
private void OnKeyInputEmit(object? sender, KeyInputEmittedEventArgs e)
{
// manually handle the input event
switch(e.Key) {
case KeyInput.PlayPause:
_mediaPlayer.IsPlaying ? Pause() : Play();
break;
case KeyInput.Next:
NextChapter();
break;
}
e.Handled = true; // optional: prevent further handling of these events
}
public void Dispose()
{
Pause();
_mediaPlayer.Dispose();
_libVlc.Dispose();
}
}
Documentation
Since this feature is more an under the hood one, for the default behaviour it would no additional documentation.
However, since the feature could use customized hooks via KeyInputEmmitted
, this eventhandler should be documented with at least one example like the one above.