Adding dependency injection
This commit is contained in:
parent
f8ad2f459e
commit
48d0ffa77d
@ -150,7 +150,7 @@
|
|||||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
|
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces">
|
<Reference Include="Microsoft.Bcl.AsyncInterfaces">
|
||||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Linq.Async">
|
<Reference Include="System.Linq.Async">
|
||||||
<HintPath>..\packages\System.Linq.Async.4.0.0\lib\net461\System.Linq.Async.dll</HintPath>
|
<HintPath>..\packages\System.Linq.Async.4.0.0\lib\net461\System.Linq.Async.dll</HintPath>
|
||||||
@ -164,6 +164,10 @@
|
|||||||
<Reference Include="CarouselView.FormsPlugin.Abstractions">
|
<Reference Include="CarouselView.FormsPlugin.Abstractions">
|
||||||
<HintPath>..\packages\CarouselView.FormsPlugin.5.2.0\lib\netstandard2.0\CarouselView.FormsPlugin.Abstractions.dll</HintPath>
|
<HintPath>..\packages\CarouselView.FormsPlugin.5.2.0\lib\netstandard2.0\CarouselView.FormsPlugin.Abstractions.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Autofac">
|
||||||
|
<HintPath>..\packages\Autofac.5.0.0\lib\net461\Autofac.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.ComponentModel.Composition" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="gtk-gui\gui.stetic">
|
<EmbeddedResource Include="gtk-gui\gui.stetic">
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="Autofac" version="5.0.0" targetFramework="net47" />
|
||||||
<package id="CarouselView.FormsPlugin" version="5.2.0" targetFramework="net47" />
|
<package id="CarouselView.FormsPlugin" version="5.2.0" targetFramework="net47" />
|
||||||
<package id="DLToolkit.Forms.Controls.FlowListView" version="2.0.11" targetFramework="net47" />
|
<package id="DLToolkit.Forms.Controls.FlowListView" version="2.0.11" targetFramework="net47" />
|
||||||
<package id="Google.Protobuf" version="3.10.1" targetFramework="net47" />
|
<package id="Google.Protobuf" version="3.10.1" targetFramework="net47" />
|
||||||
@ -13,7 +14,7 @@
|
|||||||
<package id="LibVLCSharp.GTK" version="3.3.1" targetFramework="net47" />
|
<package id="LibVLCSharp.GTK" version="3.3.1" targetFramework="net47" />
|
||||||
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net47" />
|
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net47" />
|
||||||
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net47" />
|
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net47" />
|
||||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="1.0.0" targetFramework="net47" />
|
<package id="Microsoft.Bcl.AsyncInterfaces" version="1.1.0" targetFramework="net47" />
|
||||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net47" />
|
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net47" />
|
||||||
<package id="OpenTK" version="3.1.0" targetFramework="net47" />
|
<package id="OpenTK" version="3.1.0" targetFramework="net47" />
|
||||||
<package id="OpenTK.GLControl" version="3.0.1" targetFramework="net47" />
|
<package id="OpenTK.GLControl" version="3.0.1" targetFramework="net47" />
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Grpc" Version="2.26.0" />
|
<PackageReference Include="Grpc" Version="2.26.0" />
|
||||||
|
<PackageReference Include="Autofac" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Protobuf Remove="..\Aurora\Proto\general.proto" />
|
<Protobuf Remove="..\Aurora\Proto\general.proto" />
|
||||||
|
29
Aurora.test/ControllerTests/MediaControllerTest.cs
Normal file
29
Aurora.test/ControllerTests/MediaControllerTest.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using Aurora.Proto.PartyV2;
|
||||||
|
using Aurora.Services.Server;
|
||||||
|
using Grpc.Core;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Aurora.test.ControllerTests
|
||||||
|
{
|
||||||
|
public class MediaControllerTests
|
||||||
|
{
|
||||||
|
private RemotePartyService.RemotePartyServiceClient _remotePartyService;
|
||||||
|
private Channel _channel;
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
ServerService.Instance.Start("testParty", "asdf");
|
||||||
|
_channel = new Channel(string.Format("{0}:{1}", ServerService.GetLocalIPAddress(), 8080), ChannelCredentials.Insecure);
|
||||||
|
_remotePartyService = new RemotePartyService.RemotePartyServiceClient(_channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public async Task TearDown()
|
||||||
|
{
|
||||||
|
await ServerService.Instance.Stop();
|
||||||
|
await _channel.ShutdownAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -139,5 +139,50 @@ namespace Aurora.test.ControllerTests
|
|||||||
Assert.AreEqual(resp.Members.Count, 5);
|
Assert.AreEqual(resp.Members.Count, 5);
|
||||||
Assert.False(resp.Members.Any(member => member.UserName == "Ke$sha"));
|
Assert.False(resp.Members.Any(member => member.UserName == "Ke$sha"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static object[] PagingCases =
|
||||||
|
{
|
||||||
|
new object[] {"Tupac", "Aubrey Grahm", "Beyonce Knowls", "Ke$ha", "A$ap Ferg", "asdf", "sdfa", "dfas", "fasd"},
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[TestCaseSource("PagingCases")]
|
||||||
|
public void MemberPagingTest(object[] members)
|
||||||
|
{
|
||||||
|
foreach (string name in members)
|
||||||
|
{
|
||||||
|
Member member = _remotePartyService.CreateMember(new CreateMemberRequest()
|
||||||
|
{
|
||||||
|
Parent = "party1",
|
||||||
|
Member = new Member()
|
||||||
|
{
|
||||||
|
UserName = name
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.NotNull(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
//List members
|
||||||
|
ListMembersResponse resp = _remotePartyService.ListMembers(new ListMembersRequest()
|
||||||
|
{
|
||||||
|
Parent = "party1",
|
||||||
|
PageSize = 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
string nextPageToken = resp.NextPageToken;
|
||||||
|
|
||||||
|
Assert.AreEqual(resp.Members.Count, 2);
|
||||||
|
|
||||||
|
//List members
|
||||||
|
resp = _remotePartyService.ListMembers(new ListMembersRequest()
|
||||||
|
{
|
||||||
|
Parent = "party1",
|
||||||
|
PageSize = 2,
|
||||||
|
PageToken = nextPageToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.AreEqual(resp.Members.Count, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,19 +1,51 @@
|
|||||||
using System;
|
using System;
|
||||||
using Aurora.Design.Views.Main;
|
using Aurora.Design.Views.Main;
|
||||||
|
using Aurora.Design.Views.Albums;
|
||||||
|
using Aurora.Design.Views.Artists;
|
||||||
|
using Aurora.Design.Views.Party;
|
||||||
|
using Aurora.Design.Views.Profile;
|
||||||
|
using Aurora.Design.Views.Songs;
|
||||||
|
using Aurora.Design.Views.Stations;
|
||||||
|
using Aurora.Services.ClientService;
|
||||||
|
using Autofac;
|
||||||
using LibVLCSharp.Shared;
|
using LibVLCSharp.Shared;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Xaml;
|
using Aurora.Services.Player;
|
||||||
|
using Aurora.Services.Settings;
|
||||||
|
|
||||||
namespace Aurora
|
namespace Aurora
|
||||||
{
|
{
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
private static IContainer _container;
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Core.Initialize();
|
Core.Initialize();
|
||||||
|
|
||||||
MainPage = new MainView();
|
//Register DI
|
||||||
|
ContainerBuilder _builder = new ContainerBuilder();
|
||||||
|
// _builder.RegisterInstance<IPlayer>(new PlayerService()).SingleInstance();
|
||||||
|
_builder.RegisterType<PlayerService>().As<IPlayer>().SingleInstance();
|
||||||
|
_builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance();
|
||||||
|
_builder.RegisterType<ClientService>().As<IClientService>().SingleInstance();
|
||||||
|
_builder.RegisterType<MainView>().SingleInstance();
|
||||||
|
_builder.RegisterType<AlbumsViewModel>();
|
||||||
|
_builder.RegisterType<ArtistsViewModel>();
|
||||||
|
_builder.RegisterType<PartyViewModel>();
|
||||||
|
_builder.RegisterType<ProfileViewModel>();
|
||||||
|
_builder.RegisterType<SongsViewModel>();
|
||||||
|
_builder.RegisterType<StationsViewModel>();
|
||||||
|
|
||||||
|
// _builder.RegisterInstance<ISettingsService>(new SettingsService()).SingleInstance();
|
||||||
|
_container = _builder.Build();
|
||||||
|
|
||||||
|
MainPage = _container.Resolve<MainView>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IContainer Container
|
||||||
|
{
|
||||||
|
get { return _container; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStart()
|
protected override void OnStart()
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<PackageReference Include="Sharpnado.Forms.HorizontalListView" Version="1.3.0" />
|
<PackageReference Include="Sharpnado.Forms.HorizontalListView" Version="1.3.0" />
|
||||||
<PackageReference Include="DLToolkit.Forms.Controls.FlowListView" Version="2.0.11" />
|
<PackageReference Include="DLToolkit.Forms.Controls.FlowListView" Version="2.0.11" />
|
||||||
<PackageReference Include="CarouselView.FormsPlugin" Version="5.2.0" />
|
<PackageReference Include="CarouselView.FormsPlugin" Version="5.2.0" />
|
||||||
|
<PackageReference Include="Autofac" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Design\" />
|
<Folder Include="Design\" />
|
||||||
|
@ -9,8 +9,8 @@ using Xamarin.Forms;
|
|||||||
using Xamarin.Forms.Xaml;
|
using Xamarin.Forms.Xaml;
|
||||||
using Aurora.Models.Media;
|
using Aurora.Models.Media;
|
||||||
using Aurora.Design.Components.MediaPlayer;
|
using Aurora.Design.Components.MediaPlayer;
|
||||||
using Aurora.Services.PlayerService;
|
using Aurora.Services.Player;
|
||||||
using System.Threading;
|
using Autofac;
|
||||||
|
|
||||||
namespace Aurora.Design.Views.Main
|
namespace Aurora.Design.Views.Main
|
||||||
{
|
{
|
||||||
@ -38,10 +38,10 @@ namespace Aurora.Design.Views.Main
|
|||||||
private Dictionary<int, BaseViewModel> _viewModels;
|
private Dictionary<int, BaseViewModel> _viewModels;
|
||||||
private BaseViewModel _lastViewModel;
|
private BaseViewModel _lastViewModel;
|
||||||
private Player _playerComponent;
|
private Player _playerComponent;
|
||||||
private PlayerService _playerService;
|
private IPlayer _playerService;
|
||||||
private ContentPresenter _viewContent;
|
private ContentPresenter _viewContent;
|
||||||
|
|
||||||
public MainView()
|
public MainView(IPlayer player)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
BindingContext = new MainViewModel();
|
BindingContext = new MainViewModel();
|
||||||
@ -50,7 +50,7 @@ namespace Aurora.Design.Views.Main
|
|||||||
_playerComponent = Player;
|
_playerComponent = Player;
|
||||||
|
|
||||||
_viewContent = (ContentPresenter)Content.FindByName("ViewContent");
|
_viewContent = (ContentPresenter)Content.FindByName("ViewContent");
|
||||||
_playerService = PlayerService.Instance;
|
_playerService = player;
|
||||||
|
|
||||||
MasterPage.ListView.ItemSelected += OnNavItemSelected;
|
MasterPage.ListView.ItemSelected += OnNavItemSelected;
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ namespace Aurora.Design.Views.Main
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Instantiate new view model
|
//Instantiate new view model
|
||||||
vm = (BaseViewModel)Activator.CreateInstance(item.TargetViewModelType);
|
vm = (BaseViewModel)App.Container.Resolve(item.TargetViewModelType); //Activator.CreateInstance(item.TargetViewModelType);
|
||||||
_viewModels.Add(item.Id, vm);
|
_viewModels.Add(item.Id, vm);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ namespace Aurora.Design.Views.Main
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Instantiate new view model
|
//Instantiate new view model
|
||||||
vm = (BaseViewModel)Activator.CreateInstance(firstNavItem.TargetViewModelType);
|
vm = (BaseViewModel)App.Container.Resolve(firstNavItem.TargetViewModelType); //(BaseViewModel)Activator.CreateInstance(firstNavItem.TargetViewModelType);
|
||||||
_viewModels.Add(firstNavItem.Id, vm);
|
_viewModels.Add(firstNavItem.Id, vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,11 @@ using Aurora.Proto.Party;
|
|||||||
using Aurora.Proto.Events;
|
using Aurora.Proto.Events;
|
||||||
using Aurora.Services.ClientService;
|
using Aurora.Services.ClientService;
|
||||||
using Aurora.Services.ClientService.Events;
|
using Aurora.Services.ClientService.Events;
|
||||||
using Aurora.Services.PlayerService;
|
using Aurora.Services.Player;
|
||||||
using Aurora.Services.EventManager;
|
using Aurora.Services.EventManager;
|
||||||
using Aurora.Models.Media;
|
using Aurora.Models.Media;
|
||||||
using Aurora.Design.Views.Party.NewPartyDialog;
|
using Aurora.Design.Views.Party.NewPartyDialog;
|
||||||
|
using Aurora.Services.Settings;
|
||||||
|
|
||||||
namespace Aurora.Design.Views.Party
|
namespace Aurora.Design.Views.Party
|
||||||
{
|
{
|
||||||
@ -32,22 +33,25 @@ namespace Aurora.Design.Views.Party
|
|||||||
private ObservableCollection<PartyMember> _members;
|
private ObservableCollection<PartyMember> _members;
|
||||||
private ObservableCollection<BaseMedia> _queue;
|
private ObservableCollection<BaseMedia> _queue;
|
||||||
private BaseMedia _selectedMedia;
|
private BaseMedia _selectedMedia;
|
||||||
private ClientService _client;
|
private IClientService _client;
|
||||||
|
private ISettingsService _settingsService;
|
||||||
|
|
||||||
private int _selectedTabIndex;
|
private int _selectedTabIndex;
|
||||||
|
|
||||||
public PartyViewModel()
|
public PartyViewModel(ISettingsService settingsService, IClientService clientService)
|
||||||
{
|
{
|
||||||
_members = new ObservableCollection<PartyMember>();
|
_members = new ObservableCollection<PartyMember>();
|
||||||
_queue = new ObservableCollection<BaseMedia>();
|
_queue = new ObservableCollection<BaseMedia>();
|
||||||
|
|
||||||
|
this._settingsService = settingsService;
|
||||||
|
|
||||||
SetState(PartyState.SelectingHost);
|
SetState(PartyState.SelectingHost);
|
||||||
|
|
||||||
PlayCommand = new Command(OnDoubleClickCommandExecute, CanDoubleClickCommandExecute);
|
PlayCommand = new Command(OnDoubleClickCommandExecute, CanDoubleClickCommandExecute);
|
||||||
|
|
||||||
LeavePartyCommand = new Command(OnLeavePartyCommandExecute, CanLeavePartyCommandExecute);
|
LeavePartyCommand = new Command(OnLeavePartyCommandExecute, CanLeavePartyCommandExecute);
|
||||||
|
|
||||||
_client = ClientService.Instance;
|
_client = clientService;
|
||||||
|
|
||||||
_client.OnMediaPaused += this.OnRemoteMediaPaused;
|
_client.OnMediaPaused += this.OnRemoteMediaPaused;
|
||||||
_client.OnMediaResumed += this.OnRemoteMediaResumed;
|
_client.OnMediaResumed += this.OnRemoteMediaResumed;
|
||||||
@ -245,7 +249,7 @@ namespace Aurora.Design.Views.Party
|
|||||||
private async void OnJoinCommandExecute()
|
private async void OnJoinCommandExecute()
|
||||||
{
|
{
|
||||||
SetState(PartyState.Connecting);
|
SetState(PartyState.Connecting);
|
||||||
_client.Start(_hostname, SettingsService.Instance.DefaultPort.ToString());
|
_client.Start(_hostname, this._settingsService.DefaultPort.ToString());
|
||||||
await JoinParty(false);
|
await JoinParty(false);
|
||||||
|
|
||||||
//TODO add cancellation token
|
//TODO add cancellation token
|
||||||
@ -272,7 +276,7 @@ namespace Aurora.Design.Views.Party
|
|||||||
ServerService.Instance.Start();
|
ServerService.Instance.Start();
|
||||||
string localHost = ServerService.GetLocalIPAddress();
|
string localHost = ServerService.GetLocalIPAddress();
|
||||||
_client.IsHost = true;
|
_client.IsHost = true;
|
||||||
_client.Start(localHost, SettingsService.Instance.DefaultPort.ToString());
|
_client.Start(localHost, this._settingsService.DefaultPort.ToString());
|
||||||
await JoinParty(true);
|
await JoinParty(true);
|
||||||
|
|
||||||
|
|
||||||
@ -387,10 +391,10 @@ namespace Aurora.Design.Views.Party
|
|||||||
{
|
{
|
||||||
JoinPartyResponse resp = await _client.RemotePartyClient.JoinPartyAsync(new JoinPartyRequest
|
JoinPartyResponse resp = await _client.RemotePartyClient.JoinPartyAsync(new JoinPartyRequest
|
||||||
{
|
{
|
||||||
UserName = SettingsService.Instance.Username,
|
UserName = this._settingsService.Username,
|
||||||
});
|
});
|
||||||
|
|
||||||
SettingsService.Instance.ClientId = resp.ClientId;
|
this._settingsService.ClientId = resp.ClientId;
|
||||||
|
|
||||||
RefreshMembers();
|
RefreshMembers();
|
||||||
|
|
||||||
@ -447,13 +451,13 @@ namespace Aurora.Design.Views.Party
|
|||||||
req.EventTypes.Add(EventType.PartyMemberLeft);
|
req.EventTypes.Add(EventType.PartyMemberLeft);
|
||||||
req.EventTypes.Add(EventType.MediaPlaying);
|
req.EventTypes.Add(EventType.MediaPlaying);
|
||||||
req.EventTypes.Add(EventType.MediaStopped);
|
req.EventTypes.Add(EventType.MediaStopped);
|
||||||
if (!string.IsNullOrWhiteSpace(SettingsService.Instance.ClientId))
|
if (!string.IsNullOrWhiteSpace(this._settingsService.ClientId))
|
||||||
{
|
{
|
||||||
req.ClientId = SettingsService.Instance.ClientId;
|
req.ClientId = this._settingsService.ClientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine(string.Format("CLIENT {0} - SubscribeToEvents called from client with id", SettingsService.Instance.ClientId));
|
Console.WriteLine(string.Format("CLIENT {0} - SubscribeToEvents called from client with id", this._settingsService.ClientId));
|
||||||
await _client.RemoteEventClient.SubscribeToEventsAsync(req);
|
await _client.RemoteEventClient.SubscribeToEventsAsync(req);
|
||||||
}
|
}
|
||||||
private async Task UnsubscribeFromEvents()
|
private async Task UnsubscribeFromEvents()
|
||||||
|
@ -1,32 +1,34 @@
|
|||||||
using System;
|
using System;
|
||||||
using Aurora.Services;
|
using Aurora.Services.Settings;
|
||||||
|
|
||||||
namespace Aurora.Design.Views.Profile
|
namespace Aurora.Design.Views.Profile
|
||||||
{
|
{
|
||||||
public class ProfileViewModel : BaseViewModel
|
public class ProfileViewModel : BaseViewModel
|
||||||
{
|
{
|
||||||
|
private ISettingsService _settingsService;
|
||||||
|
|
||||||
public ProfileViewModel()
|
public ProfileViewModel(ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
|
this._settingsService = settingsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Username
|
public string Username
|
||||||
{
|
{
|
||||||
get { return SettingsService.Instance.Username; }
|
get { return this._settingsService.Username; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
SettingsService.Instance.Username = value;
|
this._settingsService.Username = value;
|
||||||
OnPropertyChanged("Username");
|
OnPropertyChanged("Username");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Port
|
public string Port
|
||||||
{
|
{
|
||||||
get { return SettingsService.Instance.DefaultPort.ToString(); }
|
get { return this._settingsService.DefaultPort.ToString(); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Int32.TryParse(value, out int portNum);
|
Int32.TryParse(value, out int portNum);
|
||||||
SettingsService.Instance.DefaultPort = portNum;
|
this._settingsService.DefaultPort = portNum;
|
||||||
OnPropertyChanged("Port");
|
OnPropertyChanged("Port");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,13 @@ service RemotePartyService {
|
|||||||
rpc ListMedia(ListMediaRequest) returns (ListMediaResponse);
|
rpc ListMedia(ListMediaRequest) returns (ListMediaResponse);
|
||||||
|
|
||||||
//Get
|
//Get
|
||||||
rpc GetMedia(GetMediaRequest) returns (RemoteMedia);
|
rpc GetMedia(GetMediaRequest) returns (Media);
|
||||||
|
|
||||||
|
//Create
|
||||||
|
rpc CreateMedia(CreateMediaRequest) returns (Media);
|
||||||
|
|
||||||
|
//Delete
|
||||||
|
rpc DeleteMedia(DeleteMediaRequest) returns (Aurora.Proto.General.Empty) {};
|
||||||
|
|
||||||
//CUSTOM: Stream
|
//CUSTOM: Stream
|
||||||
rpc StreamMedia(StreamMediaRequest) returns (stream Aurora.Proto.General.Chunk) {};
|
rpc StreamMedia(StreamMediaRequest) returns (stream Aurora.Proto.General.Chunk) {};
|
||||||
@ -97,7 +103,10 @@ message Member {
|
|||||||
//Resource name of the party member to be returned (Added by server)
|
//Resource name of the party member to be returned (Added by server)
|
||||||
string name = 1;
|
string name = 1;
|
||||||
string userName = 2;
|
string userName = 2;
|
||||||
|
|
||||||
|
//Added by server
|
||||||
string ipAddress = 3;
|
string ipAddress = 3;
|
||||||
|
|
||||||
//Added by server
|
//Added by server
|
||||||
google.protobuf.Timestamp addedOn = 4;
|
google.protobuf.Timestamp addedOn = 4;
|
||||||
}
|
}
|
||||||
@ -134,7 +143,7 @@ message DeleteMemberRequest {
|
|||||||
string name = 1;
|
string name = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RemoteMedia {
|
message Media {
|
||||||
//Resource name of the remote media object
|
//Resource name of the remote media object
|
||||||
string name = 1;
|
string name = 1;
|
||||||
string title = 2;
|
string title = 2;
|
||||||
@ -151,7 +160,7 @@ message ListMediaRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ListMediaResponse {
|
message ListMediaResponse {
|
||||||
repeated RemoteMedia media = 1;
|
repeated Media media = 1;
|
||||||
string nextPageToken = 3;
|
string nextPageToken = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +169,17 @@ message GetMediaRequest {
|
|||||||
string name = 1;
|
string name = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message CreateMediaRequest {
|
||||||
|
//Resource name of the parent collection of the member to be created (The party)
|
||||||
|
string parent = 1;
|
||||||
|
Media media = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteMediaRequest {
|
||||||
|
//Resource name of the member to be deleted
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message StreamMediaRequest {
|
message StreamMediaRequest {
|
||||||
//Resource name of the media requested
|
//Resource name of the media requested
|
||||||
string name = 1;
|
string name = 1;
|
||||||
@ -199,7 +219,7 @@ message BaseEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message NewMediaPlayingEvent {
|
message NewMediaPlayingEvent {
|
||||||
RemoteMedia media = 1;
|
Media media = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message MediaResumedEvent {
|
message MediaResumedEvent {
|
||||||
|
@ -2,7 +2,9 @@ using System;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Aurora.Proto.Sync;
|
using Aurora.Proto.Sync;
|
||||||
using Aurora.Proto.General;
|
using Aurora.Proto.General;
|
||||||
using Aurora.Services.PlayerService;
|
using Aurora.Services.Player;
|
||||||
|
using Aurora;
|
||||||
|
using Autofac;
|
||||||
|
|
||||||
namespace Aurora.RemoteImpl
|
namespace Aurora.RemoteImpl
|
||||||
{
|
{
|
||||||
@ -19,31 +21,36 @@ namespace Aurora.RemoteImpl
|
|||||||
Grpc.Core.IServerStreamWriter<Sync> responseStream,
|
Grpc.Core.IServerStreamWriter<Sync> responseStream,
|
||||||
Grpc.Core.ServerCallContext context)
|
Grpc.Core.ServerCallContext context)
|
||||||
{
|
{
|
||||||
bool continueSync = true;
|
using (var scope = App.Container.BeginLifetimeScope())
|
||||||
string currentId = PlayerService.Instance.CurrentMedia.Id;
|
|
||||||
MediaChangedEventHandler mediaChanged = (sender, e) =>
|
|
||||||
{
|
{
|
||||||
if (e.NewId != currentId)
|
IPlayer player = scope.Resolve<IPlayer>();
|
||||||
|
bool continueSync = true;
|
||||||
|
string currentId = player.CurrentMedia.Id;
|
||||||
|
MediaChangedEventHandler mediaChanged = (sender, e) =>
|
||||||
{
|
{
|
||||||
continueSync = false;
|
if (e.NewId != currentId)
|
||||||
}
|
{
|
||||||
};
|
continueSync = false;
|
||||||
|
}
|
||||||
PlayerService.Instance.MediaChanged += mediaChanged;
|
|
||||||
|
|
||||||
while (continueSync)
|
|
||||||
{
|
|
||||||
float length = PlayerService.Instance.CurrentMediaLength;
|
|
||||||
|
|
||||||
Sync sync = new Sync()
|
|
||||||
{
|
|
||||||
TrackPosition = PlayerService.Instance.CurrentMediaPosition,
|
|
||||||
ServerTimeTicks = Utils.TimeUtils.GetNetworkTime().DateTime.Ticks
|
|
||||||
};
|
};
|
||||||
await responseStream.WriteAsync(sync);
|
|
||||||
Console.WriteLine("Sent Sync");
|
player.MediaChanged += mediaChanged;
|
||||||
await Task.Delay(5000);
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,11 +8,12 @@ using Aurora.Proto.Playback;
|
|||||||
using Aurora.Proto.Sync;
|
using Aurora.Proto.Sync;
|
||||||
using Aurora.Services.ClientService.Events;
|
using Aurora.Services.ClientService.Events;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Aurora.Services.Settings;
|
||||||
|
|
||||||
namespace Aurora.Services.ClientService
|
namespace Aurora.Services.ClientService
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ClientService : BaseService<ClientService>
|
public class ClientService : IClientService
|
||||||
{
|
{
|
||||||
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
|
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
|
||||||
private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
|
private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
|
||||||
@ -20,17 +21,19 @@ namespace Aurora.Services.ClientService
|
|||||||
private RemoteSyncService.RemoteSyncServiceClient _remoteSyncClient;
|
private RemoteSyncService.RemoteSyncServiceClient _remoteSyncClient;
|
||||||
|
|
||||||
private Channel _channel;
|
private Channel _channel;
|
||||||
CancellationTokenSource _eventCancellationTokenSource;
|
private CancellationTokenSource _eventCancellationTokenSource;
|
||||||
|
private ISettingsService _settingsService;
|
||||||
|
|
||||||
public ClientService()
|
public ClientService(ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
|
this._settingsService = settingsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaPausedEventHandler OnMediaPaused;
|
public MediaPausedEventHandler OnMediaPaused { get; set; }
|
||||||
public NewMediaPlayingEventHandler OnNewMediaPlaying;
|
public NewMediaPlayingEventHandler OnNewMediaPlaying { get; set; }
|
||||||
public PartyMemberJoinedEventHandler OnPartyMemberJoined;
|
public PartyMemberJoinedEventHandler OnPartyMemberJoined { get; set; }
|
||||||
public PartyMemberLeftEventHandler OnPartyMemberLeft;
|
public PartyMemberLeftEventHandler OnPartyMemberLeft { get; set; }
|
||||||
public MediaResumedEventHandler OnMediaResumed;
|
public MediaResumedEventHandler OnMediaResumed { get; set; }
|
||||||
|
|
||||||
public RemotePartyService.RemotePartyServiceClient RemotePartyClient
|
public RemotePartyService.RemotePartyServiceClient RemotePartyClient
|
||||||
{
|
{
|
||||||
@ -94,10 +97,10 @@ namespace Aurora.Services.ClientService
|
|||||||
public async Task GetEvents()
|
public async Task GetEvents()
|
||||||
{
|
{
|
||||||
_eventCancellationTokenSource = new CancellationTokenSource();
|
_eventCancellationTokenSource = new CancellationTokenSource();
|
||||||
string clientId = SettingsService.Instance.ClientId;
|
string clientId = this._settingsService.ClientId;
|
||||||
Console.WriteLine(string.Format("CLIENT {0} - GetEvents called from client with id", clientId));
|
Console.WriteLine(string.Format("CLIENT {0} - GetEvents called from client with id", clientId));
|
||||||
using (AsyncServerStreamingCall<BaseEvent> eventStream = _remoteEventsClient
|
using (AsyncServerStreamingCall<BaseEvent> eventStream = _remoteEventsClient
|
||||||
.GetEvents(new EventsRequest { ClientId = SettingsService.Instance.ClientId }))
|
.GetEvents(new EventsRequest { ClientId = this._settingsService.ClientId }))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
42
Aurora/Services/ClientService/IClientService.cs
Normal file
42
Aurora/Services/ClientService/IClientService.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Aurora.Services.ClientService.Events;
|
||||||
|
using Aurora.Proto.Events;
|
||||||
|
using Aurora.Proto.Party;
|
||||||
|
using Aurora.Proto.Playback;
|
||||||
|
using Aurora.Proto.Sync;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Aurora.Services.ClientService
|
||||||
|
{
|
||||||
|
public interface IClientService
|
||||||
|
{
|
||||||
|
MediaPausedEventHandler OnMediaPaused { get; set; }
|
||||||
|
NewMediaPlayingEventHandler OnNewMediaPlaying { get; set; }
|
||||||
|
PartyMemberJoinedEventHandler OnPartyMemberJoined { get; set; }
|
||||||
|
PartyMemberLeftEventHandler OnPartyMemberLeft { get; set; }
|
||||||
|
MediaResumedEventHandler OnMediaResumed { get; set; }
|
||||||
|
|
||||||
|
RemotePartyService.RemotePartyServiceClient RemotePartyClient { get; }
|
||||||
|
|
||||||
|
RemoteEventService.RemoteEventServiceClient RemoteEventClient { get; }
|
||||||
|
|
||||||
|
RemotePlaybackService.RemotePlaybackServiceClient RemotePlaybackClient { get; }
|
||||||
|
|
||||||
|
RemoteSyncService.RemoteSyncServiceClient RemoteSyncClient { get; }
|
||||||
|
|
||||||
|
bool IsStarted { get; }
|
||||||
|
|
||||||
|
bool IsHost { get; set; }
|
||||||
|
|
||||||
|
void Start(string hostname, string port);
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asynchronous function for processing events off of the event stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task GetEvents();
|
||||||
|
|
||||||
|
void StopEvents();
|
||||||
|
}
|
||||||
|
}
|
64
Aurora/Services/Player/IPlayer.cs
Normal file
64
Aurora/Services/Player/IPlayer.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
using Grpc.Core;
|
||||||
|
using Aurora.Models.Media;
|
||||||
|
using Aurora.Proto.Sync;
|
||||||
|
using LibVLCSharp.Shared;
|
||||||
|
|
||||||
|
namespace Aurora.Services.Player
|
||||||
|
{
|
||||||
|
|
||||||
|
public interface IPlayer
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event handler for changing playback states.
|
||||||
|
/// </summary>
|
||||||
|
event PlaybackStateChangedEventHandler PlaybackStateChanged;
|
||||||
|
|
||||||
|
event MediaChangedEventHandler MediaChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The state of playback
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
PlaybackState PlaybackState { get; }
|
||||||
|
|
||||||
|
bool IsLoaded { get; }
|
||||||
|
|
||||||
|
bool IsMediaLoaded(BaseMedia media);
|
||||||
|
|
||||||
|
BaseMedia CurrentMedia { get; }
|
||||||
|
|
||||||
|
float CurrentMediaPosition { get; }
|
||||||
|
|
||||||
|
long CurrentMediaLength { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load media into the media player.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="media">Media to load</param>
|
||||||
|
Task LoadMedia(BaseMedia media);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Play currently loaded media.
|
||||||
|
/// </summary>
|
||||||
|
void Play();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pause currently loaded media.
|
||||||
|
/// </summary>
|
||||||
|
void Pause();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop currently loaded media.
|
||||||
|
/// </summary>
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
void Enqueue(BaseMedia song);
|
||||||
|
|
||||||
|
void Dequeue(BaseMedia song);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Aurora.Models.Media;
|
using Aurora.Models.Media;
|
||||||
|
|
||||||
namespace Aurora.Services.PlayerService
|
namespace Aurora.Services.Player
|
||||||
{
|
{
|
||||||
public delegate void MediaChangedEventHandler(object source, MediaChangedEventArgs e);
|
public delegate void MediaChangedEventHandler(object source, MediaChangedEventArgs e);
|
||||||
|
|
12
Aurora/Services/Player/PlaybackState.cs
Normal file
12
Aurora/Services/Player/PlaybackState.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Aurora.Services.Player
|
||||||
|
{
|
||||||
|
public enum PlaybackState
|
||||||
|
{
|
||||||
|
Playing,
|
||||||
|
Stopped,
|
||||||
|
Buffering,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Aurora.Models.Media;
|
using Aurora.Models.Media;
|
||||||
|
|
||||||
namespace Aurora.Services.PlayerService
|
namespace Aurora.Services.Player
|
||||||
{
|
{
|
||||||
public delegate void PlaybackStateChangedEventHandler(object source, PlaybackStateChangedEventArgs e);
|
public delegate void PlaybackStateChangedEventHandler(object source, PlaybackStateChangedEventArgs e);
|
||||||
|
|
@ -6,10 +6,10 @@ using Aurora.Models.Media;
|
|||||||
using Aurora.Proto.Sync;
|
using Aurora.Proto.Sync;
|
||||||
using LibVLCSharp.Shared;
|
using LibVLCSharp.Shared;
|
||||||
|
|
||||||
namespace Aurora.Services.PlayerService
|
namespace Aurora.Services.Player
|
||||||
{
|
{
|
||||||
|
|
||||||
public class PlayerService : BaseService<PlayerService>
|
public class PlayerService : BaseService<PlayerService>, IPlayer
|
||||||
{
|
{
|
||||||
private const long _ticksPerMillisecond = 10000;
|
private const long _ticksPerMillisecond = 10000;
|
||||||
private BaseMedia _currentMedia;
|
private BaseMedia _currentMedia;
|
@ -1,9 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
public enum PlaybackState
|
|
||||||
{
|
|
||||||
Playing,
|
|
||||||
Stopped,
|
|
||||||
Buffering,
|
|
||||||
|
|
||||||
}
|
|
38
Aurora/Services/Server/Controllers/Constructor.cs
Normal file
38
Aurora/Services/Server/Controllers/Constructor.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Aurora.Proto.PartyV2;
|
||||||
|
|
||||||
|
namespace Aurora.Services.Server.Controllers
|
||||||
|
{
|
||||||
|
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for partial class
|
||||||
|
/// </summary>
|
||||||
|
public RemotePartyController(string partyName, string description)
|
||||||
|
{
|
||||||
|
this._startDateTime = DateTime.UtcNow;
|
||||||
|
this._displayName = partyName;
|
||||||
|
this._description = description;
|
||||||
|
this._memberList = new SortedList<string, Member>();
|
||||||
|
this._mediaList = new SortedList<string, Models.Media.BaseMedia>();
|
||||||
|
|
||||||
|
string userName = "testUser";
|
||||||
|
|
||||||
|
this._eventManager = new EventManager.EventManager();
|
||||||
|
|
||||||
|
this._hostMember = new Member()
|
||||||
|
{
|
||||||
|
Name = GetNewMemberResourceName(_partyResourceName, ServerService.GetLocalIPAddress(), userName),
|
||||||
|
UserName = userName,
|
||||||
|
IpAddress = ServerService.GetLocalIPAddress(),
|
||||||
|
};
|
||||||
|
|
||||||
|
this._memberList.Add(_hostMember.Name, _hostMember);
|
||||||
|
|
||||||
|
//Add media from library
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +1,158 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Aurora.Proto.PartyV2;
|
using Aurora.Proto.PartyV2;
|
||||||
|
using Aurora.Models.Media;
|
||||||
|
using Aurora.Proto.General;
|
||||||
|
using Aurora.Services.Player;
|
||||||
|
using Autofac;
|
||||||
|
|
||||||
namespace Aurora.Services.Server.Controllers
|
namespace Aurora.Services.Server.Controllers
|
||||||
{
|
{
|
||||||
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
public partial class RemotePartyController : RemotePartyService.RemotePartyServiceBase
|
||||||
{
|
{
|
||||||
|
private SortedList<string, BaseMedia> _mediaList;
|
||||||
|
|
||||||
public override Task<ListMediaResponse> ListMedia(ListMediaRequest request, Grpc.Core.ServerCallContext context)
|
public override Task<ListMediaResponse> ListMedia(ListMediaRequest request, Grpc.Core.ServerCallContext context)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
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<RemoteMedia> GetMedia(GetMediaRequest request, Grpc.Core.ServerCallContext context)
|
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();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task StreamMedia(StreamMediaRequest request, Grpc.Core.IServerStreamWriter<Proto.General.Chunk> responseStream, Grpc.Core.ServerCallContext context)
|
public override Task<Empty> DeleteMedia(DeleteMediaRequest request, Grpc.Core.ServerCallContext context)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task SyncMedia(SyncMediaRequest request, Grpc.Core.IServerStreamWriter<Sync> responseStream, Grpc.Core.ServerCallContext context)
|
public override async Task StreamMedia(StreamMediaRequest request, Grpc.Core.IServerStreamWriter<Proto.General.Chunk> responseStream, Grpc.Core.ServerCallContext context)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,19 +25,21 @@ namespace Aurora.Services.Server.Controllers
|
|||||||
startIdx = _memberList.IndexOfKey(request.PageToken) + 1;
|
startIdx = _memberList.IndexOfKey(request.PageToken) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pageSize = request.PageSize;
|
||||||
|
|
||||||
//Assign pageSize
|
//Assign pageSize
|
||||||
if (request.PageSize > _memberList.Count)
|
if (pageSize > _memberList.Count)
|
||||||
{
|
{
|
||||||
request.PageSize = _memberList.Count;
|
pageSize = _memberList.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Gather page
|
//Gather page
|
||||||
List<Member> members = new List<Member>(_memberList.Values);
|
List<Member> members = new List<Member>(_memberList.Values);
|
||||||
resp.Members.AddRange(members.GetRange(startIdx, request.PageSize));
|
resp.Members.AddRange(members.GetRange(startIdx, pageSize));
|
||||||
|
|
||||||
//Set next page token
|
//Set next page token
|
||||||
resp.NextPageToken = resp.Members[(startIdx + request.PageSize) - 1].Name;
|
resp.NextPageToken = resp.Members[resp.Members.Count - 1].Name;
|
||||||
|
|
||||||
return Task.FromResult(resp);
|
return Task.FromResult(resp);
|
||||||
}
|
}
|
||||||
|
@ -17,30 +17,6 @@ namespace Aurora.Services.Server.Controllers
|
|||||||
|
|
||||||
private EventManager.EventManager _eventManager;
|
private EventManager.EventManager _eventManager;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor for partial class
|
|
||||||
/// </summary>
|
|
||||||
public RemotePartyController(string partyName, string description)
|
|
||||||
{
|
|
||||||
this._startDateTime = DateTime.UtcNow;
|
|
||||||
this._displayName = partyName;
|
|
||||||
this._description = description;
|
|
||||||
this._memberList = new SortedList<string, Member>();
|
|
||||||
|
|
||||||
string userName = "testUser";
|
|
||||||
|
|
||||||
this._eventManager = new EventManager.EventManager();
|
|
||||||
|
|
||||||
this._hostMember = new Member()
|
|
||||||
{
|
|
||||||
Name = GetNewMemberResourceName(_partyResourceName, ServerService.GetLocalIPAddress(), userName),
|
|
||||||
UserName = userName,
|
|
||||||
IpAddress = ServerService.GetLocalIPAddress(),
|
|
||||||
};
|
|
||||||
|
|
||||||
this._memberList.Add(_hostMember.Name, _hostMember);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task<Party> GetParty(Proto.General.Empty request, Grpc.Core.ServerCallContext context)
|
public override Task<Party> GetParty(Proto.General.Empty request, Grpc.Core.ServerCallContext context)
|
||||||
{
|
{
|
||||||
Party party = new Party()
|
Party party = new Party()
|
||||||
|
@ -8,13 +8,14 @@ using Aurora.Proto.Events;
|
|||||||
using Aurora.Proto.Party;
|
using Aurora.Proto.Party;
|
||||||
using Aurora.Proto.Playback;
|
using Aurora.Proto.Playback;
|
||||||
using Aurora.Proto.Sync;
|
using Aurora.Proto.Sync;
|
||||||
|
using Aurora.Services.Settings;
|
||||||
|
using Autofac;
|
||||||
|
|
||||||
namespace Aurora.Services
|
namespace Aurora.Services
|
||||||
{
|
{
|
||||||
public class ServerService : BaseService<ServerService>
|
public class ServerService : BaseService<ServerService>
|
||||||
{
|
{
|
||||||
private int _port = SettingsService.Instance.DefaultPort;
|
private int _port;
|
||||||
private string _hostname;
|
private string _hostname;
|
||||||
private Grpc.Core.Server _server;
|
private Grpc.Core.Server _server;
|
||||||
|
|
||||||
@ -30,6 +31,11 @@ namespace Aurora.Services
|
|||||||
public ServerService()
|
public ServerService()
|
||||||
{
|
{
|
||||||
string host = GetLocalIPAddress();
|
string host = GetLocalIPAddress();
|
||||||
|
using (var scope = App.Container.BeginLifetimeScope())
|
||||||
|
{
|
||||||
|
var service = scope.Resolve<ISettingsService>();
|
||||||
|
this._port = service.DefaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(host))
|
if (string.IsNullOrWhiteSpace(host))
|
||||||
{
|
{
|
||||||
|
27
Aurora/Services/Settings/ISettingsService.cs
Normal file
27
Aurora/Services/Settings/ISettingsService.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using Plugin.Settings.Abstractions;
|
||||||
|
|
||||||
|
namespace Aurora.Services.Settings
|
||||||
|
{
|
||||||
|
public interface ISettingsService
|
||||||
|
{
|
||||||
|
ISettings AppSettings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user's username. This is persisted.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
string Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default port to use. This is persisted.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
int DefaultPort { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current sessions clientId. This is assigned by the server. This is not persisted.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
string ClientId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -3,9 +3,9 @@ using System.Threading;
|
|||||||
using Plugin.Settings;
|
using Plugin.Settings;
|
||||||
using Plugin.Settings.Abstractions;
|
using Plugin.Settings.Abstractions;
|
||||||
|
|
||||||
namespace Aurora.Services
|
namespace Aurora.Services.Settings
|
||||||
{
|
{
|
||||||
public class SettingsService : BaseService<SettingsService>
|
public class SettingsService : ISettingsService
|
||||||
{
|
{
|
||||||
private Lazy<ISettings> _appSettings;
|
private Lazy<ISettings> _appSettings;
|
||||||
private string _usernameKey = "username";
|
private string _usernameKey = "username";
|
Reference in New Issue
Block a user