More progress on IoC. Controllers are implemented
This commit is contained in:
@ -12,6 +12,7 @@ using LibVLCSharp.Shared;
|
||||
using Xamarin.Forms;
|
||||
using Aurora.Services.Player;
|
||||
using Aurora.Services.Settings;
|
||||
using Aurora.Services.Library;
|
||||
|
||||
namespace Aurora
|
||||
{
|
||||
@ -29,6 +30,7 @@ namespace Aurora
|
||||
_builder.RegisterType<PlayerService>().As<IPlayer>().SingleInstance();
|
||||
_builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance();
|
||||
_builder.RegisterType<ClientService>().As<IClientService>().SingleInstance();
|
||||
_builder.RegisterType<LibraryService>().As<ILibraryService>().SingleInstance();
|
||||
_builder.RegisterType<MainView>().SingleInstance();
|
||||
_builder.RegisterType<AlbumsViewModel>();
|
||||
_builder.RegisterType<ArtistsViewModel>();
|
||||
|
@ -22,6 +22,14 @@
|
||||
<Entry
|
||||
Text="{Binding Port}"/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
Orientation="Horizontal">
|
||||
<Label
|
||||
VerticalOptions="Center"
|
||||
Text="Path to Library"/>
|
||||
<Entry
|
||||
Text="{Binding LibraryPath}"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ContentView.Content>
|
||||
</ContentView>
|
@ -32,5 +32,15 @@ namespace Aurora.Design.Views.Profile
|
||||
OnPropertyChanged("Port");
|
||||
}
|
||||
}
|
||||
|
||||
public string LibraryPath
|
||||
{
|
||||
get { return this._settingsService.LibraryLocation; }
|
||||
set
|
||||
{
|
||||
this._settingsService.LibraryLocation = value;
|
||||
OnPropertyChanged("LibraryPath");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Services;
|
||||
using Aurora.Services.Library;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Design.Views.Songs
|
||||
@ -10,15 +10,18 @@ namespace Aurora.Design.Views.Songs
|
||||
#region Fields
|
||||
private ObservableCollection<BaseMedia> _songsList;
|
||||
private BaseMedia _selectedSong;
|
||||
private ILibraryService _libraryService;
|
||||
|
||||
#endregion Fields
|
||||
|
||||
#region Constructor
|
||||
public SongsViewModel()
|
||||
public SongsViewModel(ILibraryService libraryService)
|
||||
{
|
||||
_songsList = new ObservableCollection<BaseMedia>();
|
||||
DoubleClickCommand = new Command(OnDoubleClickExecute, OnDoubleClickCanExecute);
|
||||
|
||||
this._libraryService = libraryService;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
@ -45,7 +48,7 @@ namespace Aurora.Design.Views.Songs
|
||||
public void Initialize()
|
||||
{
|
||||
|
||||
SongsList = LibraryService.Instance.GetLibrary();
|
||||
SongsList = this._libraryService.GetLibrary();
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
|
@ -10,6 +10,7 @@ namespace Aurora.Models.Media
|
||||
|
||||
public BaseMedia()
|
||||
{
|
||||
//TODO need to make sure this is unique
|
||||
Id = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
|
@ -239,8 +239,6 @@ message MemberDeletedEvent {
|
||||
}
|
||||
|
||||
message EventSubscription {
|
||||
//Resource name of the event
|
||||
string name = 1;
|
||||
EventType type = 2;
|
||||
}
|
||||
|
||||
@ -253,7 +251,6 @@ message ListEventSubscriptionsRequest {
|
||||
|
||||
message ListEventSubscriptionsResponse {
|
||||
repeated EventSubscription subscriptions = 1;
|
||||
string nextPageToken = 3;
|
||||
}
|
||||
|
||||
message CreateEventSubscriptionRequest {
|
||||
@ -264,7 +261,8 @@ message CreateEventSubscriptionRequest {
|
||||
|
||||
message DeleteEventSubscriptionRequest {
|
||||
//Resource name of the subscription to delete
|
||||
string name = 1;
|
||||
string parent = 1;
|
||||
EventType type = 2;
|
||||
}
|
||||
|
||||
message DeleteAllEventSubscriptionsRequest {
|
||||
|
@ -6,8 +6,9 @@ using Aurora.Utils;
|
||||
using Aurora.Proto.Party;
|
||||
using Aurora.Proto.Events;
|
||||
using Aurora.Services.EventManager;
|
||||
using Aurora.Services;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Services.Library;
|
||||
using Autofac;
|
||||
|
||||
namespace Aurora.RemoteImpl
|
||||
{
|
||||
@ -90,49 +91,56 @@ namespace Aurora.RemoteImpl
|
||||
|
||||
public override Task<QueueResponse> GetQueue(Proto.General.Empty empty, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
QueueResponse mediaList = new QueueResponse();
|
||||
|
||||
//This will change as queuing operation gets solidified
|
||||
//Simply return the hosts library
|
||||
|
||||
ObservableCollection<BaseMedia> queue = LibraryService.Instance.GetLibrary();
|
||||
|
||||
QueueResponse mediaList = new QueueResponse();
|
||||
foreach (BaseMedia media in queue)
|
||||
using (var scope = App.Container.BeginLifetimeScope())
|
||||
{
|
||||
AudioMetadata metadata = new AudioMetadata();
|
||||
try
|
||||
ILibraryService library = scope.Resolve<ILibraryService>();
|
||||
|
||||
ObservableCollection<BaseMedia> queue = library.GetLibrary();
|
||||
|
||||
|
||||
foreach (BaseMedia media in queue)
|
||||
{
|
||||
if (media.Metadata is AudioMetadata)
|
||||
AudioMetadata metadata = new AudioMetadata();
|
||||
try
|
||||
{
|
||||
metadata = media.Metadata as AudioMetadata;
|
||||
if (media.Metadata is AudioMetadata)
|
||||
{
|
||||
metadata = media.Metadata as AudioMetadata;
|
||||
|
||||
RemoteMediaData data = new RemoteMediaData();
|
||||
data.Id = media.Id;
|
||||
if (metadata.Title != null)
|
||||
{
|
||||
data.Title = metadata.Title;
|
||||
}
|
||||
if (metadata.Artist != null)
|
||||
{
|
||||
data.Artist = metadata.Artist;
|
||||
}
|
||||
if (metadata.Album != null)
|
||||
{
|
||||
data.Album = metadata.Album;
|
||||
}
|
||||
if (metadata.Duration != null)
|
||||
{
|
||||
data.Duration = metadata.Duration;
|
||||
}
|
||||
RemoteMediaData data = new RemoteMediaData();
|
||||
data.Id = media.Id;
|
||||
if (metadata.Title != null)
|
||||
{
|
||||
data.Title = metadata.Title;
|
||||
}
|
||||
if (metadata.Artist != null)
|
||||
{
|
||||
data.Artist = metadata.Artist;
|
||||
}
|
||||
if (metadata.Album != null)
|
||||
{
|
||||
data.Album = metadata.Album;
|
||||
}
|
||||
if (metadata.Duration != null)
|
||||
{
|
||||
data.Duration = metadata.Duration;
|
||||
}
|
||||
|
||||
mediaList.MediaList.Add(data);
|
||||
mediaList.MediaList.Add(data);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Task.FromResult(mediaList);
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using Aurora.Services;
|
||||
using Aurora.Proto.Playback;
|
||||
using Aurora.Proto.General;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Services.Library;
|
||||
using Autofac;
|
||||
|
||||
namespace Aurora.RemoteImpl
|
||||
{
|
||||
@ -15,38 +14,44 @@ namespace Aurora.RemoteImpl
|
||||
Grpc.Core.IServerStreamWriter<Chunk> responseStream,
|
||||
Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
BaseMedia originalSong = LibraryService.Instance.GetSong(request.Id);
|
||||
if (!(originalSong is LocalAudio))
|
||||
using (var scope = App.Container.BeginLifetimeScope())
|
||||
{
|
||||
return;
|
||||
}
|
||||
ILibraryService library = scope.Resolve<ILibraryService>();
|
||||
|
||||
//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)
|
||||
BaseMedia originalSong = library.GetSong(request.Id);
|
||||
if (!(originalSong is LocalAudio))
|
||||
{
|
||||
await songCopy.Load();
|
||||
return;
|
||||
}
|
||||
|
||||
//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)
|
||||
//Copy media object to not interfere with other threads
|
||||
LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong);
|
||||
|
||||
try
|
||||
{
|
||||
Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer);
|
||||
await responseStream.WriteAsync(new Chunk { Content = bufferByteString });
|
||||
//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);
|
||||
}
|
||||
Console.WriteLine("Done sending file");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception caught while sending audio file: " + ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
12
Aurora/Services/Library/ILibraryService.cs
Normal file
12
Aurora/Services/Library/ILibraryService.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Aurora.Models.Media;
|
||||
|
||||
namespace Aurora.Services.Library
|
||||
{
|
||||
public interface ILibraryService
|
||||
{
|
||||
ObservableCollection<BaseMedia> GetLibrary();
|
||||
|
||||
BaseMedia GetSong(string Id);
|
||||
}
|
||||
}
|
@ -3,22 +3,24 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Services.Settings;
|
||||
using Aurora.Utils;
|
||||
|
||||
namespace Aurora.Services
|
||||
namespace Aurora.Services.Library
|
||||
{
|
||||
public class LibraryService : BaseService<LibraryService>
|
||||
public class LibraryService : ILibraryService
|
||||
{
|
||||
#region Fields
|
||||
private string _pathName = "/Users/brandonwatson/Music/iTunes/iTunes Media/Music";
|
||||
private string _pathName;
|
||||
private string _extensions = ".wav,.mp3,.aiff,.flac,.m4a,.m4b,.wma";
|
||||
private Dictionary<string, BaseMedia> _library;
|
||||
|
||||
#endregion Fields
|
||||
|
||||
public LibraryService()
|
||||
public LibraryService(ISettingsService settingsService)
|
||||
{
|
||||
_library = new Dictionary<string, BaseMedia>();
|
||||
this._pathName = settingsService.LibraryLocation;
|
||||
LoadLibrary();
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ using LibVLCSharp.Shared;
|
||||
namespace Aurora.Services.Player
|
||||
{
|
||||
|
||||
public class PlayerService : BaseService<PlayerService>, IPlayer
|
||||
public class PlayerService : IPlayer
|
||||
{
|
||||
private const long _ticksPerMillisecond = 10000;
|
||||
private BaseMedia _currentMedia;
|
||||
|
@ -1,22 +1,29 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Generic;
|
||||
using Aurora.Proto.PartyV2;
|
||||
using Aurora.Services.Library;
|
||||
using Aurora.Models.Media;
|
||||
using Autofac;
|
||||
|
||||
namespace Aurora.Services.Server.Controllers
|
||||
{
|
||||
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
||||
{
|
||||
private ILibraryService _libraryService;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for partial class
|
||||
/// </summary>
|
||||
public RemotePartyController(string partyName, string description)
|
||||
public RemotePartyController(string partyName, string description, ILibraryService libraryService)
|
||||
{
|
||||
this._startDateTime = DateTime.UtcNow;
|
||||
this._displayName = partyName;
|
||||
this._description = description;
|
||||
this._memberList = new SortedList<string, Member>();
|
||||
this._mediaList = new SortedList<string, Models.Media.BaseMedia>();
|
||||
this._mediaList = new SortedList<string, Media>();
|
||||
|
||||
_libraryService = libraryService;
|
||||
|
||||
string userName = "testUser";
|
||||
|
||||
@ -32,7 +39,47 @@ namespace Aurora.Services.Server.Controllers
|
||||
this._memberList.Add(_hostMember.Name, _hostMember);
|
||||
|
||||
//Add media from library
|
||||
//This will change as queuing operation gets solidified
|
||||
//Simply return the hosts library
|
||||
ObservableCollection<BaseMedia> queue = _libraryService.GetLibrary();
|
||||
|
||||
|
||||
foreach (BaseMedia media in queue)
|
||||
{
|
||||
AudioMetadata metadata = new AudioMetadata();
|
||||
try
|
||||
{
|
||||
if (media.Metadata is AudioMetadata)
|
||||
{
|
||||
metadata = media.Metadata as AudioMetadata;
|
||||
|
||||
Media data = new Media();
|
||||
data.Name = media.Id;
|
||||
if (metadata.Title != null)
|
||||
{
|
||||
data.Title = metadata.Title;
|
||||
}
|
||||
if (metadata.Artist != null)
|
||||
{
|
||||
data.Artist = metadata.Artist;
|
||||
}
|
||||
if (metadata.Album != null)
|
||||
{
|
||||
data.Album = metadata.Album;
|
||||
}
|
||||
if (metadata.Duration != null)
|
||||
{
|
||||
data.Duration = metadata.Duration;
|
||||
}
|
||||
|
||||
_mediaList.Add(data.Name, data);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(string.Format("Error preparing queue: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Aurora.Proto.PartyV2;
|
||||
using Aurora.Utils;
|
||||
|
||||
namespace Aurora.Services.Server.Controllers
|
||||
{
|
||||
@ -8,7 +10,26 @@ namespace Aurora.Services.Server.Controllers
|
||||
{
|
||||
public override Task GetEvents(GetEventsRequest request, Grpc.Core.IServerStreamWriter<BaseEvent> responseStream, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
string peerId = Misc.Combine(new string[] { context.Peer, request.Parent });
|
||||
Console.WriteLine(string.Format("SERVER - Events request received from peer: {0}", peerId));
|
||||
|
||||
AutoResetEvent are = new AutoResetEvent(false);
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
Action cancelled = () =>
|
||||
{
|
||||
are.Set();
|
||||
};
|
||||
|
||||
this._eventManager.AddEventHandler(callback, cancelled, Misc.Combine(new string[] { context.Peer, request.Parent }));
|
||||
are.WaitOne();
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Threading.Tasks;
|
||||
using Aurora.Proto.PartyV2;
|
||||
using Aurora.Proto.General;
|
||||
using Aurora.Utils;
|
||||
|
||||
namespace Aurora.Services.Server.Controllers
|
||||
{
|
||||
@ -14,17 +15,24 @@ namespace Aurora.Services.Server.Controllers
|
||||
|
||||
public override Task<EventSubscription> CreateEventSubscription(CreateEventSubscriptionRequest request, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
Console.WriteLine(string.Format("SERVER - Subscription from client with id: {0}", request.Parent));
|
||||
this._eventManager.AddSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.EventSubscription.Type);
|
||||
|
||||
return Task.FromResult(request.EventSubscription);
|
||||
}
|
||||
|
||||
public override Task<Empty> DeleteEventSubscription(DeleteEventSubscriptionRequest request, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
this._eventManager.RemoveSubscription(Misc.Combine(new string[] { context.Peer, request.Parent }), request.Type);
|
||||
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
|
||||
public override Task<Empty> DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest request, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
this._eventManager.RemoveAllSubscriptions(Misc.Combine(new string[] { context.Peer, request.Parent }));
|
||||
|
||||
return Task.FromResult(new Empty());
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using Aurora.Proto.PartyV2;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Proto.General;
|
||||
using Aurora.Services.Library;
|
||||
using Aurora.Services.Player;
|
||||
using Autofac;
|
||||
|
||||
@ -11,7 +12,7 @@ namespace Aurora.Services.Server.Controllers
|
||||
{
|
||||
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
||||
{
|
||||
private SortedList<string, BaseMedia> _mediaList;
|
||||
private SortedList<string, Media> _mediaList;
|
||||
|
||||
public override Task<ListMediaResponse> ListMedia(ListMediaRequest request, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
@ -31,22 +32,8 @@ namespace Aurora.Services.Server.Controllers
|
||||
}
|
||||
|
||||
//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
|
||||
});
|
||||
}
|
||||
}
|
||||
List<Media> mediaList = new List<Media>(_mediaList.Values);
|
||||
resp.Media.AddRange(mediaList.GetRange(startIdx, pageSize));
|
||||
|
||||
resp.NextPageToken = resp.Media[resp.Media.Count - 1].Name;
|
||||
return Task.FromResult(resp);
|
||||
@ -54,24 +41,14 @@ namespace Aurora.Services.Server.Controllers
|
||||
|
||||
public override Task<Media> GetMedia(GetMediaRequest request, Grpc.Core.ServerCallContext context)
|
||||
{
|
||||
_mediaList.TryGetValue(request.Name, out BaseMedia baseMedia);
|
||||
_mediaList.TryGetValue(request.Name, out Media 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);
|
||||
return Task.FromResult(baseMedia);
|
||||
}
|
||||
|
||||
public override Task<Media> CreateMedia(CreateMediaRequest request, Grpc.Core.ServerCallContext context)
|
||||
@ -86,37 +63,43 @@ namespace Aurora.Services.Server.Controllers
|
||||
|
||||
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))
|
||||
using (var scope = App.Container.BeginLifetimeScope())
|
||||
{
|
||||
return;
|
||||
}
|
||||
ILibraryService library = scope.Resolve<ILibraryService>();
|
||||
|
||||
//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)
|
||||
BaseMedia originalSong = library.GetSong(request.Name);
|
||||
if (!(originalSong is LocalAudio))
|
||||
{
|
||||
await songCopy.Load();
|
||||
return;
|
||||
}
|
||||
|
||||
//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)
|
||||
//Copy media object to not interfere with other threads
|
||||
LocalAudio songCopy = new LocalAudio((LocalAudio)originalSong);
|
||||
|
||||
try
|
||||
{
|
||||
Google.Protobuf.ByteString bufferByteString = Google.Protobuf.ByteString.CopyFrom(buffer);
|
||||
await responseStream.WriteAsync(new Chunk { Content = bufferByteString });
|
||||
//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");
|
||||
}
|
||||
Console.WriteLine("Done sending file");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception caught while sending audio file: " + ex.Message);
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception caught while sending audio file: " + ex.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
27
Aurora/Services/Server/Server/IServerService.cs
Normal file
27
Aurora/Services/Server/Server/IServerService.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Aurora.Services.Server
|
||||
{
|
||||
public interface IServerService
|
||||
{
|
||||
int Port { get; }
|
||||
|
||||
string Hostname { get; }
|
||||
|
||||
bool Initialized { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start Server
|
||||
/// </summary>
|
||||
void Start(string partyName, string description);
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown server async.
|
||||
/// </summary>
|
||||
/// <returns>Task</returns>
|
||||
Task Stop();
|
||||
|
||||
Task Reset();
|
||||
}
|
||||
}
|
@ -4,16 +4,18 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Grpc.Core;
|
||||
using Aurora.Services.Server.Controllers;
|
||||
using Aurora.Services.Library;
|
||||
using Aurora.Proto.PartyV2;
|
||||
|
||||
|
||||
namespace Aurora.Services.Server
|
||||
{
|
||||
public class ServerService : BaseService<ServerService>
|
||||
public class ServerService : IServerService
|
||||
{
|
||||
private int _port = 8080;
|
||||
private string _hostname;
|
||||
private Grpc.Core.Server _server;
|
||||
private ILibraryService _libraryService;
|
||||
|
||||
//Implementation class declarations
|
||||
private RemotePartyController _remotePartyController;
|
||||
@ -21,10 +23,10 @@ namespace Aurora.Services.Server
|
||||
/// <summary>
|
||||
/// Constructor. Registers GRPC service implementations.
|
||||
/// </summary>
|
||||
public ServerService()
|
||||
public ServerService(ILibraryService libraryService)
|
||||
{
|
||||
string host = GetLocalIPAddress();
|
||||
|
||||
this._libraryService = libraryService;
|
||||
if (string.IsNullOrWhiteSpace(host))
|
||||
{
|
||||
throw new Exception("This device must have a valid IP address");
|
||||
@ -69,7 +71,7 @@ namespace Aurora.Services.Server
|
||||
};
|
||||
|
||||
//Construct implementations
|
||||
_remotePartyController = new RemotePartyController(partyName, description);
|
||||
_remotePartyController = new RemotePartyController(partyName, description, _libraryService);
|
||||
|
||||
// Register grpc RemoteService with singleton server service
|
||||
RegisterService(RemotePartyService.BindService(_remotePartyController));
|
@ -23,5 +23,7 @@ namespace Aurora.Services.Settings
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
string ClientId { get; set; }
|
||||
|
||||
string LibraryLocation { get; set; }
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@ namespace Aurora.Services.Settings
|
||||
private string _usernameKey = "username";
|
||||
private string _defaultPortKey = "port";
|
||||
|
||||
private string _libraryLocationKey = "libraryLocation";
|
||||
|
||||
public SettingsService()
|
||||
{
|
||||
}
|
||||
@ -55,6 +57,12 @@ namespace Aurora.Services.Settings
|
||||
set { AppSettings.AddOrUpdateValue(_defaultPortKey, value); }
|
||||
}
|
||||
|
||||
public string LibraryLocation
|
||||
{
|
||||
get { return AppSettings.GetValueOrDefault(_libraryLocationKey, "~/Music"); }
|
||||
set { AppSettings.AddOrUpdateValue(_libraryLocationKey, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current sessions clientId. This is assigned by the server. This is not persisted.
|
||||
/// </summary>
|
||||
|
Reference in New Issue
Block a user