diff --git a/Aurora/Design/Views/Party/PartyViewModel.cs b/Aurora/Design/Views/Party/PartyViewModel.cs index d047e63..da24c1f 100644 --- a/Aurora/Design/Views/Party/PartyViewModel.cs +++ b/Aurora/Design/Views/Party/PartyViewModel.cs @@ -32,7 +32,6 @@ namespace Aurora.Design.Views.Party private ObservableCollection _members; private ObservableCollection _queue; private BaseMedia _selectedMedia; - // private IClientService _client; private ISettingsService _settingsService; private IClientService _clientService; private IServerService _serverService; diff --git a/Aurora/Models/Media/RemoteAudio.cs b/Aurora/Models/Media/RemoteAudio.cs index 5620722..cdf6487 100644 --- a/Aurora/Models/Media/RemoteAudio.cs +++ b/Aurora/Models/Media/RemoteAudio.cs @@ -58,6 +58,7 @@ namespace Aurora.Models.Media { try { + _cancellationTokenSource = new CancellationTokenSource(); while (await call.ResponseStream.MoveNext(_cancellationTokenSource.Token)) { Chunk chunk = call.ResponseStream.Current; @@ -80,13 +81,13 @@ namespace Aurora.Models.Media /// public override void Unload() { - // if (!_cancellationTokenSource.IsCancellationRequested) - // { - // _cancellationTokenSource.Cancel(); + if (!_cancellationTokenSource.IsCancellationRequested) + { + _cancellationTokenSource.Cancel(); - // //Wait for cancellation - // WaitHandle.WaitAny(new[] { _cancellationTokenSource.Token.WaitHandle }); - // } + //Wait for cancellation + WaitHandle.WaitAny(new[] { _cancellationTokenSource.Token.WaitHandle }); + } base.Unload(); } } diff --git a/Aurora/Services/Player/PlayerService.cs b/Aurora/Services/Player/PlayerService.cs index 83e19b9..9c81006 100644 --- a/Aurora/Services/Player/PlayerService.cs +++ b/Aurora/Services/Player/PlayerService.cs @@ -16,6 +16,7 @@ namespace Aurora.Services.Player private MediaPlayer _mediaPlayer; private LibVLC _libvlc; private PlaybackState _state; + private CancellationTokenSource _remoteSyncCancellationTokenSource; public PlayerService() { @@ -61,7 +62,7 @@ namespace Aurora.Services.Player { get { - return _mediaPlayer.Position; + return _mediaPlayer != null ? _mediaPlayer.Position : -1; } } @@ -69,7 +70,7 @@ namespace Aurora.Services.Player { get { - return _mediaPlayer.Length; + return _mediaPlayer != null ? _mediaPlayer.Length : -1; } } @@ -105,6 +106,13 @@ namespace Aurora.Services.Player PlaybackState oldState = _state; _state = PlaybackState.Playing; + //Cancel sync if not cancelled + if (_remoteSyncCancellationTokenSource != null && !_remoteSyncCancellationTokenSource.IsCancellationRequested) + { + _remoteSyncCancellationTokenSource.Cancel(); + _remoteSyncCancellationTokenSource = null; + } + _mediaPlayer.Play(); //Use sync RPC for remote audio if (_currentMedia is RemoteAudio) @@ -118,13 +126,13 @@ namespace Aurora.Services.Player //Task completes when host stops syncing (when a song is complete) Task syncTask = new Task(async () => { - CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + _remoteSyncCancellationTokenSource = new CancellationTokenSource(); using (AsyncServerStreamingCall syncStream = remotePartyServiceClient .SyncMedia(new SyncMediaRequest() { })) { try { - while (await syncStream.ResponseStream.MoveNext(cancellationTokenSource.Token)) + while (await syncStream.ResponseStream.MoveNext(_remoteSyncCancellationTokenSource.Token)) { Sync sync = new Sync(syncStream.ResponseStream.Current); if (sync != null) @@ -159,7 +167,7 @@ namespace Aurora.Services.Player } catch (Exception ex) { - Console.WriteLine("Exception caught while attempting to sync: " + ex.Message); + Console.WriteLine("Exception caught while attempting to sync: " + ex.Message + ": " + ex.StackTrace); } } }); @@ -198,6 +206,13 @@ namespace Aurora.Services.Player _state = PlaybackState.Stopped; _mediaPlayer.Stop(); + //Cancel sync if not cancelled + if (_remoteSyncCancellationTokenSource != null && !_remoteSyncCancellationTokenSource.IsCancellationRequested) + { + _remoteSyncCancellationTokenSource.Cancel(); + _remoteSyncCancellationTokenSource = null; + } + if (PlaybackStateChanged != null) { PlaybackStateChanged.Invoke(this, new PlaybackStateChangedEventArgs(oldState, _state)); @@ -219,6 +234,10 @@ namespace Aurora.Services.Player /// private void Unload() { + if (_currentMedia == null) + { + return; + } _currentMedia.Unload(); _currentMedia = null; _mediaPlayer.Media = null; diff --git a/Aurora/Services/Server/Controllers/MediaController.cs b/Aurora/Services/Server/Controllers/MediaController.cs index 35ea244..5b617be 100644 --- a/Aurora/Services/Server/Controllers/MediaController.cs +++ b/Aurora/Services/Server/Controllers/MediaController.cs @@ -110,32 +110,31 @@ namespace Aurora.Services.Server.Controllers bool continueSync = true; using (var scope = App.Container.BeginLifetimeScope()) { - IPlayer player = scope.Resolve(); - - string currentId = player.CurrentMedia.Id; - MediaChangedEventHandler mediaChanged = (sender, e) => + try { - if (e.NewId != currentId) + IPlayer player = scope.Resolve(); + + string currentId = player.CurrentMedia.Id; + while (continueSync) { - continueSync = false; + float length = player.CurrentMediaLength; + + Sync sync = new Sync() + { + TrackPosition = player.CurrentMediaPosition, + ServerTimeTicks = Utils.TimeUtils.GetNetworkTime().DateTime.Ticks + }; + await responseStream.WriteAsync(sync); + Console.WriteLine("Sent Sync"); + await Task.Delay(5000); } - }; - - player.MediaChanged += mediaChanged; - - while (continueSync) - { - float length = player.CurrentMediaLength; - - Sync sync = new Sync() - { - TrackPosition = player.CurrentMediaPosition, - ServerTimeTicks = Utils.TimeUtils.GetNetworkTime().DateTime.Ticks - }; - await responseStream.WriteAsync(sync); - Console.WriteLine("Sent Sync"); - await Task.Delay(5000); } + catch (Exception ex) + { + Console.WriteLine("Error sending sync: " + ex.Message); + } + + } }