-
Notifications
You must be signed in to change notification settings - Fork 491
Expand file tree
/
Copy pathMediaControlsService.android.cs
More file actions
94 lines (81 loc) · 3.45 KB
/
MediaControlsService.android.cs
File metadata and controls
94 lines (81 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System.Runtime.Versioning;
using Android.App;
using Android.Content;
using Android.Content.PM;
using AndroidX.Media3.Common;
using AndroidX.Media3.DataSource;
using AndroidX.Media3.ExoPlayer;
using AndroidX.Media3.ExoPlayer.TrackSelection;
using AndroidX.Media3.Session;
using Java.Util;
namespace CommunityToolkit.Maui.Media.Services;
[SupportedOSPlatform("Android26.0")]
[IntentFilter(["androidx.media3.session.MediaSessionService"])]
[Service(Exported = false, Enabled = true, Name = "communityToolkit.maui.media.services", ForegroundServiceType = ForegroundService.TypeMediaPlayback)]
sealed partial class MediaControlsService : MediaSessionService
{
MediaSession? mediaSession;
IExoPlayer? exoPlayer;
DefaultTrackSelector? trackSelector;
public override void OnTaskRemoved(Intent? rootIntent)
{
base.OnTaskRemoved(rootIntent);
PauseAllPlayersAndStopSelf();
}
public override void OnCreate()
{
base.OnCreate();
var audioAttribute = new AndroidX.Media3.Common.AudioAttributes.Builder()?
.SetContentType(C.AudioContentTypeMusic)? // When phonecalls come in, music is paused
.SetUsage(C.UsageMedia)?
.Build();
trackSelector = new DefaultTrackSelector(this);
var trackSelectionParameters = trackSelector.BuildUponParameters()?
.SetPreferredAudioLanguage(C.LanguageUndetermined)? // Fallback to system language if no preferred language found
.SetPreferredTextLanguage(C.LanguageUndetermined)? // Fallback to system language if no preferred language found
.SetIgnoredTextSelectionFlags(C.SelectionFlagAutoselect); // Ignore text tracks that are not explicitly selected by the user
trackSelector.SetParameters((DefaultTrackSelector.Parameters.Builder?)trackSelectionParameters); // Allows us to select tracks based on user preferences
var loadControlBuilder = new DefaultLoadControl.Builder();
loadControlBuilder.SetBufferDurationsMs(
minBufferMs: 15000,
maxBufferMs: 50000,
bufferForPlaybackMs: 2500,
bufferForPlaybackAfterRebufferMs: 5000); // Custom buffering strategy
var builder = new ExoPlayerBuilder(this) ?? throw new InvalidOperationException("ExoPlayerBuilder returned null");
builder.SetTrackSelector(trackSelector);
builder.SetAudioAttributes(audioAttribute, true);
builder.SetHandleAudioBecomingNoisy(true); // Unplugging headphones will pause playback
builder.SetLoadControl(loadControlBuilder.Build());
exoPlayer = builder.Build() ?? throw new InvalidOperationException("ExoPlayerBuilder.Build() returned null");
var mediaSessionBuilder = new MediaSession.Builder(this, exoPlayer);
UUID sessionId = UUID.RandomUUID() ?? throw new InvalidOperationException("UUID.RandomUUID() returned null");
mediaSessionBuilder.SetId(sessionId.ToString());
var dataSourceBitmapFactory = new DataSourceBitmapLoader(this);
mediaSessionBuilder.SetBitmapLoader(dataSourceBitmapFactory);
mediaSession = mediaSessionBuilder.Build() ?? throw new InvalidOperationException("MediaSession.Builder.Build() returned null");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
PauseAllPlayersAndStopSelf();
mediaSession?.Release();
mediaSession?.Dispose();
mediaSession = null;
exoPlayer?.Release();
exoPlayer = null;
trackSelector?.Dispose();
trackSelector = null;
}
base.Dispose(disposing);
}
public override void OnDestroy()
{
base.OnDestroy();
PauseAllPlayersAndStopSelf();
}
public override MediaSession? OnGetSession(MediaSession.ControllerInfo? p0)
{
return mediaSession;
}
}