Code refactoring for cleaner view model design
This commit is contained in:
parent
3398d145ac
commit
85ab39defd
@ -75,9 +75,9 @@ namespace Aurora.Design.Views
|
||||
#endregion Player
|
||||
|
||||
#region Lifecycle
|
||||
public virtual void OnActive() { }
|
||||
public virtual Task OnActive() { return Task.FromResult<object>(null); }
|
||||
|
||||
public virtual void OnInactive() { }
|
||||
public virtual Task OnInactive() { return Task.FromResult<object>(null); }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -8,6 +8,7 @@ using Aurora.Proto.General;
|
||||
using Aurora.Proto.Party;
|
||||
using Aurora.Proto.Events;
|
||||
using Aurora.Services.ClientService;
|
||||
using Aurora.Services.ClientService.Events;
|
||||
using Aurora.Services.PlayerService;
|
||||
using Aurora.Services.EventManager;
|
||||
using Aurora.Models.Media;
|
||||
@ -47,9 +48,6 @@ namespace Aurora.Design.Views.Party
|
||||
PlayCommand = new Command(OnDoubleClickExecute, CanDoubleClickExecute);
|
||||
|
||||
_client = ClientService.Instance;
|
||||
|
||||
//Hook up event handler
|
||||
_client.EventReceived += this.OnEventReceived;
|
||||
}
|
||||
|
||||
~PartyViewModel()
|
||||
@ -151,70 +149,100 @@ namespace Aurora.Design.Views.Party
|
||||
#endregion Properties
|
||||
|
||||
#region Events
|
||||
public override void OnActive()
|
||||
/// <summary>
|
||||
/// Called by framework when view becomes active
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override async Task OnActive()
|
||||
{
|
||||
//TODO
|
||||
//If in party subscribe to events
|
||||
//If in party get events
|
||||
}
|
||||
|
||||
public override void OnInactive()
|
||||
{
|
||||
//TODO
|
||||
//unsubscribe
|
||||
//stop getting events
|
||||
if (this._state == PartyState.Hosting)
|
||||
{
|
||||
await SubscribeToEvents();
|
||||
}
|
||||
_client.OnMediaPaused += this.OnMediaPaused;
|
||||
_client.OnMediaResumed += this.OnMediaResumed;
|
||||
_client.OnNewMediaPlaying += this.OnNewMediaPlaying;
|
||||
_client.OnPartyMemberJoined += this.OnPartyMemberJoined;
|
||||
_client.OnPartyMemberLeft += this.OnPartyMemberLeft;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event handler for the client receiving update events
|
||||
/// Called by framework when view becomes inactive
|
||||
/// </summary>
|
||||
/// <param name="sender">The object that sent the event</param>
|
||||
/// <param name="eventArgs">The event arguments</param>
|
||||
public void OnEventReceived(object sender, EventReceivedEventArgs eventArgs)
|
||||
/// <returns></returns>
|
||||
public override async Task OnInactive()
|
||||
{
|
||||
switch (eventArgs.BaseEvent.DerivedEventCase)
|
||||
_client.StopEvents();
|
||||
await UnsubscribeFromEvents();
|
||||
//Stop event stream and un hook events
|
||||
|
||||
_client.OnMediaPaused -= this.OnMediaPaused;
|
||||
_client.OnMediaResumed -= this.OnMediaResumed;
|
||||
_client.OnNewMediaPlaying -= this.OnNewMediaPlaying;
|
||||
_client.OnPartyMemberJoined -= this.OnPartyMemberJoined;
|
||||
_client.OnPartyMemberLeft -= this.OnPartyMemberLeft;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote media paused event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnMediaPaused(object sender, MediaPausedEventArgs args)
|
||||
{
|
||||
StopPlaying();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote playing new media event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnNewMediaPlaying(object sender, NewMediaPlayingEventArgs args)
|
||||
{
|
||||
PlayFromBeginning(GetMediaFromQueue(args.Event.Media.Id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote resumed playing event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnMediaResumed(object sender, MediaResumedEventArgs args)
|
||||
{
|
||||
PlayResume();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Member joined party event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnPartyMemberJoined(object sender, PartyMemberJoinedEventArgs args)
|
||||
{
|
||||
PartyMember member = new PartyMember
|
||||
{
|
||||
case BaseEvent.DerivedEventOneofCase.None:
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
case BaseEvent.DerivedEventOneofCase.PartyMemberJoinedEvent:
|
||||
{
|
||||
PartyMemberJoinedEvent derivedEvent = eventArgs.BaseEvent.PartyMemberJoinedEvent;
|
||||
PartyMember member = new PartyMember
|
||||
{
|
||||
UserName = derivedEvent.Member.UserName,
|
||||
Id = derivedEvent.Member.Id,
|
||||
IpAddress = derivedEvent.Member.IpAddress,
|
||||
Port = derivedEvent.Member.Port
|
||||
};
|
||||
UserName = args.Event.Member.UserName,
|
||||
Id = args.Event.Member.Id,
|
||||
IpAddress = args.Event.Member.IpAddress,
|
||||
Port = args.Event.Member.Port
|
||||
};
|
||||
|
||||
Members.Add(member);
|
||||
Members.Add(member);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BaseEvent.DerivedEventOneofCase.PartyMemberLeftEvent:
|
||||
{
|
||||
PartyMemberJoinedEvent derivedEvent = eventArgs.BaseEvent.PartyMemberJoinedEvent;
|
||||
var found = Members.Where(x => x.Id == derivedEvent.Member.Id);
|
||||
foreach (PartyMember member in found)
|
||||
{
|
||||
_members.Remove(member);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BaseEvent.DerivedEventOneofCase.MediaPlayingEvent:
|
||||
{
|
||||
MediaPlayingEvent derivedEvent = eventArgs.BaseEvent.MediaPlayingEvent;
|
||||
Play(derivedEvent);
|
||||
break;
|
||||
}
|
||||
case BaseEvent.DerivedEventOneofCase.MediaPausedEvent:
|
||||
{
|
||||
MediaPausedEvent derivedEvent = eventArgs.BaseEvent.MediaPausedEvent;
|
||||
StopPlaying();
|
||||
break;
|
||||
}
|
||||
/// <summary>
|
||||
/// Member left party event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnPartyMemberLeft(object sender, PartyMemberLeftEventArgs args)
|
||||
{
|
||||
var found = Members.Where(x => x.Id == args.Event.Member.Id);
|
||||
foreach (PartyMember member in found)
|
||||
{
|
||||
_members.Remove(member);
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,17 +302,32 @@ namespace Aurora.Design.Views.Party
|
||||
|
||||
public override void OnPlayButtonExecute()
|
||||
{
|
||||
_player.Play();
|
||||
switch (_player.PlaybackState)
|
||||
{
|
||||
case PlaybackState.Buffering:
|
||||
{
|
||||
_player.Play();
|
||||
//Fire play resume event
|
||||
AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata;
|
||||
MediaResumedEvent mediaResumed = new MediaResumedEvent();
|
||||
|
||||
EventManager.Instance.FireEvent(new BaseEvent()
|
||||
{
|
||||
MediaResumedEvent = mediaResumed
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case PlaybackState.Playing:
|
||||
{
|
||||
_player.Pause();
|
||||
//Fire play stopped event
|
||||
AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata;
|
||||
MediaPausedEvent mediaPaused = new MediaPausedEvent();
|
||||
|
||||
EventManager.Instance.FireEvent(new BaseEvent()
|
||||
{
|
||||
MediaPausedEvent = mediaPaused
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -310,8 +353,9 @@ namespace Aurora.Design.Views.Party
|
||||
/// </summary>
|
||||
public void OnDoubleClickExecute()
|
||||
{
|
||||
//Fire Playing event
|
||||
AudioMetadata meta = _selectedMedia.Metadata as AudioMetadata;
|
||||
MediaPlayingEvent mediaPlaying = new MediaPlayingEvent()
|
||||
NewMediaPlayingEvent mediaPlaying = new NewMediaPlayingEvent()
|
||||
{
|
||||
Media = new RemoteMediaData()
|
||||
{
|
||||
@ -324,7 +368,7 @@ namespace Aurora.Design.Views.Party
|
||||
|
||||
EventManager.Instance.FireEvent(new BaseEvent()
|
||||
{
|
||||
MediaPlayingEvent = mediaPlaying
|
||||
NewMediaPlayingEvent = mediaPlaying
|
||||
});
|
||||
}
|
||||
|
||||
@ -355,19 +399,7 @@ namespace Aurora.Design.Views.Party
|
||||
RefreshMembers();
|
||||
|
||||
//Subscribe to events
|
||||
SubscribeRequest req = new SubscribeRequest();
|
||||
req.EventTypes.Add(EventType.PartyMemberJoined);
|
||||
req.EventTypes.Add(EventType.PartyMemberLeft);
|
||||
req.EventTypes.Add(EventType.MediaPlaying);
|
||||
req.EventTypes.Add(EventType.MediaStopped);
|
||||
if (!string.IsNullOrWhiteSpace(SettingsService.Instance.ClientId))
|
||||
{
|
||||
req.ClientId = SettingsService.Instance.ClientId;
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine(string.Format("CLIENT {0} - SubscribeToEvents called from client with id", SettingsService.Instance.ClientId));
|
||||
_client.RemoteEventClient.SubscribeToEvents(req);
|
||||
await SubscribeToEvents();
|
||||
|
||||
QueueResponse queueResponse = _client.RemotePartyClient.GetQueue(new Empty());
|
||||
|
||||
@ -403,19 +435,41 @@ namespace Aurora.Design.Views.Party
|
||||
_client.StopEvents();
|
||||
|
||||
//Unsubscribe
|
||||
UnsubscribeAllRequest unsubscribeReq = new UnsubscribeAllRequest();
|
||||
await _client.RemoteEventClient.UnsubscribeFromAllAsync(unsubscribeReq);
|
||||
await UnsubscribeFromEvents();
|
||||
|
||||
//Leave party
|
||||
LeavePartyRequest leaveReq = new LeavePartyRequest();
|
||||
await _client.RemotePartyClient.LeavePartyAsync(leaveReq);
|
||||
}
|
||||
|
||||
private async Task SubscribeToEvents()
|
||||
{
|
||||
SubscribeRequest req = new SubscribeRequest();
|
||||
req.EventTypes.Add(EventType.PartyMemberJoined);
|
||||
req.EventTypes.Add(EventType.PartyMemberLeft);
|
||||
req.EventTypes.Add(EventType.MediaPlaying);
|
||||
req.EventTypes.Add(EventType.MediaStopped);
|
||||
if (!string.IsNullOrWhiteSpace(SettingsService.Instance.ClientId))
|
||||
{
|
||||
req.ClientId = SettingsService.Instance.ClientId;
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine(string.Format("CLIENT {0} - SubscribeToEvents called from client with id", SettingsService.Instance.ClientId));
|
||||
await _client.RemoteEventClient.SubscribeToEventsAsync(req);
|
||||
}
|
||||
private async Task UnsubscribeFromEvents()
|
||||
{
|
||||
UnsubscribeAllRequest unsubscribeReq = new UnsubscribeAllRequest();
|
||||
await _client.RemoteEventClient.UnsubscribeFromAllAsync(unsubscribeReq);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh members list.
|
||||
/// </summary>
|
||||
private void RefreshMembers()
|
||||
{
|
||||
Members.Clear();
|
||||
MembersResponse response = _client.RemotePartyClient.GetPartyMembers(new Empty());
|
||||
//Add members
|
||||
foreach (PartyMember member in response.Members)
|
||||
@ -431,17 +485,28 @@ namespace Aurora.Design.Views.Party
|
||||
OnPropertyChanged("IsNotSelectingHost");
|
||||
}
|
||||
|
||||
private async void Play(MediaPlayingEvent args)
|
||||
private BaseMedia GetMediaFromQueue(string Id)
|
||||
{
|
||||
//TODO this design assumes all played music is in a queue
|
||||
//TODO this is a slow design depending on size of queue
|
||||
if (_queue.Any((BaseMedia media) => media.Id == args.Media.Id))
|
||||
if (_queue.Any((BaseMedia media) => media.Id == Id))
|
||||
{
|
||||
BaseMedia media = _queue.First((BaseMedia med) => med.Id == args.Media.Id);
|
||||
base.Media = media;
|
||||
await _player.LoadMedia(base.Media).ConfigureAwait(true);
|
||||
_player.Play();
|
||||
BaseMedia media = _queue.First((BaseMedia med) => med.Id == Id);
|
||||
return media;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private async void PlayFromBeginning(BaseMedia args)
|
||||
{
|
||||
base.Media = args;
|
||||
await _player.LoadMedia(base.Media).ConfigureAwait(true);
|
||||
_player.Play();
|
||||
}
|
||||
|
||||
private void PlayResume()
|
||||
{
|
||||
_player.Play();
|
||||
}
|
||||
|
||||
private void StopPlaying()
|
||||
|
@ -93,7 +93,6 @@ namespace Aurora.Design.Views.Songs
|
||||
await _player.LoadMedia(base.Media).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
_player.Play();
|
||||
switch (_player.PlaybackState)
|
||||
{
|
||||
case PlaybackState.Buffering:
|
||||
@ -106,6 +105,11 @@ namespace Aurora.Design.Views.Songs
|
||||
_player.Pause();
|
||||
break;
|
||||
}
|
||||
case PlaybackState.Stopped:
|
||||
{
|
||||
_player.Play();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,15 +50,20 @@ message BaseEvent {
|
||||
oneof derivedEvent {
|
||||
PartyMemberJoinedEvent partyMemberJoinedEvent = 3;
|
||||
PartyMemberLeftEvent partyMemberLeftEvent = 4;
|
||||
MediaPlayingEvent mediaPlayingEvent = 5;
|
||||
NewMediaPlayingEvent newMediaPlayingEvent = 5;
|
||||
MediaPausedEvent mediaPausedEvent = 6;
|
||||
MediaResumedEvent mediaResumedEvent = 7;
|
||||
}
|
||||
}
|
||||
|
||||
message MediaPlayingEvent {
|
||||
message NewMediaPlayingEvent {
|
||||
Aurora.Proto.Party.RemoteMediaData media = 1;
|
||||
}
|
||||
|
||||
message MediaResumedEvent {
|
||||
Aurora.Proto.General.Empty empty = 1;
|
||||
}
|
||||
|
||||
message MediaPausedEvent {
|
||||
Aurora.Proto.General.Empty empty = 1;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace Aurora.RemoteImpl
|
||||
Action<BaseEvent> callback = (BaseEvent bEvent) =>
|
||||
{
|
||||
Console.WriteLine(string.Format("SERVER - Event fired for peer: {0}", peerId));
|
||||
//TODO need to remove callback if stream no longer exists IE. Client crashed or stopped
|
||||
responseStream.WriteAsync(bEvent);
|
||||
|
||||
};
|
||||
|
@ -6,9 +6,12 @@ using Aurora.Proto.Events;
|
||||
using Aurora.Proto.Party;
|
||||
using Aurora.Proto.Playback;
|
||||
using Aurora.Proto.Sync;
|
||||
using Aurora.Services.ClientService.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Aurora.Services.ClientService
|
||||
{
|
||||
|
||||
public class ClientService : BaseService<ClientService>
|
||||
{
|
||||
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
|
||||
@ -23,7 +26,11 @@ namespace Aurora.Services.ClientService
|
||||
{
|
||||
}
|
||||
|
||||
public EventReceivedEventHandler EventReceived;
|
||||
public MediaPausedEventHandler OnMediaPaused;
|
||||
public NewMediaPlayingEventHandler OnNewMediaPlaying;
|
||||
public PartyMemberJoinedEventHandler OnPartyMemberJoined;
|
||||
public PartyMemberLeftEventHandler OnPartyMemberLeft;
|
||||
public MediaResumedEventHandler OnMediaResumed;
|
||||
|
||||
public RemotePartyService.RemotePartyServiceClient RemotePartyClient
|
||||
{
|
||||
@ -99,16 +106,36 @@ namespace Aurora.Services.ClientService
|
||||
while (!_eventCancellationTokenSource.Token.IsCancellationRequested &&
|
||||
await eventStream.ResponseStream.MoveNext(_eventCancellationTokenSource.Token))
|
||||
{
|
||||
BaseEvent e = new BaseEvent(eventStream.ResponseStream.Current);
|
||||
if (this.EventReceived != null)
|
||||
try
|
||||
{
|
||||
this.EventReceived.Invoke(this, new EventReceivedEventArgs(e));
|
||||
BaseEvent e = new BaseEvent(eventStream.ResponseStream.Current);
|
||||
|
||||
Dictionary<BaseEvent.DerivedEventOneofCase, EventInfo> events = new Dictionary<BaseEvent.DerivedEventOneofCase, EventInfo>()
|
||||
{
|
||||
{BaseEvent.DerivedEventOneofCase.MediaPausedEvent, new EventInfo(this.OnMediaPaused, typeof(MediaPausedEventArgs))},
|
||||
{BaseEvent.DerivedEventOneofCase.MediaResumedEvent, new EventInfo(this.OnMediaResumed, typeof(MediaResumedEventArgs))},
|
||||
{BaseEvent.DerivedEventOneofCase.NewMediaPlayingEvent, new EventInfo(this.OnNewMediaPlaying, typeof(NewMediaPlayingEventArgs))},
|
||||
{BaseEvent.DerivedEventOneofCase.PartyMemberJoinedEvent, new EventInfo(this.OnPartyMemberJoined, typeof(PartyMemberJoinedEventArgs))},
|
||||
{BaseEvent.DerivedEventOneofCase.PartyMemberLeftEvent, new EventInfo(this.OnPartyMemberLeft, typeof(PartyMemberLeftEventArgs))}
|
||||
};
|
||||
|
||||
events.TryGetValue(e.DerivedEventCase, out EventInfo eventInfo);
|
||||
|
||||
if (eventInfo != null && eventInfo.Handler != null)
|
||||
{
|
||||
eventInfo.Handler.DynamicInvoke(new object[] { this, Activator.CreateInstance(eventInfo.ArgsType, new object[] { e }) });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception while parsing event ---" + ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format("EXCEPTION --- " + ex.Message));
|
||||
Console.WriteLine(string.Format("EXCEPTION while parsing events --- " + ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
Aurora/Services/ClientService/EventInfo.cs
Normal file
25
Aurora/Services/ClientService/EventInfo.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Grpc.Core;
|
||||
using Aurora.Proto.Events;
|
||||
using Aurora.Proto.Party;
|
||||
using Aurora.Proto.Playback;
|
||||
using Aurora.Proto.Sync;
|
||||
using Aurora.Services.ClientService.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Aurora.Services.ClientService
|
||||
{
|
||||
public class EventInfo
|
||||
{
|
||||
public EventInfo(Delegate handler, Type argsType)
|
||||
{
|
||||
this.Handler = handler;
|
||||
ArgsType = argsType;
|
||||
}
|
||||
|
||||
public Delegate Handler { get; private set; }
|
||||
public Type ArgsType { get; private set; }
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using Aurora.Proto.Events;
|
||||
|
||||
namespace Aurora.Services.ClientService
|
||||
{
|
||||
public delegate void EventReceivedEventHandler(object sender, EventReceivedEventArgs e);
|
||||
|
||||
public class EventReceivedEventArgs
|
||||
{
|
||||
public BaseEvent BaseEvent { get; private set; }
|
||||
public EventReceivedEventArgs(BaseEvent e)
|
||||
{
|
||||
BaseEvent = e;
|
||||
}
|
||||
}
|
||||
}
|
16
Aurora/Services/ClientService/Events/MediaPausedEvent.cs
Normal file
16
Aurora/Services/ClientService/Events/MediaPausedEvent.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Aurora.Proto.Events;
|
||||
|
||||
namespace Aurora.Services.ClientService.Events
|
||||
{
|
||||
public delegate void MediaPausedEventHandler(object sender, MediaPausedEventArgs e);
|
||||
|
||||
public class MediaPausedEventArgs
|
||||
{
|
||||
public MediaPausedEvent Event { get; private set; }
|
||||
public MediaPausedEventArgs(BaseEvent e)
|
||||
{
|
||||
Event = e.MediaPausedEvent;
|
||||
}
|
||||
}
|
||||
}
|
16
Aurora/Services/ClientService/Events/MediaResumedEvent.cs
Normal file
16
Aurora/Services/ClientService/Events/MediaResumedEvent.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Aurora.Proto.Events;
|
||||
|
||||
namespace Aurora.Services.ClientService
|
||||
{
|
||||
public delegate void MediaResumedEventHandler(object sender, MediaResumedEventArgs e);
|
||||
|
||||
public class MediaResumedEventArgs
|
||||
{
|
||||
public MediaResumedEvent Event { get; private set; }
|
||||
public MediaResumedEventArgs(BaseEvent e)
|
||||
{
|
||||
Event = e.MediaResumedEvent;
|
||||
}
|
||||
}
|
||||
}
|
16
Aurora/Services/ClientService/Events/NewMediaPlayingEvent.cs
Normal file
16
Aurora/Services/ClientService/Events/NewMediaPlayingEvent.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Aurora.Proto.Events;
|
||||
|
||||
namespace Aurora.Services.ClientService.Events
|
||||
{
|
||||
public delegate void NewMediaPlayingEventHandler(object sender, NewMediaPlayingEventArgs e);
|
||||
|
||||
public class NewMediaPlayingEventArgs
|
||||
{
|
||||
public NewMediaPlayingEvent Event { get; private set; }
|
||||
public NewMediaPlayingEventArgs(BaseEvent e)
|
||||
{
|
||||
Event = e.NewMediaPlayingEvent;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Aurora.Proto.Events;
|
||||
|
||||
namespace Aurora.Services.ClientService.Events
|
||||
{
|
||||
public delegate void PartyMemberJoinedEventHandler(object sender, PartyMemberJoinedEventArgs e);
|
||||
|
||||
public class PartyMemberJoinedEventArgs
|
||||
{
|
||||
public PartyMemberJoinedEvent Event { get; private set; }
|
||||
public PartyMemberJoinedEventArgs(BaseEvent e)
|
||||
{
|
||||
Event = e.PartyMemberJoinedEvent;
|
||||
}
|
||||
}
|
||||
}
|
16
Aurora/Services/ClientService/Events/PartyMemberLeftEvent.cs
Normal file
16
Aurora/Services/ClientService/Events/PartyMemberLeftEvent.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Aurora.Proto.Events;
|
||||
|
||||
namespace Aurora.Services.ClientService.Events
|
||||
{
|
||||
public delegate void PartyMemberLeftEventHandler(object sender, PartyMemberLeftEventArgs e);
|
||||
|
||||
public class PartyMemberLeftEventArgs
|
||||
{
|
||||
public PartyMemberLeftEvent Event { get; private set; }
|
||||
public PartyMemberLeftEventArgs(BaseEvent e)
|
||||
{
|
||||
Event = e.PartyMemberLeftEvent;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Google.Protobuf.Reflection;
|
||||
using Aurora.Proto.Events;
|
||||
using Aurora.Models;
|
||||
|
||||
namespace Aurora.Services.EventManager
|
||||
{
|
||||
@ -183,8 +176,6 @@ namespace Aurora.Services.EventManager
|
||||
{
|
||||
foreach (KeyValuePair<string, List<EventType>> pair in _subscriptionList)
|
||||
{
|
||||
Console.WriteLine("SERVER - Invoking action for client: " + pair.Key);
|
||||
|
||||
Task.Delay(1000);
|
||||
//If action list contains an action for id, invoke
|
||||
if (actionsCopy.ContainsKey(pair.Key))
|
||||
|
@ -4,6 +4,8 @@ using System.Threading;
|
||||
using Grpc.Core;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Proto.Sync;
|
||||
using Aurora.Proto.Events;
|
||||
using Aurora.Proto.Party;
|
||||
using LibVLCSharp.Shared;
|
||||
|
||||
namespace Aurora.Services.PlayerService
|
||||
@ -110,14 +112,14 @@ namespace Aurora.Services.PlayerService
|
||||
RemoteAudio media = _currentMedia as RemoteAudio;
|
||||
if (!media.FromHost)
|
||||
{
|
||||
RemoteSyncService.RemoteSyncServiceClient _remoteSyncClient = media.RemoteSyncClient;
|
||||
RemoteSyncService.RemoteSyncServiceClient remoteSyncClient = media.RemoteSyncClient;
|
||||
|
||||
//Sync playback in a separate task
|
||||
//Task completes when host stops syncing (when a song is complete)
|
||||
Task syncTask = new Task(async () =>
|
||||
{
|
||||
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
|
||||
using (AsyncServerStreamingCall<Sync> syncStream = _remoteSyncClient
|
||||
using (AsyncServerStreamingCall<Sync> syncStream = remoteSyncClient
|
||||
.GetMediaSync(new Proto.General.Empty()))
|
||||
{
|
||||
try
|
||||
@ -154,6 +156,7 @@ namespace Aurora.Services.PlayerService
|
||||
});
|
||||
|
||||
syncTask.Start();
|
||||
// Task syncTask = Task.Run(() => Sync(remoteSyncClient));
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,6 +166,50 @@ namespace Aurora.Services.PlayerService
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Async method to synchronize music playback with host
|
||||
/// </summary>
|
||||
/// <param name="remoteSyncClient"></param>
|
||||
/// <returns></returns>
|
||||
private async Task Sync(RemoteSyncService.RemoteSyncServiceClient remoteSyncClient)
|
||||
{
|
||||
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
|
||||
using (AsyncServerStreamingCall<Sync> syncStream = remoteSyncClient
|
||||
.GetMediaSync(new Proto.General.Empty()))
|
||||
{
|
||||
try
|
||||
{
|
||||
while (await syncStream.ResponseStream.MoveNext(cancellationTokenSource.Token))
|
||||
{
|
||||
Sync sync = new Sync(syncStream.ResponseStream.Current);
|
||||
if (sync != null)
|
||||
{
|
||||
//Adjust position based on sync
|
||||
DateTime localTime = Utils.TimeUtils.GetNetworkTime();
|
||||
//Get offset converted to milliseconds
|
||||
float offset = ((localTime.Ticks - sync.ServerTime) * 100) / (1000 * 1000);
|
||||
|
||||
float length = CurrentMediaLength;
|
||||
float newPosition = (sync.TrackTime + offset) / length;
|
||||
|
||||
//Adjust position if greater than 10 percent difference
|
||||
float oldPosition = _mediaPlayer.Position;
|
||||
if (newPosition - oldPosition > 0.001 ||
|
||||
newPosition - oldPosition < -0.001)
|
||||
{
|
||||
_mediaPlayer.Position = newPosition;
|
||||
Console.WriteLine("Audio synced");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception caught while attempting to sync: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause currently loaded media.
|
||||
/// </summary>
|
||||
@ -191,7 +238,6 @@ namespace Aurora.Services.PlayerService
|
||||
{
|
||||
PlaybackStateChanged.Invoke(this, new PlaybackStateChangedEventArgs(oldState, _state));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Enqueue(BaseMedia song)
|
||||
|
Reference in New Issue
Block a user