From 1d919c8511850d92f0ad8a6b22780f4ad762ee50 Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Sat, 6 Aug 2022 00:01:21 -0500 Subject: [PATCH] Added VLC Strix audio service impl --- ZuneImpl/Playback/VlcAudioService.cs | 152 ++++++++++++++++++ ZuneImpl/ZuneImpl.csproj | 11 +- .../Microsoft/Zune/Shell/ZuneApplication.cs | 4 +- ZuneShell/ZuneShell.csproj | 2 +- 4 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 ZuneImpl/Playback/VlcAudioService.cs diff --git a/ZuneImpl/Playback/VlcAudioService.cs b/ZuneImpl/Playback/VlcAudioService.cs new file mode 100644 index 0000000..c5c88d7 --- /dev/null +++ b/ZuneImpl/Playback/VlcAudioService.cs @@ -0,0 +1,152 @@ +#if OPENZUNE + +using LibVLCSharp.Shared; +using NAudio.Wave; +using StrixMusic.Sdk.MediaPlayback; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using StrixPlaybackState = StrixMusic.Sdk.MediaPlayback.PlaybackState; + +namespace Microsoft.Zune.Playback +{ + public class VlcAudioService : IAudioPlayerService + { + readonly LibVLC m_vlc; + readonly MediaPlayer m_player; + private Media m_media; + private PlaybackItem m_currentSource; + + public static VlcAudioService Instance => new(); + + private VlcAudioService() + { + Core.Initialize(); + + bool debug = +#if DEBUG + true; +#else + false; +#endif + + m_vlc = new(enableDebugLogs: debug); + m_player = new(m_vlc); + } + + public PlaybackItem CurrentSource + { + get => m_currentSource; + set + { + m_currentSource = value; + CurrentSourceChanged?.Invoke(this, value); + } + } + + public TimeSpan Position { get; private set; } + + public StrixPlaybackState PlaybackState => m_player.State switch + { + VLCState.Playing => StrixPlaybackState.Playing, + + VLCState.Paused or + VLCState.Stopped => StrixPlaybackState.Paused, + + VLCState.Opening or + VLCState.Buffering => StrixPlaybackState.Loading, + + VLCState.Error => StrixPlaybackState.Failed, + + _ => StrixPlaybackState.None + }; + + public double Volume + { + get => m_player.Volume / 100d; + private set + { + m_player.Volume = (int)(value * 100); + VolumeChanged?.Invoke(this, value); + } + } + + public double PlaybackSpeed + { + get => m_player.Rate; + private set + { + m_player.SetRate((float)value); + VolumeChanged?.Invoke(this, value); + } + } + + public event EventHandler CurrentSourceChanged; + public event EventHandler QuantumProcessed; + public event EventHandler PositionChanged; + public event EventHandler PlaybackStateChanged; + public event EventHandler VolumeChanged; + public event EventHandler PlaybackSpeedChanged; + + public Task ChangePlaybackSpeedAsync(double speed, CancellationToken cancellationToken = default) + { + PlaybackSpeed = speed; + return Task.CompletedTask; + } + + public Task ChangeVolumeAsync(double volume, CancellationToken cancellationToken = default) + { + Volume = (float)volume; + return Task.CompletedTask; + } + + public Task PauseAsync(CancellationToken cancellationToken = default) + { + m_player.Pause(); + return Task.CompletedTask; + } + + public async Task Play(PlaybackItem sourceConfig, CancellationToken cancellationToken = default) + { + if (CurrentSource != sourceConfig) + await Preload(sourceConfig, cancellationToken); + + m_player.Play(m_media); + } + + public async Task Preload(PlaybackItem sourceConfig, CancellationToken cancellationToken = default) + { + CurrentSource = sourceConfig; + var uri = sourceConfig.MediaConfig.MediaSourceUri; + var stream = sourceConfig.MediaConfig.FileStreamSource; + + if (uri != null) + { + m_media = new(m_vlc, uri); + } + else if (stream != null) + { + m_media = new(m_vlc, new StreamMediaInput(stream)); + } + + await m_media.Parse(MediaParseOptions.ParseNetwork | MediaParseOptions.ParseLocal, cancellationToken: cancellationToken); + } + + public Task ResumeAsync(CancellationToken cancellationToken = default) + { + m_player.Play(); + return Task.CompletedTask; + } + + public Task SeekAsync(TimeSpan position, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + } +} + +#endif diff --git a/ZuneImpl/ZuneImpl.csproj b/ZuneImpl/ZuneImpl.csproj index 132c699..bc2750b 100644 --- a/ZuneImpl/ZuneImpl.csproj +++ b/ZuneImpl/ZuneImpl.csproj @@ -8,7 +8,7 @@ 4.8.0.0 latest - net35;net40;netstandard2.0;net6.0 + net35;net40;netstandard2.0;net6.0;net6.0-windows x64;x86 Microsoft.Zune @@ -32,7 +32,7 @@ - + True $(DefineConstants);NETSTANDARD2_1_OR_GREATER @@ -48,6 +48,9 @@ + + + @@ -60,4 +63,8 @@ + + + + diff --git a/ZuneShell/Microsoft/Zune/Shell/ZuneApplication.cs b/ZuneShell/Microsoft/Zune/Shell/ZuneApplication.cs index ee17981..d3ffc8b 100644 --- a/ZuneShell/Microsoft/Zune/Shell/ZuneApplication.cs +++ b/ZuneShell/Microsoft/Zune/Shell/ZuneApplication.cs @@ -189,7 +189,7 @@ namespace Microsoft.Zune.Shell // Add plugins string mfAudioServiceId = Guid.NewGuid().ToString(); PlaybackHandler = new PlaybackHandlerService(); - PlaybackHandler.RegisterAudioPlayer(MediaFoundationAudioService.Instance, localCore.InstanceId); + PlaybackHandler.RegisterAudioPlayer(VlcAudioService.Instance, localCore.InstanceId); DataRoot = new StrixDataRootPluginWrapper(mergedLayer, new PlaybackHandlerPlugin(PlaybackHandler) @@ -205,7 +205,7 @@ namespace Microsoft.Zune.Shell DataRoot.Library.TracksChanged += LibraryTracksChanged; - //await DataRoot.Library.PlayTrackCollectionAsync(); + await DataRoot.Library.PlayTrackCollectionAsync(); }); #endif diff --git a/ZuneShell/ZuneShell.csproj b/ZuneShell/ZuneShell.csproj index e391825..19a500c 100644 --- a/ZuneShell/ZuneShell.csproj +++ b/ZuneShell/ZuneShell.csproj @@ -45,7 +45,7 @@ - + True $(DefineConstants);WINDOWS10 $(DefineConstants);WINDOWS8