Skip to content

Commit

Permalink
(#96) Resume local playback after AVAudioSession interruption
Browse files Browse the repository at this point in the history
  • Loading branch information
Difegue committed Sep 8, 2024
1 parent b33df77 commit 5609f5e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Sources/Stylophone.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public bool FinishedLaunching(UIApplication application, NSDictionary launchOpti
// Enable Now Playing integration
application.BeginReceivingRemoteControlEvents();
AVAudioSession.SharedInstance().SetCategory(AVAudioSessionCategory.Playback);

//AVAudioSession.SharedInstance().SetPrefersNoInterruptionsFromSystemAlerts(true, out _);

// Override point for customization after application launch
Task.Run(async () => await InitializeApplicationAsync());

Expand Down
11 changes: 5 additions & 6 deletions Sources/Stylophone.iOS/Services/InteropService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@
using UIKit;
using SkiaSharp.Views.iOS;
using Foundation;
using CommunityToolkit.Mvvm.DependencyInjection;

namespace Stylophone.iOS.Services
{
public class InteropService: IInteropService
{
private NowPlayingService _nowPlayingService;

public InteropService(NowPlayingService nowPlayingService)
public InteropService()
{
_nowPlayingService = nowPlayingService;
}

public Task SetThemeAsync(Theme theme)
Expand Down Expand Up @@ -61,8 +59,9 @@ public async Task<SKImage> GetPlaceholderImageAsync()

public async Task UpdateOperatingSystemIntegrationsAsync(TrackViewModel currentTrack)
{
await _nowPlayingService.UpdateMetadataAsync(currentTrack);
//await LiveTileHelper.UpdatePlayingSongAsync(currentTrack);
// This needs to be instantiated lazily since NPService depends on LocalPlayback, which depends on Interop already..
var nowPlayingService = Ioc.Default.GetRequiredService<NowPlayingService>();
await nowPlayingService.UpdateMetadataAsync(currentTrack);
}

public Version GetAppVersion()
Expand Down
23 changes: 22 additions & 1 deletion Sources/Stylophone.iOS/Services/NowPlayingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public class NowPlayingService

private AVAudioPlayer? _silencePlayer;

public NowPlayingService(MPDConnectionService mpdService, IApplicationStorageService storageService)
private bool _localPlaybackWasInterrupted;

public NowPlayingService(MPDConnectionService mpdService, LocalPlaybackViewModel localPlaybackVm, IApplicationStorageService storageService)
{
_mpdService = mpdService;
_storageService = storageService;
Expand All @@ -35,6 +37,25 @@ public NowPlayingService(MPDConnectionService mpdService, IApplicationStorageSer

_silencePlayer = new AVAudioPlayer(new NSUrl("silence.wav",false,NSBundle.MainBundle.ResourceUrl), null, out var error);
_silencePlayer.NumberOfLoops = -1;

// Listen for AVAudio interruptions (eg phone calls)
AVAudioSession.Notifications.ObserveInterruption((s, e) =>
{
Task.Run(() =>
{
// The interruption always seems to be marked as ended, but using a bool of our own to track interrupting works well enough.
if (localPlaybackVm.IsPlaying)
{
localPlaybackVm.Stop();
_localPlaybackWasInterrupted = true;
}
else if (_localPlaybackWasInterrupted)
{
localPlaybackVm.Resume();
_localPlaybackWasInterrupted = false;
}
});
});
}

public void Initialize()
Expand Down

0 comments on commit 5609f5e

Please sign in to comment.