Pretty good audio sync if I do say so myself :)
This commit is contained in:
parent
8bea1d03da
commit
41e853b1c6
@ -10,7 +10,7 @@ namespace Aurora.Design.Components.MemberList
|
|||||||
public partial class MemberList : ContentView
|
public partial class MemberList : ContentView
|
||||||
{
|
{
|
||||||
private static ObservableCollection<PartyMember> _newSource;
|
private static ObservableCollection<PartyMember> _newSource;
|
||||||
private static NotifyCollectionChangedEventHandler _collectionChangedHandler;
|
// private static NotifyCollectionChangedEventHandler _collectionChangedHandler;
|
||||||
public MemberList()
|
public MemberList()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -172,9 +172,10 @@ namespace Aurora.Design.Views.Party
|
|||||||
/// Called by framework when view becomes inactive
|
/// Called by framework when view becomes inactive
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override async Task OnInactive()
|
public override Task OnInactive()
|
||||||
{
|
{
|
||||||
_client.StopEvents();
|
_client.StopEvents();
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -10,6 +10,6 @@ service RemoteSyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message Sync {
|
message Sync {
|
||||||
int64 serverTime = 1;
|
int64 serverTimeTicks = 1;
|
||||||
float trackTime = 2;
|
float trackPosition= 2;
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ namespace Aurora.RemoteImpl
|
|||||||
/// <param name="responseStream">The response stream</param>
|
/// <param name="responseStream">The response stream</param>
|
||||||
/// <param name="context">gRPC client context</param>
|
/// <param name="context">gRPC client context</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async override Task GetEvents(EventsRequest request,
|
public override Task GetEvents(EventsRequest request,
|
||||||
Grpc.Core.IServerStreamWriter<BaseEvent> responseStream,
|
Grpc.Core.IServerStreamWriter<BaseEvent> responseStream,
|
||||||
Grpc.Core.ServerCallContext context)
|
Grpc.Core.ServerCallContext context)
|
||||||
{
|
{
|
||||||
@ -41,6 +41,7 @@ namespace Aurora.RemoteImpl
|
|||||||
|
|
||||||
EventManager.Instance.AddEventHandler(callback, Combine(new string[] { context.Peer, request.ClientId }));
|
EventManager.Instance.AddEventHandler(callback, Combine(new string[] { context.Peer, request.ClientId }));
|
||||||
are.WaitOne();
|
are.WaitOne();
|
||||||
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -33,13 +33,12 @@ namespace Aurora.RemoteImpl
|
|||||||
|
|
||||||
while (continueSync)
|
while (continueSync)
|
||||||
{
|
{
|
||||||
Utils.Time networkTime = Utils.TimeUtils.GetNetworkTime();
|
|
||||||
float length = PlayerService.Instance.CurrentMediaLength;
|
float length = PlayerService.Instance.CurrentMediaLength;
|
||||||
|
|
||||||
Sync sync = new Sync()
|
Sync sync = new Sync()
|
||||||
{
|
{
|
||||||
TrackTime = length * PlayerService.Instance.CurrentMediaPosition,
|
TrackPosition = PlayerService.Instance.CurrentMediaPosition,
|
||||||
ServerTime = networkTime.DateTime.Ticks + networkTime.Elapsed.Ticks
|
ServerTimeTicks = Utils.TimeUtils.GetNetworkTime().DateTime.Ticks
|
||||||
};
|
};
|
||||||
await responseStream.WriteAsync(sync);
|
await responseStream.WriteAsync(sync);
|
||||||
Console.WriteLine("Sent Sync");
|
Console.WriteLine("Sent Sync");
|
||||||
|
@ -10,8 +10,10 @@ using LibVLCSharp.Shared;
|
|||||||
|
|
||||||
namespace Aurora.Services.PlayerService
|
namespace Aurora.Services.PlayerService
|
||||||
{
|
{
|
||||||
|
|
||||||
public class PlayerService : BaseService<PlayerService>
|
public class PlayerService : BaseService<PlayerService>
|
||||||
{
|
{
|
||||||
|
private const long _ticksPerMillisecond = 10000;
|
||||||
private BaseMedia _currentMedia;
|
private BaseMedia _currentMedia;
|
||||||
private MediaPlayer _mediaPlayer;
|
private MediaPlayer _mediaPlayer;
|
||||||
private LibVLC _libvlc;
|
private LibVLC _libvlc;
|
||||||
@ -134,10 +136,10 @@ namespace Aurora.Services.PlayerService
|
|||||||
DateTime localTime = time.DateTime;
|
DateTime localTime = time.DateTime;
|
||||||
|
|
||||||
//Get offset - elapsed time converted to milliseconds
|
//Get offset - elapsed time converted to milliseconds
|
||||||
float offset = (((localTime.Ticks - sync.ServerTime) * 100) / (1000 * 1000));
|
|
||||||
|
|
||||||
float length = CurrentMediaLength;
|
float length = CurrentMediaLength;
|
||||||
float newPosition = (sync.TrackTime + (offset + time.Elapsed.Milliseconds)) / length;
|
float offset = (localTime.Ticks - sync.ServerTimeTicks) * _ticksPerMillisecond;
|
||||||
|
|
||||||
|
float newPosition = (sync.TrackPosition + offset);
|
||||||
|
|
||||||
//Adjust position if greater than 10 percent difference
|
//Adjust position if greater than 10 percent difference
|
||||||
float oldPosition = _mediaPlayer.Position;
|
float oldPosition = _mediaPlayer.Position;
|
||||||
@ -145,7 +147,15 @@ namespace Aurora.Services.PlayerService
|
|||||||
newPosition - oldPosition < -0.001)
|
newPosition - oldPosition < -0.001)
|
||||||
{
|
{
|
||||||
_mediaPlayer.Position = newPosition;
|
_mediaPlayer.Position = newPosition;
|
||||||
Console.WriteLine(string.Format("Audio synced: oldPosition: {0} newPosition: {1}", oldPosition, newPosition));
|
Console.WriteLine(string.Format("**Audio synced**"));
|
||||||
|
Console.WriteLine(string.Format("Remote Server Time {0}", new DateTime(sync.ServerTimeTicks).ToLongTimeString()));
|
||||||
|
Console.WriteLine(string.Format("Remote Track Time: {0}", sync.TrackPosition));
|
||||||
|
Console.WriteLine(string.Format("Local Server Time: {0}", time.DateTime.ToLongTimeString()));
|
||||||
|
Console.WriteLine(string.Format("Local Track Time: {0}", _mediaPlayer.Position));
|
||||||
|
Console.WriteLine(string.Format("Offset: {0}", offset));
|
||||||
|
Console.WriteLine(string.Format("Old Position: {0}", oldPosition));
|
||||||
|
Console.WriteLine(string.Format("New Position: {0}", newPosition));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,7 +168,6 @@ namespace Aurora.Services.PlayerService
|
|||||||
});
|
});
|
||||||
|
|
||||||
syncTask.Start();
|
syncTask.Start();
|
||||||
// Task syncTask = Task.Run(() => Sync(remoteSyncClient));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,13 +45,14 @@ namespace Aurora.Utils
|
|||||||
socket.ReceiveTimeout = 3000;
|
socket.ReceiveTimeout = 3000;
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
socket.Send(ntpData);
|
socket.Send(ntpData);
|
||||||
|
stopwatch.Stop();
|
||||||
socket.Receive(ntpData);
|
socket.Receive(ntpData);
|
||||||
socket.Close();
|
socket.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Offset to get to the "Transmit Timestamp" field (time at which the reply
|
//Offset to get to the "Transmit Timestamp" field (time at which the reply
|
||||||
//departed the server for the client, in 64-bit timestamp format."
|
//departed the server for the client, in 64-bit timestamp format."
|
||||||
const byte serverReplyTime = 40;
|
byte serverReplyTime = 40;
|
||||||
|
|
||||||
//Get the seconds part
|
//Get the seconds part
|
||||||
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
|
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
|
||||||
|
Loading…
Reference in New Issue
Block a user