158 lines
5.6 KiB
C#
158 lines
5.6 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Generic;
|
|
using Aurora.Proto.PartyV2;
|
|
using Aurora.Models.Media;
|
|
using Aurora.Proto.General;
|
|
using Aurora.Services.Player;
|
|
using Autofac;
|
|
|
|
namespace Aurora.Services.Server.Controllers
|
|
{
|
|
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
|
{
|
|
private SortedList<string, BaseMedia> _mediaList;
|
|
|
|
public override Task<ListMediaResponse> ListMedia(ListMediaRequest request, Grpc.Core.ServerCallContext context)
|
|
{
|
|
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
|
|
List<BaseMedia> baseMedia = new List<BaseMedia>(_mediaList.Values);
|
|
foreach (BaseMedia media in baseMedia)
|
|
{
|
|
if (media.Metadata is AudioMetadata)
|
|
{
|
|
AudioMetadata meta = media.Metadata as AudioMetadata;
|
|
resp.Media.Add(new Media()
|
|
{
|
|
Name = media.Id,
|
|
Title = meta.Title,
|
|
Album = meta.Album,
|
|
Artist = meta.Artist,
|
|
Duration = meta.Duration
|
|
});
|
|
}
|
|
}
|
|
|
|
resp.NextPageToken = resp.Media[resp.Media.Count - 1].Name;
|
|
return Task.FromResult(resp);
|
|
}
|
|
|
|
public override Task<Media> GetMedia(GetMediaRequest request, Grpc.Core.ServerCallContext context)
|
|
{
|
|
_mediaList.TryGetValue(request.Name, out BaseMedia baseMedia);
|
|
|
|
if (baseMedia == null)
|
|
{
|
|
throw new KeyNotFoundException();
|
|
}
|
|
|
|
Media media = new Media();
|
|
if (baseMedia.Metadata != null && baseMedia.Metadata is AudioMetadata)
|
|
{
|
|
AudioMetadata metadata = baseMedia.Metadata as AudioMetadata;
|
|
media.Name = baseMedia.Id;
|
|
media.Title = metadata.Title;
|
|
media.Artist = metadata.Artist;
|
|
media.Album = metadata.Album;
|
|
}
|
|
|
|
return Task.FromResult(media);
|
|
}
|
|
|
|
public override Task<Media> CreateMedia(CreateMediaRequest request, Grpc.Core.ServerCallContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override Task<Empty> DeleteMedia(DeleteMediaRequest request, Grpc.Core.ServerCallContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override async Task StreamMedia(StreamMediaRequest request, Grpc.Core.IServerStreamWriter<Proto.General.Chunk> responseStream, Grpc.Core.ServerCallContext context)
|
|
{
|
|
BaseMedia originalSong = LibraryService.Instance.GetSong(request.Name);
|
|
if (!(originalSong is LocalAudio))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//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)
|
|
{
|
|
Console.WriteLine("Exception caught while sending audio file: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
} |