2020-01-20 21:55:12 +00:00
|
|
|
using System;
|
|
|
|
using System.Threading.Tasks;
|
2020-02-01 01:41:45 +00:00
|
|
|
using System.Collections.Generic;
|
2020-02-02 21:49:01 +00:00
|
|
|
using Aurora.Proto.Party;
|
2020-02-01 01:41:45 +00:00
|
|
|
using Aurora.Models.Media;
|
|
|
|
using Aurora.Proto.General;
|
2020-02-02 15:26:47 +00:00
|
|
|
using Aurora.Services.Library;
|
2020-02-01 01:41:45 +00:00
|
|
|
using Aurora.Services.Player;
|
|
|
|
using Autofac;
|
2020-01-20 21:55:12 +00:00
|
|
|
|
|
|
|
namespace Aurora.Services.Server.Controllers
|
|
|
|
{
|
|
|
|
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
|
|
|
{
|
2020-02-02 15:26:47 +00:00
|
|
|
private SortedList<string, Media> _mediaList;
|
2020-02-01 01:41:45 +00:00
|
|
|
|
2020-01-20 21:55:12 +00:00
|
|
|
public override Task<ListMediaResponse> ListMedia(ListMediaRequest request, Grpc.Core.ServerCallContext context)
|
|
|
|
{
|
2020-02-01 01:41:45 +00:00
|
|
|
ListMediaResponse resp = new ListMediaResponse();
|
|
|
|
|
|
|
|
int startIdx = 0;
|
|
|
|
if (!string.IsNullOrEmpty(request.PageToken))
|
|
|
|
{
|
|
|
|
startIdx = _memberList.IndexOfKey(request.PageToken) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pageSize = request.PageSize;
|
|
|
|
|
|
|
|
if (pageSize > _mediaList.Count)
|
|
|
|
{
|
|
|
|
pageSize = _mediaList.Count;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Gather page
|
2020-02-02 15:26:47 +00:00
|
|
|
List<Media> mediaList = new List<Media>(_mediaList.Values);
|
|
|
|
resp.Media.AddRange(mediaList.GetRange(startIdx, pageSize));
|
2020-02-01 01:41:45 +00:00
|
|
|
|
|
|
|
resp.NextPageToken = resp.Media[resp.Media.Count - 1].Name;
|
|
|
|
return Task.FromResult(resp);
|
2020-01-20 21:55:12 +00:00
|
|
|
}
|
|
|
|
|
2020-02-01 01:41:45 +00:00
|
|
|
public override Task<Media> GetMedia(GetMediaRequest request, Grpc.Core.ServerCallContext context)
|
2020-01-20 21:55:12 +00:00
|
|
|
{
|
2020-02-02 15:26:47 +00:00
|
|
|
_mediaList.TryGetValue(request.Name, out Media baseMedia);
|
2020-02-01 01:41:45 +00:00
|
|
|
|
|
|
|
if (baseMedia == null)
|
|
|
|
{
|
|
|
|
throw new KeyNotFoundException();
|
|
|
|
}
|
|
|
|
|
2020-02-02 15:26:47 +00:00
|
|
|
return Task.FromResult(baseMedia);
|
2020-01-20 21:55:12 +00:00
|
|
|
}
|
|
|
|
|
2020-02-01 01:41:45 +00:00
|
|
|
public override Task<Media> CreateMedia(CreateMediaRequest request, Grpc.Core.ServerCallContext context)
|
2020-01-20 21:55:12 +00:00
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2020-02-01 01:41:45 +00:00
|
|
|
public override Task<Empty> DeleteMedia(DeleteMediaRequest request, Grpc.Core.ServerCallContext context)
|
2020-01-20 21:55:12 +00:00
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
2020-02-01 01:41:45 +00:00
|
|
|
|
|
|
|
public override async Task StreamMedia(StreamMediaRequest request, Grpc.Core.IServerStreamWriter<Proto.General.Chunk> responseStream, Grpc.Core.ServerCallContext context)
|
|
|
|
{
|
2020-02-02 15:26:47 +00:00
|
|
|
using (var scope = App.Container.BeginLifetimeScope())
|
2020-02-01 01:41:45 +00:00
|
|
|
{
|
2020-02-02 15:26:47 +00:00
|
|
|
ILibraryService library = scope.Resolve<ILibraryService>();
|
2020-02-01 01:41:45 +00:00
|
|
|
|
2020-02-02 22:28:34 +00:00
|
|
|
string mediaName = request.Name.Split('/')[1];
|
|
|
|
|
|
|
|
BaseMedia originalSong = library.GetSong(mediaName);
|
2020-02-02 15:26:47 +00:00
|
|
|
if (!(originalSong is LocalAudio))
|
2020-02-01 01:41:45 +00:00
|
|
|
{
|
2020-02-02 15:26:47 +00:00
|
|
|
return;
|
2020-02-01 01:41:45 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 15:26:47 +00:00
|
|
|
//Copy media object to not interfere with other threads
|
|
|
|
LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
//Load only if not already loaded. (Multiple clients may be requesting media)
|
|
|
|
if (!songCopy.IsLoaded)
|
|
|
|
{
|
|
|
|
await songCopy.Load();
|
|
|
|
}
|
|
|
|
|
|
|
|
//Send stream
|
|
|
|
Console.WriteLine("Begin sending file");
|
|
|
|
byte[] buffer = new byte[2048]; // read in chunks of 2KB
|
|
|
|
int bytesRead;
|
|
|
|
while ((bytesRead = songCopy.DataStream.Read(buffer, 0, buffer.Length)) > 0)
|
|
|
|
{
|
|
|
|
Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer);
|
|
|
|
await responseStream.WriteAsync(new Chunk { Content = bufferByteString });
|
|
|
|
}
|
|
|
|
Console.WriteLine("Done sending file");
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
2020-02-01 01:41:45 +00:00
|
|
|
{
|
2020-02-02 15:26:47 +00:00
|
|
|
Console.WriteLine("Exception caught while sending audio file: " + ex.Message);
|
2020-02-01 01:41:45 +00:00
|
|
|
}
|
2020-02-02 15:26:47 +00:00
|
|
|
|
2020-02-01 01:41:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override async Task SyncMedia(SyncMediaRequest request, Grpc.Core.IServerStreamWriter<Sync> responseStream, Grpc.Core.ServerCallContext context)
|
|
|
|
{
|
|
|
|
bool continueSync = true;
|
|
|
|
using (var scope = App.Container.BeginLifetimeScope())
|
|
|
|
{
|
|
|
|
IPlayer player = scope.Resolve<IPlayer>();
|
|
|
|
|
|
|
|
string currentId = player.CurrentMedia.Id;
|
|
|
|
MediaChangedEventHandler mediaChanged = (sender, e) =>
|
|
|
|
{
|
|
|
|
if (e.NewId != currentId)
|
|
|
|
{
|
|
|
|
continueSync = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-01-20 21:55:12 +00:00
|
|
|
}
|
|
|
|
}
|