Finish PlayerInteropAudioService

This commit is contained in:
Yoshi Askharoun
2023-05-03 22:56:14 -05:00
parent 35a8ad11bc
commit 6efd1529b8
4 changed files with 139 additions and 12 deletions
+99 -8
View File
@@ -1,8 +1,12 @@
#if OPENZUNE
using CommunityToolkit.Diagnostics;
using MicrosoftZunePlayback;
using OwlCore.Storage;
using OwlCore.Storage.SystemIO;
using StrixMusic.Sdk.MediaPlayback;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -11,8 +15,33 @@ namespace Microsoft.Zune.Playback
public class PlayerInteropAudioService : IAudioPlayerService
{
private readonly PlayerInterop _playbackWrapper = PlayerInterop.Instance;
private readonly IModifiableFolder _tempFolder;
private PlaybackItem m_currentSource;
private int _playbackId = 0;
public PlaybackItem CurrentSource { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public PlayerInteropAudioService(IModifiableFolder tempFolder)
{
_tempFolder = tempFolder;
}
public PlayerInteropAudioService()
{
DirectoryInfo cacheFolderPath = new(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\Zune\OpenZune\PlayerInteropTemp"));
cacheFolderPath.Create();
_tempFolder = new SystemFolder(cacheFolderPath);
}
public static PlayerInteropAudioService Instance => new();
public PlaybackItem CurrentSource
{
get => m_currentSource;
set
{
m_currentSource = value;
CurrentSourceChanged?.Invoke(this, value);
}
}
public TimeSpan Position => new(_playbackWrapper.Position);
@@ -20,7 +49,7 @@ namespace Microsoft.Zune.Playback
public double Volume => _playbackWrapper.Volume / 100d;
public double PlaybackSpeed => 1.0d;
public double PlaybackSpeed => _playbackWrapper.Rate;
public event EventHandler<PlaybackItem> CurrentSourceChanged;
public event EventHandler<float[]> QuantumProcessed;
@@ -31,7 +60,8 @@ namespace Microsoft.Zune.Playback
public Task ChangePlaybackSpeedAsync(double speed, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
_playbackWrapper.Rate = (float)speed;
return Task.CompletedTask;
}
public Task ChangeVolumeAsync(double volume, CancellationToken cancellationToken = default)
@@ -46,15 +76,29 @@ namespace Microsoft.Zune.Playback
return Task.CompletedTask;
}
public Task Play(PlaybackItem sourceConfig, CancellationToken cancellationToken = default)
public async Task Play(PlaybackItem sourceConfig, CancellationToken cancellationToken = default)
{
_playbackWrapper.Play();
return Task.CompletedTask;
var media = await LoadAsync(sourceConfig.MediaConfig);
Iris.Application.DeferredInvoke(new Iris.DeferredInvokeHandler(delegate
{
// Play cannot be called immediately after SetUri,
// so we have to listen for when the change is done.
_playbackWrapper.UriSet += PlaybackWrapper_UriSet;
_playbackWrapper.SetUri(media.Uri, 0, media.Id);
}), Iris.DeferredInvokePriority.Normal);
}
public Task Preload(PlaybackItem sourceConfig, CancellationToken cancellationToken = default)
private void PlaybackWrapper_UriSet(object sender, EventArgs e)
{
throw new NotImplementedException();
_playbackWrapper.UriSet -= PlaybackWrapper_UriSet;
_playbackWrapper.Play();
}
public async Task Preload(PlaybackItem sourceConfig, CancellationToken cancellationToken = default)
{
var media = await LoadAsync(sourceConfig.MediaConfig);
_playbackWrapper.SetNextUri(media.Uri, 0, media.Id);
}
public Task ResumeAsync(CancellationToken cancellationToken = default)
@@ -69,6 +113,53 @@ namespace Microsoft.Zune.Playback
_playbackWrapper.SeekToAbsolutePosition(position.Ticks);
return Task.CompletedTask;
}
private async Task<PlayerInteropMedia> LoadAsync(IMediaSourceConfig mediaConfig, bool saveStream = true)
{
Guard.IsNotNull(mediaConfig);
mediaConfig.FileStreamSource?.Dispose();
var url = mediaConfig.MediaSourceUri?.ToString();
if (url is null)
{
if (IsValidUri(mediaConfig.Id))
{
url = mediaConfig.Id;
}
else if (saveStream && mediaConfig.FileStreamSource is not null)
{
var dstFile = await _tempFolder.CreateFileAsync(mediaConfig.Id, true);
using (var stream = await dstFile.OpenStreamAsync(FileAccess.ReadWrite))
{
await mediaConfig.FileStreamSource.CopyToAsync(stream);
}
Guard.IsTrue(IsValidUri(url));
url = dstFile.Id;
}
else
{
throw new ArgumentException("PlayerInterop can only load media from a URI.");
}
}
return new(url, ++_playbackId);
}
private static bool IsValidUri(string? url) => Uri.TryCreate(url, UriKind.Absolute, out _);
private readonly struct PlayerInteropMedia
{
public PlayerInteropMedia(string uri, int id)
{
Uri = uri;
Id = id;
}
public string Uri { get; }
public int Id { get; }
}
}
}
@@ -182,9 +182,9 @@ namespace Microsoft.Zune.Shell
// Perform any async initialization needed. Authenticating, connecting to database, etc.
// Add plugins
string mfAudioServiceId = Guid.NewGuid().ToString();
PlaybackHandler = new PlaybackHandlerService();
PlaybackHandler.RegisterAudioPlayer(VlcAudioService.Instance, localCore.InstanceId);
//PlaybackHandler.RegisterAudioPlayer(PlayerInteropAudioService.Instance, localCore.InstanceId);
DataRoot = new StrixDataRootPluginWrapper(mergedLayer,
new PlaybackHandlerPlugin(PlaybackHandler)
@@ -219,7 +219,7 @@ namespace Microsoft.Zune.Shell
ITrack firstTrack = addedItems[1].Data;
await firstTrack.PlayArtistCollectionAsync();
//await firstTrack.PlayArtistCollectionAsync();
}
}
@@ -6,6 +6,9 @@ namespace ZuneUI
{
partial class TransportControls
{
private void OnInit() { }
private void OnUninit() { }
private void OnPlayClicked(object sender, EventArgs e)
{
if (!this._play.Available)
@@ -1,4 +1,6 @@
using Microsoft.Zune.Util;
using Microsoft.Iris;
using Microsoft.Zune.Shell;
using Microsoft.Zune.Util;
using MicrosoftZunePlayback;
using StrixMusic.Sdk.MediaPlayback;
using System;
@@ -7,7 +9,18 @@ namespace ZuneUI
{
partial class TransportControls
{
private readonly IPlaybackHandlerService _playbackHandler = Microsoft.Zune.Shell.ZuneApplication.PlaybackHandler;
private IPlaybackHandlerService _playbackHandler;
private void OnInit()
{
_playbackHandler = ZuneApplication.PlaybackHandler;
_playbackHandler.CurrentItemChanged += PlaybackHandler_CurrentItemChanged;
}
private void OnUninit()
{
_playbackHandler.CurrentItemChanged -= PlaybackHandler_CurrentItemChanged;
}
private async void OnPlayClicked(object sender, EventArgs e)
{
@@ -131,5 +144,25 @@ namespace ZuneUI
}
}
}
private async void PlaybackHandler_CurrentItemChanged(object sender, PlaybackItem e)
{
// NOTE: This currently does not work. Perhaps something to do with
// the lack of a valid media ID?
string title = $"[Strix] {e.Track.Name}";
int num = e.Track.TrackNumber ?? 0;
string album = e.Track.Album?.Name ?? string.Empty;
string artist = string.Empty;
await foreach (var artistItem in e.Track.GetArtistItemsAsync(1, 0))
artist = artistItem.Name;
Application.DeferredInvoke(new DeferredInvokeHandler(delegate
{
Microsoft.Zune.Util.Notification.ResetNowPlaying();
Microsoft.Zune.Util.Notification.BroadcastNowPlaying(EMediaTypes.eMediaTypeAudio, album, artist, title, num, Guid.NewGuid());
}), DeferredInvokePriority.Normal);
}
}
}