-
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Attempt at getting an async audio player working (#36)
* Attempt at getting an async audio player working * Make the async part actually work * Async playback updates
- Loading branch information
Showing
6 changed files
with
134 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/Plugin.Maui.Audio/AudioPlayer/AsyncAudioPlayer.shared.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
namespace Plugin.Maui.Audio; | ||
|
||
/// <summary> | ||
/// Provides async/await support by wrapping an <see cref="IAudioPlayer"/>. | ||
/// </summary> | ||
public class AsyncAudioPlayer | ||
{ | ||
readonly IAudioPlayer audioPlayer; | ||
CancellationTokenSource? stopCancellationToken; | ||
|
||
/// <summary> | ||
/// Creates a new instance of <see cref="AsyncAudioPlayer"/>. | ||
/// This is particularly useful if you want to customise the audio playback settings before playback. | ||
/// </summary> | ||
/// <param name="audioPlayer">An <see cref="IAudioPlayer"/> implementation to act as the underlying mechanism of playing audio.</param> | ||
public AsyncAudioPlayer(IAudioPlayer audioPlayer) | ||
{ | ||
this.audioPlayer = audioPlayer; | ||
} | ||
|
||
/// <summary> | ||
/// Begin audio playback asynchronously. | ||
/// </summary> | ||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to allow for canceling the audio playback.</param> | ||
/// <returns>A <see cref="Task"/> that represents the asynchronous operation, awaiting this method will wait until the audio has finished playing before continuing.</returns> | ||
public async Task PlayAsync(CancellationToken cancellationToken) | ||
{ | ||
var taskCompletionSource = new TaskCompletionSource(); | ||
|
||
stopCancellationToken = new(); | ||
|
||
audioPlayer.PlaybackEnded += (o, e) => taskCompletionSource.TrySetResult(); | ||
|
||
audioPlayer.Play(); | ||
|
||
await Task.WhenAny( | ||
taskCompletionSource.Task, | ||
cancellationToken.WhenCanceled(), | ||
stopCancellationToken.Token.WhenCanceled()); | ||
|
||
audioPlayer.Stop(); | ||
} | ||
|
||
/// <summary> | ||
/// Stops the currently playing audio. | ||
/// </summary> | ||
public void Stop() | ||
{ | ||
stopCancellationToken?.Cancel(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace Plugin.Maui.Audio; | ||
|
||
public static class TaskExtensions | ||
{ | ||
/// <summary> | ||
/// Provides a mechanism to await until the supplied <paramref name="cancellationToken"/> has been cancelled. | ||
/// </summary> | ||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to await.</param> | ||
/// <returns>A task that represents the asynchronous operation.</returns> | ||
public static Task WhenCanceled(this CancellationToken cancellationToken) | ||
{ | ||
var completionSource = new TaskCompletionSource<bool>(); | ||
|
||
cancellationToken.Register( | ||
input => | ||
{ | ||
if (input is TaskCompletionSource<bool> taskCompletionSource) | ||
{ | ||
taskCompletionSource.SetResult(true); | ||
} | ||
}, | ||
completionSource); | ||
|
||
return completionSource.Task; | ||
} | ||
} |