diff --git a/Mear/Mear/Managers/SongManager.cs b/Mear/Mear/Managers/SongManager.cs new file mode 100644 index 0000000..44ce21b --- /dev/null +++ b/Mear/Mear/Managers/SongManager.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using Newtonsoft.Json; +using RestSharp; + +using Mear.Constants.API; +using Mear.Models; +using Mear.Repositories.Database; + +namespace Mear.Managers +{ + public class SongManager + { + #region Methods + public bool DownloadStream(ref Song song) + { + try + { + using (var writer = File.OpenWrite(song.SongPath)) + { + var client = new RestClient(API.ApiUrl); + var apiEndpoint = $@"api/{API.APIVersion}/song/stream/{song.Id}"; + + var request = new RestRequest(apiEndpoint, Method.GET); + var tokRepo = new DBTokenRepository(); + var token = tokRepo.RetrieveToken(); + + request.AddHeader("Authorization", $"Bearer {token.AccessToken}"); + request.ResponseWriter = (responseStream) => + responseStream.CopyTo(writer); + + var response = client.DownloadData(request); + + return true; + } + } + catch (Exception ex) + { + var msg = ex.Message; + } + + return false; + } + #endregion + } +} diff --git a/Mear/Mear/Models/PlayerControls/Shuffle.cs b/Mear/Mear/Models/PlayerControls/Shuffle.cs new file mode 100644 index 0000000..5e9f62d --- /dev/null +++ b/Mear/Mear/Models/PlayerControls/Shuffle.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Mear.Models.PlayerControls +{ + public enum Shuffle + { + Off = 0, + All + } +} diff --git a/Mear/Mear/Playback/MearPlayer.cs b/Mear/Mear/Playback/MearPlayer.cs index fae9c4d..be3f450 100644 --- a/Mear/Mear/Playback/MearPlayer.cs +++ b/Mear/Mear/Playback/MearPlayer.cs @@ -12,6 +12,7 @@ using RestSharp; using Mear.Constants; using Mear.Constants.API; +using Mear.Managers; using Mear.Models; using Mear.Models.Authentication; using Mear.Models.PlayerControls; @@ -87,7 +88,7 @@ namespace Mear.Playback case PlayControls.PLAYOFFLINE: DeterminePlayType(); var plyCountRepo = new DBPlayCountRepository(); - plyCountRepo.AffectPlayCount(song); + plyCountRepo.AffectPlayCount(_song); InitializeRepeatMode(); break; case PlayControls.PAUSE: @@ -98,21 +99,31 @@ namespace Mear.Playback break; case PlayControls.STREAM: InitializeRepeatMode(); - return StreamSong(song); + return StreamSong().Result; ; case PlayControls.REPEAT: ToggleRepeat(); break; case PlayControls.SHUFFLE: - // TODO: Implement shuffling + ToggleShuffle(); break; case PlayControls.NEXT: - _song = _mearQueue.ToArray()[++QueueIndex]; + var res = DetermineControlFlow(); + if (!res) + { + QueueIndex++; + } + _song = _mearQueue.ToArray()[QueueIndex]; DeterminePlayType(); _songChanged[MusicViews.Player] = true; break; case PlayControls.PREVIOUS: - _song = _mearQueue.ToArray()[--QueueIndex]; + var prevRes = DetermineControlFlow(); + if (!prevRes) + { + QueueIndex--; + } + _song = _mearQueue.ToArray()[QueueIndex]; DeterminePlayType(); _songChanged[MusicViews.Player] = true; @@ -218,13 +229,13 @@ namespace Mear.Playback { var controlRepo = new DBMusicControlsRepository(); var shuffleOn = controlRepo.IsShuffleOn(); - try + + switch (shuffleOn) { - return shuffleOn ? "ShfOn" : "ShfOff"; - } - catch (Exception ex) - { - var msg = ex.Message; + case Shuffle.Off: + return "ShfOff"; + case Shuffle.All: + return "ShfOn"; } return string.Empty; @@ -253,6 +264,37 @@ namespace Mear.Playback InitializeRepeatMode(); } + private static Task StreamSong() + { + var tmpFile = Path.GetTempPath() + "track.mp3"; + + if (File.Exists(tmpFile)) + File.Delete(tmpFile); + + try + { + var songMgr = new SongManager(); + _song.SongPath = tmpFile; + + var downloaded = songMgr.DownloadStream(ref _song); + + if (downloaded) + { + PlaySong(); + } + + return Task.Run(() => + { + return _song; + }); + } + catch (Exception ex) + { + var msg = ex.Message; + } + + return null; + } private static Song StreamSong(Song song) { string tmpFile = Path.GetTempPath() + "track.mp3"; @@ -294,15 +336,67 @@ namespace Mear.Playback return null; } + private static bool DetermineControlFlow() + { + var ctrlRepo = new DBMusicControlsRepository(); + var repeatMode = ctrlRepo.IsRepeatOn(); + + var repRes = DetermineControlFlow(repeatMode); + if (repRes) + { + return true; + } + + var shuffleMode = ctrlRepo.IsShuffleOn(); + var shfRes = DetermineControlFlow(shuffleMode); + if (shfRes) + { + return true; + } + else + { + return false; + } + } + private static bool DetermineControlFlow(Repeat repeatMode) + { + switch (repeatMode) + { + case Repeat.ONE: + CrossMediaManager.Current.SeekToStart(); + PlaySong(); + return true; + case Repeat.ALL: + PlaySong(); + return true; + } + + return false; + } + private static bool DetermineControlFlow(Shuffle shuffleMode) + { + switch (shuffleMode) + { + case Shuffle.Off: + return false; + case Shuffle.All: + var rnd = new Random(); + var rando = rnd.Next(QueueCount); + QueueIndex = rando; + return true; + } + + return false; + } private static void DeterminePlayType() { if (!_song.Downloaded) { - StreamSong(_song); + StreamSong(); } else { - PlaySong(_song.SongPath); + PlaySong(); } } private static void InitializeModes() @@ -322,6 +416,20 @@ namespace Mear.Playback { await CrossMediaManager.Current.Pause(); } + private static async Task PlaySong() + { + await CrossMediaManager.Current.Play(_song.SongPath); + + if (_initialized == null) + { + CrossMediaManager.Current.MediaItemFinished += Current_MediaItemFinished; + _initialized = true; + } + + _songChanged[MusicViews.Song] = true; + _songChanged[MusicViews.Album] = true; + _songChanged[MusicViews.Artist] = true; + } private static async Task PlaySong(string songPath) { await CrossMediaManager.Current.Play(songPath); @@ -347,6 +455,14 @@ namespace Mear.Playback CrossMediaManager.Current.RepeatMode = RepeatUtility.RetrieveRepeatMode(repeatMode); } + private static void ToggleShuffle() + { + var musicCtrl = new DBMusicControlsRepository(); + musicCtrl.UpdateShuffle(); + var shuffleMode = musicCtrl.IsShuffleOn(); + + CrossMediaManager.Current.ShuffleMode = ShuffleUtility.RetrieveShuffleMode(shuffleMode); + } #region Background private static async Task BackgroundWork() @@ -371,6 +487,8 @@ namespace Mear.Playback var ctrlRepo = new DBMusicControlsRepository(); var repeatMode = ctrlRepo.IsRepeatOn(); + DetermineControlFlow(); + switch(repeatMode) { case Repeat.ONE: @@ -383,14 +501,28 @@ namespace Mear.Playback return; } - var song = _mearQueue.ToArray()[++QueueIndex]; - if (song.Downloaded) + var shuffleMode = ctrlRepo.IsShuffleOn(); + + switch (shuffleMode) { - PlaySong(song.SongPath); + case Shuffle.Off: + QueueIndex++; + break; + case Shuffle.All: + Random rnd = new Random(); + var rando = rnd.Next(QueueCount); + QueueIndex = rando; + break; + } + + _song = _mearQueue.ToArray()[QueueIndex]; + if (_song.Downloaded) + { + PlaySong(); } else { - StreamSong(song); + StreamSong(); } _songChanged[MusicViews.Player] = true; diff --git a/Mear/Mear/Repositories/Database/DBMusicControlsRepository.cs b/Mear/Mear/Repositories/Database/DBMusicControlsRepository.cs index 02159b7..d541139 100644 --- a/Mear/Mear/Repositories/Database/DBMusicControlsRepository.cs +++ b/Mear/Mear/Repositories/Database/DBMusicControlsRepository.cs @@ -28,7 +28,7 @@ namespace Mear.Repositories.Database #region Methods - public bool IsShuffleOn() + public Shuffle IsShuffleOn() { try { @@ -38,7 +38,7 @@ namespace Mear.Repositories.Database if (shuffle != null) { - return shuffle.Value; ; + return shuffle.Value ? Shuffle.All : Shuffle.Off; } } } @@ -47,7 +47,7 @@ namespace Mear.Repositories.Database var msg = ex.Message; } - return false; + return Shuffle.Off; } public Repeat IsRepeatOn() { diff --git a/Mear/Mear/Utilities/ShuffleUtility.cs b/Mear/Mear/Utilities/ShuffleUtility.cs new file mode 100644 index 0000000..2d10a4c --- /dev/null +++ b/Mear/Mear/Utilities/ShuffleUtility.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using MediaManager; + +using Mear.Models.PlayerControls; + +namespace Mear.Utilities +{ + public class ShuffleUtility + { + #region Methods + public static MediaManager.Queue.ShuffleMode RetrieveShuffleMode(Shuffle shuffleMode) + { + switch (shuffleMode) + { + case Shuffle.Off: + return MediaManager.Queue.ShuffleMode.Off; + case Shuffle.All: + return MediaManager.Queue.ShuffleMode.All; + } + + return MediaManager.Queue.ShuffleMode.Off; + } + #endregion + } +} diff --git a/Mear/Mear/Views/MearPlayerView.xaml.cs b/Mear/Mear/Views/MearPlayerView.xaml.cs index 29ba413..74c59b5 100644 --- a/Mear/Mear/Views/MearPlayerView.xaml.cs +++ b/Mear/Mear/Views/MearPlayerView.xaml.cs @@ -250,8 +250,9 @@ namespace Mear.Views } private void Shuffle_Clicked(object sender, EventArgs e) { - var musicCtrl = new DBMusicControlsRepository(); - musicCtrl.UpdateShuffle(); + //var musicCtrl = new DBMusicControlsRepository(); + //musicCtrl.UpdateShuffle(); + MearPlayer.ControlMusic(null, PlayControls.SHUFFLE); Shuffle.Text = MearPlayer.RetrieveShuffleString(); } diff --git a/Mear/Mear/Views/SongView.xaml.cs b/Mear/Mear/Views/SongView.xaml.cs index 93aece0..a76af65 100644 --- a/Mear/Mear/Views/SongView.xaml.cs +++ b/Mear/Mear/Views/SongView.xaml.cs @@ -150,6 +150,7 @@ namespace Mear.Views try { var song = (Song)SongListView.SelectedItem; + MearPlayer.OnSong = song; if (song.Downloaded) { await MearPlayer.ControlMusic(song, PlayControls.PLAYOFFLINE);