diff --git a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/AudioBackendFactory.cs b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/AudioBackendFactory.cs index 9ef273d..f8ba237 100644 --- a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/AudioBackendFactory.cs +++ b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/AudioBackendFactory.cs @@ -4,13 +4,14 @@ using System.Composition.Hosting; using System.Diagnostics; using System.IO; using System.Reflection; +using System.Threading.Tasks; namespace FRESHMusicPlayer.Backends { static class AudioBackendFactory { - private static ContainerConfiguration config = new ContainerConfiguration(); - private static CompositionHost container; + private readonly static ContainerConfiguration config = new ContainerConfiguration(); + private readonly static CompositionHost container; private static IEnumerable LoadAssemblies(IEnumerable paths) { @@ -37,25 +38,9 @@ namespace FRESHMusicPlayer.Backends private static void AddDirectory(string path) { - //AppDomain.CurrentDomain.AppendPrivatePath(path); - try - { - config.WithAssemblies(LoadAssemblies(Directory.GetFiles(path, "*.dll"))); - } - catch (DirectoryNotFoundException) - { - try - { - Directory.CreateDirectory(path); - } - catch - { - } - } - catch (Exception ex) - { - Trace.WriteLine(ex); - } + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + + config.WithAssemblies(LoadAssemblies(Directory.GetFiles(path, "*.dll"))); } static AudioBackendFactory() @@ -66,31 +51,18 @@ namespace FRESHMusicPlayer.Backends container = config.CreateContainer(); } - public static IAudioBackend CreateBackend(string filename) + public static async Task CreateBackendAsync(string filename) { - var exlist = new List(); + var problems = new List(); foreach (var lazybackend in container.GetExports>()) { - IAudioBackend backend = null; - try - { - backend = lazybackend.Value; - backend.LoadSong(filename); - return backend; - } - catch (Exception ex) - { - try - { - backend.Dispose(); - } - catch - { - } - exlist.Add(ex); - } + IAudioBackend backend = lazybackend.Value; + var result = await backend.LoadSongAsync(filename); + + if (result != BackendLoadResult.OK) problems.Add(result); + else return backend; } - throw new Exception($"No backend could be found to play {filename}.\n\n{String.Join("\n\n", exlist)}\n"); + throw new Exception($"A backend couldn't be found to load this file\n{string.Join("\n", problems)}"); } } } diff --git a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/FileMetadataProvider.cs b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/FileMetadataProvider.cs index f8dd413..0663c8b 100644 --- a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/FileMetadataProvider.cs +++ b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/FileMetadataProvider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading.Tasks; namespace FRESHMusicPlayer.Backends { @@ -29,6 +30,9 @@ namespace FRESHMusicPlayer.Backends public Track ATLTrack { get; set; } - public FileMetadataProvider(string path) => ATLTrack = new Track(path); + private string path; + public FileMetadataProvider(string path) => this.path = path; + + public async Task LoadAsync() => await Task.Run(() => ATLTrack = new Track(path)); } } diff --git a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/IAudioBackend.cs b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/IAudioBackend.cs index f24a507..bdd1804 100644 --- a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/IAudioBackend.cs +++ b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/IAudioBackend.cs @@ -34,6 +34,8 @@ namespace FRESHMusicPlayer.Backends int TrackTotal { get; } int DiscNumber { get; } int DiscTotal { get; } + + Task LoadAsync(); } public enum BackendLoadResult @@ -41,6 +43,7 @@ namespace FRESHMusicPlayer.Backends OK, NotSupported, Invalid, - Corrupt + Corrupt, + UnknownError } } diff --git a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/NAudioBackend.cs b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/NAudioBackend.cs index 90fd87d..3391d30 100644 --- a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/NAudioBackend.cs +++ b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Backends/NAudioBackend.cs @@ -46,8 +46,6 @@ namespace FRESHMusicPlayer.Backends public async Task LoadSongAsync(string file) { - if (!File.Exists(file)) return BackendLoadResult.Invalid; - if (AudioFile != null) AudioFile.Dispose(); try { @@ -75,6 +73,11 @@ namespace FRESHMusicPlayer.Backends { return BackendLoadResult.Invalid; } + catch (Exception e) + { + Console.WriteLine(e); + return BackendLoadResult.UnknownError; + } return BackendLoadResult.OK; } diff --git a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Player.cs b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Player.cs index 9bc1c11..539dd01 100644 --- a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Player.cs +++ b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Player.cs @@ -6,6 +6,7 @@ using System.Reflection; using FRESHMusicPlayer.Handlers; using FRESHMusicPlayer.Utilities; using FRESHMusicPlayer.Backends; +using System.Threading.Tasks; namespace FRESHMusicPlayer { @@ -49,7 +50,7 @@ namespace FRESHMusicPlayer /// public string FilePath { get; private set; } = string.Empty; /// - /// Whether the audio backend and file has been loaded and things are ready to go. If you interact with the Player everything + /// Whether the audio backend and file has been loaded and things are ready to go. If you interact with the Player when this is false everything /// will explode. /// public bool FileLoaded { get; set; } @@ -78,18 +79,18 @@ namespace FRESHMusicPlayer /// /// Skips to the previous track in the Queue. If there are no tracks for the player to go back to, nothing will happen. /// - public void PreviousSong() + public async Task PreviousAsync() { if (Queue.Position <= 1) return; Queue.Position -= 2; - PlayMusic(); + await PlayAsync(); } /// /// Skips to the next track in the Queue. If there are no more tracks, the player will stop. /// /// Intended to be used only by the player - public void NextSong(bool avoidNext = false) + public async Task NextAsync(bool avoidNext = false) { AvoidNextQueue = avoidNext; if (Queue.RepeatMode == RepeatMode.RepeatOne) Queue.Position--; // Don't advance Queue, play the same thing again @@ -99,21 +100,20 @@ namespace FRESHMusicPlayer if (Queue.RepeatMode == RepeatMode.RepeatAll) // Go back to the first track and play it again { Queue.Position = 0; - PlayMusic(); + await PlayAsync(); return; } - Queue.Clear(); - StopMusic(); + Stop(); return; } - PlayMusic(); + await PlayAsync(); } // Music Playing Controls - private void OnPlaybackStopped(object sender, EventArgs args) + private async void OnPlaybackStopped(object sender, EventArgs args) { if (!AvoidNextQueue) - NextSong(); + await NextAsync(); else AvoidNextQueue = false; } @@ -131,23 +131,23 @@ namespace FRESHMusicPlayer /// Plays a track. This is equivalent to calling Queue.Add() and then PlayMusic()./> /// /// The track to play - public void PlayMusic(string path) + public async Task PlayMusicAsync(string path) { Queue.Add(path); - PlayMusic(); + await PlayAsync(); } /// /// Starts playing the Queue. In order to play a track, you must first add it to the Queue using . /// /// If true, avoids dequeuing the next track. Not to be used for anything other than the player. - public void PlayMusic(bool repeat = false) + public async Task PlayAsync(bool repeat = false) { if (!repeat && Queue.Queue.Count != 0) FilePath = Queue.Queue[Queue.Position]; Queue.Position++; - void PMusic() + async Task PMusic() { - CurrentBackend = AudioBackendFactory.CreateBackend(FilePath); + CurrentBackend = await AudioBackendFactory.CreateBackendAsync(FilePath); CurrentBackend.Play(); CurrentBackend.Volume = Volume; @@ -160,43 +160,18 @@ namespace FRESHMusicPlayer { if (FileLoaded != true) { - PMusic(); + await PMusic(); } else { AvoidNextQueue = true; - StopMusic(); - PMusic(); + Stop(); + await PMusic(); } SongChanged?.Invoke(null, EventArgs.Empty); // Now that playback has started without any issues, fire the song changed event. } - //catch (FileNotFoundException) // TODO: move these to NAudioBackend - //{ - // var args = new PlaybackExceptionEventArgs {Details = "That's not a valid file path!"}; - // SongException?.Invoke(null, args); - //} - //catch (ArgumentException) - //{ - // var args = new PlaybackExceptionEventArgs {Details = "That's not a valid file path!"}; - // SongException?.Invoke(null, args); - //} - //catch (System.Runtime.InteropServices.COMException) - //{ - // var args = new PlaybackExceptionEventArgs {Details = "This isn't a valid audio file!"}; - // SongException?.Invoke(null, args); - //} - //catch (FormatException) - //{ - // var args = new PlaybackExceptionEventArgs {Details = "This audio file might be corrupt!"}; - // SongException?.Invoke(null, args); - //} - //catch (InvalidOperationException) - //{ - // var args = new PlaybackExceptionEventArgs {Details = "This audio file uses VBR \nor might be corrupt!"}; - // SongException?.Invoke(null, args); - //} catch (Exception e) { var args = new PlaybackExceptionEventArgs(e, $"{e.Message}\n{e.StackTrace}"); @@ -207,7 +182,7 @@ namespace FRESHMusicPlayer /// /// Completely stops and disposes the player and resets all playback related variables to their defaults. /// - public void StopMusic() + public void Stop() { if (!FileLoaded) return; @@ -222,7 +197,7 @@ namespace FRESHMusicPlayer /// /// Pauses playback without disposing. Can later be resumed with . /// - public void PauseMusic() + public void Pause() { if (!Paused) CurrentBackend?.Pause(); @@ -232,7 +207,7 @@ namespace FRESHMusicPlayer /// /// Resumes playback. /// - public void ResumeMusic() + public void Resume() { if (Paused) CurrentBackend?.Play(); @@ -240,41 +215,5 @@ namespace FRESHMusicPlayer } #endregion - - // Integration - - //#region DiscordRPC // TODO: move this to the frontend - ///// - ///// Initializes the Discord RPC client. Once it has been initialized, you can set the presence by using - ///// - ///// The application ID of your app - //public void InitDiscordRPC(string applicationID) - //{ // FMP application ID - 656678380283887626 - // Client = new DiscordRpcClient(applicationID); - - // Client.OnReady += (sender, e) => { Console.WriteLine("Received Ready from user {0}", e.User.Username); }; - // Client.OnPresenceUpdate += (sender, e) => { Console.WriteLine("Received Update! {0}", e.Presence); }; - // Client.Initialize(); - //} - - //public void UpdateRPC(string Activity, string Artist = null, string Title = null) - //{ - // Client?.SetPresence(new RichPresence() - // { - // Details = PlayerUtils.TruncateBytes(Title, 120), - // State = PlayerUtils.TruncateBytes(Artist, 120), - // Assets = new Assets() - // { - // LargeImageKey = "icon", - // SmallImageKey = Activity - // }, - // Timestamps = Timestamps.Now - // } - // ); - //} - - //public void DisposeRPC() => Client?.Dispose(); - - //#endregion } } \ No newline at end of file diff --git a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Properties/AssemblyInfo.cs b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Properties/AssemblyInfo.cs index 640aeb9..3edf339 100644 --- a/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Properties/AssemblyInfo.cs +++ b/FRESHMusicPlayer.Player/FRESHMusicPlayer.Player/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("4.0.0.0")] +[assembly: AssemblyFileVersion("4.0.0.0")] diff --git a/FRESHMusicPlayer.Player/FmpBassBackend/FMPMediaPlayer.cs b/FRESHMusicPlayer.Player/FmpBassBackend/FMPMediaPlayer.cs deleted file mode 100644 index 41105bf..0000000 --- a/FRESHMusicPlayer.Player/FmpBassBackend/FMPMediaPlayer.cs +++ /dev/null @@ -1,291 +0,0 @@ -using ManagedBass; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace FmpBassBackend -{ - /// - /// A modified version of ManagedBass's MediaPlayer that loads songs synchronously - /// (FMP.Core currently does not support async loading) - /// - public class FMPMediaPlayer : INotifyPropertyChanged, IDisposable - { - #region Fields - readonly SynchronizationContext _syncContext; - int _handle; - - /// - /// Channel Handle of the loaded audio file. - /// - protected internal int Handle - { - get => _handle; - private set - { - if (!Bass.ChannelGetInfo(value, out var info)) - throw new ArgumentException("Invalid Channel Handle: " + value); - - _handle = value; - - // Init Events - Bass.ChannelSetSync(Handle, SyncFlags.Free, 0, GetSyncProcedure(() => Disposed?.Invoke(this, EventArgs.Empty))); - Bass.ChannelSetSync(Handle, SyncFlags.Stop, 0, GetSyncProcedure(() => MediaFailed?.Invoke(this, EventArgs.Empty))); - Bass.ChannelSetSync(Handle, SyncFlags.End, 0, GetSyncProcedure(() => - { - try - { - if (!Bass.ChannelHasFlag(Handle, BassFlags.Loop)) - MediaEnded?.Invoke(this, EventArgs.Empty); - } - finally { OnStateChanged(); } - })); - } - } - - bool _restartOnNextPlayback; - #endregion - - SyncProcedure GetSyncProcedure(Action Handler) - { - return (SyncHandle, Channel, Data, User) => - { - if (Handler == null) - return; - - if (_syncContext == null) - Handler(); - else _syncContext.Post(S => Handler(), null); - }; - } - - static FMPMediaPlayer() - { - var currentDev = Bass.CurrentDevice; - - if (currentDev == -1 || !Bass.GetDeviceInfo(Bass.CurrentDevice).IsInitialized) - Bass.Init(currentDev); - } - - /// - /// Creates a new instance of . - /// - public FMPMediaPlayer() { _syncContext = SynchronizationContext.Current; } - - #region Events - /// - /// Fired when this Channel is Disposed. - /// - public event EventHandler Disposed; - - /// - /// Fired when the Media Playback Ends - /// - public event EventHandler MediaEnded; - - /// - /// Fired when the Playback fails - /// - public event EventHandler MediaFailed; - #endregion - - #region Device - int _dev = -1; - - /// - /// Gets or Sets the Playback Device used. - /// - public int Device - { - get => (_dev = _dev == -1 ? Bass.ChannelGetDevice(Handle) : _dev); - set - { - if (!Bass.GetDeviceInfo(value).IsInitialized) - if (!Bass.Init(value)) - return; - - if (!Bass.ChannelSetDevice(Handle, value)) - return; - - _dev = value; - OnPropertyChanged(); - } - } - #endregion - - #region Volume - double _vol = 0.5; - - /// - /// Gets or Sets the Playback Volume. - /// - public double Volume - { - get => _vol; - set - { - if (!Bass.ChannelSetAttribute(Handle, ChannelAttribute.Volume, value)) - return; - - _vol = value; - OnPropertyChanged(); - } - } - #endregion - - /// - /// Override this method for custom loading procedure. - /// - /// Path to the File to Load. - /// on Success, on failure - protected virtual int OnLoad(string FileName) => Bass.CreateStream(FileName); - /// - /// Gets the Playback State of the Channel. - /// - public PlaybackState State => Handle == 0 ? PlaybackState.Stopped : Bass.ChannelIsActive(Handle); - - #region Playback - /// - /// Starts the Channel Playback. - /// - public bool Play() - { - try - { - var result = Bass.ChannelPlay(Handle, _restartOnNextPlayback); - - if (result) - _restartOnNextPlayback = false; - - return result; - } - finally { OnStateChanged(); } - } - - /// - /// Pauses the Channel Playback. - /// - public bool Pause() - { - try { return Bass.ChannelPause(Handle); } - finally { OnStateChanged(); } - } - - /// - /// Stops the Channel Playback. - /// - /// Difference from : Playback is restarted when is called. - public bool Stop() - { - try - { - _restartOnNextPlayback = true; - return Bass.ChannelStop(Handle); - } - finally { OnStateChanged(); } - } - #endregion - - /// - /// Gets the Playback Duration. - /// - public TimeSpan Duration => TimeSpan.FromSeconds(Bass.ChannelBytes2Seconds(Handle, Bass.ChannelGetLength(Handle))); - - /// - /// Gets or Sets the Playback Position. - /// - public TimeSpan Position - { - get => TimeSpan.FromSeconds(Bass.ChannelBytes2Seconds(Handle, Bass.ChannelGetPosition(Handle))); - set => Bass.ChannelSetPosition(Handle, Bass.ChannelSeconds2Bytes(Handle, value.TotalSeconds)); - } - - /// - /// Loads a file into the player. - /// - /// Path to the file to Load. - /// on succes, on failure. - public bool Load(string FileName) - { - try - { - if (Handle != 0) - Bass.StreamFree(Handle); - } - catch { } - - if (_dev != -1) - Bass.CurrentDevice = _dev; - - var currentDev = Bass.CurrentDevice; - - if (currentDev == -1 || !Bass.GetDeviceInfo(Bass.CurrentDevice).IsInitialized) - Bass.Init(currentDev); - - var h = OnLoad(FileName); - - if (h == 0) - return false; - - Handle = h; - - InitProperties(); - - MediaLoaded?.Invoke(h); - - OnPropertyChanged(""); - - return true; - } - - /// - /// Fired when a Media is Loaded. - /// - public event Action MediaLoaded; - - /// - /// Frees all resources used by the player. - /// - public virtual void Dispose() - { - try - { - if (Bass.StreamFree(Handle)) - _handle = 0; - } - finally { OnStateChanged(); } - } - - /// - /// Initializes Properties on every call to . - /// - protected virtual void InitProperties() - { - Volume = _vol; - } - - void OnStateChanged() => OnPropertyChanged(nameof(State)); - - /// - /// Fired when a property value changes. - /// - public event PropertyChangedEventHandler PropertyChanged; - - /// - /// Fires the event. - /// - protected virtual void OnPropertyChanged([CallerMemberName] string PropertyName = null) - { - Action f = () => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName)); - - if (_syncContext == null) - f(); - else _syncContext.Post(S => f(), null); - } - } -} diff --git a/FRESHMusicPlayer.Player/FmpBassBackend/FmpBassBackend.cs b/FRESHMusicPlayer.Player/FmpBassBackend/FmpBassBackend.cs index c255193..14d28fb 100644 --- a/FRESHMusicPlayer.Player/FmpBassBackend/FmpBassBackend.cs +++ b/FRESHMusicPlayer.Player/FmpBassBackend/FmpBassBackend.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices; +using System.Threading.Tasks; namespace FmpBassBackend { @@ -20,7 +21,9 @@ namespace FmpBassBackend public event EventHandler OnPlaybackStopped; - private readonly FMPMediaPlayer player = new FMPMediaPlayer(); + public IMetadataProvider Metadata { get; private set; } + + private readonly MediaPlayer player = new MediaPlayer(); public FmpBassBackend() { @@ -28,7 +31,7 @@ namespace FmpBassBackend if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // on windows media foundation already provides flac support, { // don't bother var currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - Bass.PluginLoad(Path.Combine(currentDirectory, GetExtensionForCurrentPlatform("libbassflac"))); + Bass.PluginLoad(Path.Combine(currentDirectory, GetExtensionForCurrentPlatform("bassflac"))); } } @@ -36,9 +39,14 @@ namespace FmpBassBackend public void Dispose() => player.Dispose(); - public void LoadSong(string file) + public async Task LoadSongAsync(string file) { - if (!player.Load(file)) throw new Exception("loading didn't work :("); // not awaited because fmpcore currently does not support await like this + var wasSuccessful = await player.LoadAsync(file); + + Metadata = new FileMetadataProvider(file); + + if (!wasSuccessful) return BackendLoadResult.Invalid; + else return BackendLoadResult.OK; } public void Pause() => player.Pause(); @@ -47,8 +55,8 @@ namespace FmpBassBackend private string GetExtensionForCurrentPlatform(string name) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return $"{name}.so"; - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) return $"{name}.dylib"; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return $"lib{name}.so"; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) return $"lib{name}.dylib"; else return $"{name}.dll"; } } diff --git a/FRESHMusicPlayer.Player/FmpCdLibBackend/CDLibMetadataProvider.cs b/FRESHMusicPlayer.Player/FmpCdLibBackend/CDLibMetadataProvider.cs new file mode 100644 index 0000000..04d91ab --- /dev/null +++ b/FRESHMusicPlayer.Player/FmpCdLibBackend/CDLibMetadataProvider.cs @@ -0,0 +1,41 @@ +using CDLib; +using FRESHMusicPlayer.Backends; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FmpCdLibBackend +{ + public class CDLibMetadataProvider : IMetadataProvider + { + public string Title => track.Title; + + public string[] Artists => new string[] { track.Artist }; + + public string Album => track.AlbumTitle; + + public byte[] CoverArt => null; + + public string[] Genres => null; + + public int Year => 0; + + public int TrackNumber => (int)track.TrackNumber; + + public int TrackTotal => 0; + + public int DiscNumber => 0; + + public int DiscTotal => 0; + + private readonly IAudioCDTrack track; + public CDLibMetadataProvider(IAudioCDTrack track) => this.track = track; + + public Task LoadAsync() + { + return Task.CompletedTask; + } + } +} diff --git a/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.cs b/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.cs index 702483a..96f9995 100644 --- a/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.cs +++ b/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.cs @@ -22,6 +22,8 @@ namespace FmpCdLibBackend public float Volume { get => (float)player.Volume; set => player.Volume = value; } + public IMetadataProvider Metadata { get; private set; } + public event EventHandler OnPlaybackStopped; public FmpCdLibBackend() @@ -46,24 +48,31 @@ namespace FmpCdLibBackend //player.Dispose(); } - public void LoadSong(string file) + public async Task LoadSongAsync(string file) { - if (Path.GetExtension(file).ToUpper() != ".CDA") throw new Exception("Not a CD"); - // super hacky; assumes that the path is something like D:\Track01.cda, might be a better way to do this - var driveLetter = char.Parse(file.Substring(0, 1)); - var trackNumber = int.Parse(file.Substring(8, 2)); + if (Path.GetExtension(file).ToUpper() != ".CDA") return BackendLoadResult.NotSupported; - var drives = player.GetDrives(); - foreach (var drive in drives) + var result = BackendLoadResult.Invalid; + await Task.Run(() => { - if (drive.DriveLetter == driveLetter) + // super hacky; assumes that the path is something like D:\Track01.cda, might be a better way to do this + var driveLetter = char.Parse(file.Substring(0, 1)); + var trackNumber = int.Parse(file.Substring(8, 2)); + + var drives = player.GetDrives(); + foreach (var drive in drives) { - var trackToPlay = drive.InsertedMedia.Tracks[trackNumber - 1]; - TotalTime = trackToPlay.Duration; - player.PlayTrack(trackToPlay); - return; + if (drive.DriveLetter == driveLetter) + { + var trackToPlay = drive.InsertedMedia.Tracks[trackNumber - 1]; + TotalTime = trackToPlay.Duration; + player.PlayTrack(trackToPlay); + Metadata = new CDLibMetadataProvider(trackToPlay); + result = BackendLoadResult.OK; + } } - } + }); + return result; } public void Pause() diff --git a/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.csproj b/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.csproj index 9c6f6a1..c0d02a5 100644 --- a/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.csproj +++ b/FRESHMusicPlayer.Player/FmpCdLibBackend/FmpCdLibBackend.csproj @@ -45,6 +45,7 @@ + diff --git a/FRESHMusicPlayer.Player/WinformsTest/Form1.cs b/FRESHMusicPlayer.Player/WinformsTest/Form1.cs index b0ddd6f..b693d2c 100644 --- a/FRESHMusicPlayer.Player/WinformsTest/Form1.cs +++ b/FRESHMusicPlayer.Player/WinformsTest/Form1.cs @@ -48,22 +48,22 @@ namespace WinformsTest private void button1_Click(object sender, EventArgs e) // pause/resume { - if (player.Paused) player.ResumeMusic(); - else player.PauseMusic(); + if (player.Paused) player.Resume(); + else player.Pause(); } private void button2_Click(object sender, EventArgs e) // stop { - player.StopMusic(); + player.Stop(); } - private void button3_Click(object sender, EventArgs e) // play + private async void button3_Click(object sender, EventArgs e) // play { var openFileDialog1 = new OpenFileDialog(); if (openFileDialog1.ShowDialog() != DialogResult.OK) return; player.Queue.Add(openFileDialog1.FileName); - player.PlayMusic(); - player.Volume = 0.7f; + await player.PlayAsync(); + player.Volume = 0.5f; } private void FreshMusicPlayer_Load(object sender, EventArgs e) @@ -71,14 +71,14 @@ namespace WinformsTest } - private void button4_Click(object sender, EventArgs e) // next + private async void button4_Click(object sender, EventArgs e) // next { - player.NextSong(); + await player.NextAsync(); } - private void button5_Click(object sender, EventArgs e) // previous + private async void button5_Click(object sender, EventArgs e) // previous { - player.PreviousSong(); + await player.PreviousAsync(); } private void button6_Click(object sender, EventArgs e) // extra button 1