Remote playback almost working
This commit is contained in:
parent
a13e491a7e
commit
a537edd657
@ -1,54 +1,100 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project
|
||||||
|
Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<ProduceAssemblyReference>true</ProduceAssemblyReference>
|
<ProduceAssemblyReference>true</ProduceAssemblyReference>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup
|
||||||
|
Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Xamarin.Forms" Version="3.6.0.264807" />
|
<PackageReference
|
||||||
<PackageReference Include="Xamarin.Essentials" Version="1.0.1" />
|
Include="Xamarin.Forms"
|
||||||
<PackageReference Include="Xamarin.Forms.DataGrid" Version="3.1.0" />
|
Version="3.6.0.264807"/>
|
||||||
<PackageReference Include="taglib-sharp-netstandard2.0" Version="2.1.0" />
|
<PackageReference
|
||||||
<PackageReference Include="LibVLCSharp.Forms" Version="3.0.0" />
|
Include="Xamarin.Essentials"
|
||||||
<PackageReference Include="VideoLAN.LibVLC.Mac" Version="3.1.3" />
|
Version="1.0.1"/>
|
||||||
<PackageReference Include="Grpc" Version="1.21.0" />
|
<PackageReference
|
||||||
<PackageReference Include="Grpc.Tools" Version="1.21.0" PrivateAssests="All" />
|
Include="Xamarin.Forms.DataGrid"
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.8.0" />
|
Version="3.1.0"/>
|
||||||
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
|
<PackageReference
|
||||||
<PackageReference Include="Sharpnado.Forms.HorizontalListView" Version="1.2.0" />
|
Include="taglib-sharp-netstandard2.0"
|
||||||
|
Version="2.1.0"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="LibVLCSharp.Forms"
|
||||||
|
Version="3.0.0"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="VideoLAN.LibVLC.Mac"
|
||||||
|
Version="3.1.3"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="Grpc"
|
||||||
|
Version="1.21.0"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="Grpc.Tools"
|
||||||
|
Version="1.21.0"
|
||||||
|
PrivateAssests="All"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="Google.Protobuf"
|
||||||
|
Version="3.8.0"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="Xam.Plugins.Settings"
|
||||||
|
Version="3.1.1"/>
|
||||||
|
<PackageReference
|
||||||
|
Include="Sharpnado.Forms.HorizontalListView"
|
||||||
|
Version="1.2.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Design\" />
|
<Folder
|
||||||
<Folder Include="Design\Components\" />
|
Include="Design\"/>
|
||||||
<Folder Include="Design\Views\" />
|
<Folder
|
||||||
<Folder Include="Design\Views\Songs\" />
|
Include="Design\Components\"/>
|
||||||
<Folder Include="Design\Views\MainView\" />
|
<Folder
|
||||||
<Folder Include="Design\Behaviors\" />
|
Include="Design\Views\"/>
|
||||||
<Folder Include="Design\Components\NavigationMenu\" />
|
<Folder
|
||||||
<Folder Include="Design\Views\Albums\" />
|
Include="Design\Views\Songs\"/>
|
||||||
<Folder Include="Design\Views\Artists\" />
|
<Folder
|
||||||
<Folder Include="Design\Views\Stations\" />
|
Include="Design\Views\MainView\"/>
|
||||||
<Folder Include="Utils\" />
|
<Folder
|
||||||
<Folder Include="Models\" />
|
Include="Design\Behaviors\"/>
|
||||||
<Folder Include="Services\" />
|
<Folder
|
||||||
<Folder Include="Design\Views\Party\" />
|
Include="Design\Components\NavigationMenu\"/>
|
||||||
<Folder Include="Design\Components\HostSelector\" />
|
<Folder
|
||||||
<Folder Include="Design\Components\MemberList\" />
|
Include="Design\Views\Albums\"/>
|
||||||
<Folder Include="Design\Components\Queue\" />
|
<Folder
|
||||||
<Folder Include="Design\Views\Profile\" />
|
Include="Design\Views\Artists\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Design\Views\Stations\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Utils\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Models\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Services\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Design\Views\Party\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Design\Components\HostSelector\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Design\Components\MemberList\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Design\Components\Queue\"/>
|
||||||
|
<Folder
|
||||||
|
Include="Design\Views\Profile\"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="Design\Components\MusicPlayer\Player.xaml.cs">
|
<Compile
|
||||||
|
Update="Design\Components\MusicPlayer\Player.xaml.cs">
|
||||||
<DependentUpon>Player.xaml</DependentUpon>
|
<DependentUpon>Player.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Protobuf Include="Proto\general.proto" />
|
<Protobuf
|
||||||
<Protobuf Include="Proto\party.proto" />
|
Include="Proto\general.proto"/>
|
||||||
<Protobuf Include="Proto\playback.proto" />
|
<Protobuf
|
||||||
<Protobuf Include="Proto\events.proto" />
|
Include="Proto\party.proto"/>
|
||||||
|
<Protobuf
|
||||||
|
Include="Proto\events.proto"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -12,6 +12,10 @@
|
|||||||
HeaderHeight="40"
|
HeaderHeight="40"
|
||||||
BorderColor="#CCCCCC"
|
BorderColor="#CCCCCC"
|
||||||
HeaderBackground="#E0E6F8">
|
HeaderBackground="#E0E6F8">
|
||||||
|
<dg:DataGrid.GestureRecognizers>
|
||||||
|
<TapGestureRecognizer
|
||||||
|
NumberOfTapsRequired="2"/>
|
||||||
|
</dg:DataGrid.GestureRecognizers>
|
||||||
<dg:DataGrid.HeaderFontSize>
|
<dg:DataGrid.HeaderFontSize>
|
||||||
<OnIdiom
|
<OnIdiom
|
||||||
x:TypeArguments="x:Double">
|
x:TypeArguments="x:Double">
|
||||||
|
@ -12,6 +12,10 @@ namespace Aurora.Design.Components.Queue
|
|||||||
public Queue()
|
public Queue()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
this.QueueDataGrid.ItemSelected += (sender, e) =>
|
||||||
|
{
|
||||||
|
this.SelectedItem = e.SelectedItem;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ItemsSource Property
|
#region ItemsSource Property
|
||||||
@ -69,8 +73,7 @@ namespace Aurora.Design.Components.Queue
|
|||||||
BindableProperty.Create(propertyName: "SelectedItem",
|
BindableProperty.Create(propertyName: "SelectedItem",
|
||||||
returnType: typeof(object),
|
returnType: typeof(object),
|
||||||
declaringType: typeof(Queue),
|
declaringType: typeof(Queue),
|
||||||
defaultBindingMode: BindingMode.TwoWay,
|
defaultBindingMode: BindingMode.TwoWay);
|
||||||
propertyChanged: OnSelectedItemChanged);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Backing property for the SelectedItem property.
|
/// Backing property for the SelectedItem property.
|
||||||
@ -88,22 +91,58 @@ namespace Aurora.Design.Components.Queue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles selection change events.
|
/// Bindable property for the item double clicked command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bindable">The bindable object.</param>
|
/// <param name=""SelectedItem""></param>
|
||||||
|
/// <param name="typeof(BaseMetadata"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static readonly BindableProperty ItemDoubleClickedProperty =
|
||||||
|
BindableProperty.Create(propertyName: "ItemDoubleClicked",
|
||||||
|
returnType: typeof(Command),
|
||||||
|
declaringType: typeof(Queue),
|
||||||
|
propertyChanged: OnDoubleClickPropertyChanged);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Public backing property
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
public Command ItemDoubleClicked
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (Command)GetValue(ItemDoubleClickedProperty);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetValue(ItemDoubleClickedProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event handler for double click property. Adds command execute handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bindable"></param>
|
||||||
/// <param name="newValue"></param>
|
/// <param name="newValue"></param>
|
||||||
/// <param name="oldValue"></param>
|
/// <param name="oldValue"></param>
|
||||||
private static void OnSelectedItemChanged(BindableObject bindable, object newValue, object oldValue)
|
private static void OnDoubleClickPropertyChanged(BindableObject bindable, object newValue, object oldValue)
|
||||||
{
|
{
|
||||||
Queue control = bindable as Queue;
|
Queue control = bindable as Queue;
|
||||||
var queueDataGrid = control.FindByName("QueueDataGrid") as DataGrid;
|
var queueDataGrid = control.FindByName("QueueDataGrid") as DataGrid;
|
||||||
IEnumerable<object> source = (IEnumerable<object>)queueDataGrid.ItemsSource;
|
if (queueDataGrid.GestureRecognizers.Count > 0)
|
||||||
if (source.Contains(newValue))
|
|
||||||
{
|
{
|
||||||
queueDataGrid.SelectedItem = newValue;
|
var gestureRecognizer = queueDataGrid.GestureRecognizers.First();
|
||||||
}
|
|
||||||
|
|
||||||
|
if (gestureRecognizer is TapGestureRecognizer)
|
||||||
|
{
|
||||||
|
TapGestureRecognizer tap = gestureRecognizer as TapGestureRecognizer;
|
||||||
|
tap.Tapped += (sender, e) =>
|
||||||
|
{
|
||||||
|
control.ItemDoubleClicked.Execute(null);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
<Label
|
<Label
|
||||||
Text="Queue"/>
|
Text="Queue"/>
|
||||||
<qu:Queue
|
<qu:Queue
|
||||||
ItemsSource="{Binding Queue}"/>
|
ItemsSource="{Binding Queue}"
|
||||||
|
SelectedItem="{Binding SelectedSong}"
|
||||||
|
ItemDoubleClicked="{Binding PlayCommand}"/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<hs:HostSelector
|
<hs:HostSelector
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
|
@ -8,6 +8,7 @@ using Aurora.Proto.General;
|
|||||||
using Aurora.Proto.Party;
|
using Aurora.Proto.Party;
|
||||||
using Aurora.Proto.Events;
|
using Aurora.Proto.Events;
|
||||||
using Aurora.Services.ClientService;
|
using Aurora.Services.ClientService;
|
||||||
|
using Aurora.Services.PlayerService;
|
||||||
using Aurora.Models.Media;
|
using Aurora.Models.Media;
|
||||||
|
|
||||||
namespace Aurora.Design.Views.Party
|
namespace Aurora.Design.Views.Party
|
||||||
@ -24,8 +25,8 @@ namespace Aurora.Design.Views.Party
|
|||||||
private PartyState _state;
|
private PartyState _state;
|
||||||
private string _hostname;
|
private string _hostname;
|
||||||
private ObservableCollection<PartyMember> _members;
|
private ObservableCollection<PartyMember> _members;
|
||||||
|
private ObservableCollection<BaseMedia> _queue;
|
||||||
private ObservableCollection<RemoteMediaData> _queue;
|
private BaseMedia _selectedSong;
|
||||||
|
|
||||||
public PartyViewModel()
|
public PartyViewModel()
|
||||||
{
|
{
|
||||||
@ -33,10 +34,12 @@ namespace Aurora.Design.Views.Party
|
|||||||
this.HostCommand = new Command(OnHostExecute, CanHostExecute);
|
this.HostCommand = new Command(OnHostExecute, CanHostExecute);
|
||||||
|
|
||||||
_members = new ObservableCollection<PartyMember>();
|
_members = new ObservableCollection<PartyMember>();
|
||||||
_queue = new ObservableCollection<RemoteMediaData>();
|
_queue = new ObservableCollection<BaseMedia>();
|
||||||
|
|
||||||
SetState(PartyState.SelectingHost);
|
SetState(PartyState.SelectingHost);
|
||||||
|
|
||||||
|
PlayCommand = new Command(PlayExecute);
|
||||||
|
|
||||||
//Hook up event handler
|
//Hook up event handler
|
||||||
ClientService.Instance.EventReceived += this.OnEventReceived;
|
ClientService.Instance.EventReceived += this.OnEventReceived;
|
||||||
}
|
}
|
||||||
@ -70,7 +73,7 @@ namespace Aurora.Design.Views.Party
|
|||||||
get { return _state != PartyState.SelectingHost; }
|
get { return _state != PartyState.SelectingHost; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<RemoteMediaData> Queue
|
public ObservableCollection<BaseMedia> Queue
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -94,6 +97,14 @@ namespace Aurora.Design.Views.Party
|
|||||||
set { SetProperty(ref _hostname, value); }
|
set { SetProperty(ref _hostname, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BaseMedia SelectedSong
|
||||||
|
{
|
||||||
|
get { return _selectedSong; }
|
||||||
|
set { SetProperty(ref _selectedSong, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command PlayCommand { get; private set; }
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
@ -209,9 +220,21 @@ namespace Aurora.Design.Views.Party
|
|||||||
QueueResponse queueResponse = ClientService.Instance.RemotePartyClient.GetQueue(new Empty());
|
QueueResponse queueResponse = ClientService.Instance.RemotePartyClient.GetQueue(new Empty());
|
||||||
|
|
||||||
Queue.Clear();
|
Queue.Clear();
|
||||||
|
//Convert received data to remote audio models
|
||||||
foreach (RemoteMediaData data in queueResponse.MediaList)
|
foreach (RemoteMediaData data in queueResponse.MediaList)
|
||||||
{
|
{
|
||||||
Queue.Add(data);
|
//Assign received metadata (since this can't be aquired from a file)
|
||||||
|
AudioMetadata meta = new AudioMetadata();
|
||||||
|
meta.Title = data.Title;
|
||||||
|
meta.Album = data.Album;
|
||||||
|
meta.Artist = data.Artist;
|
||||||
|
meta.Duration = data.Duration;
|
||||||
|
|
||||||
|
RemoteAudio remote = new RemoteAudio(data.Id,
|
||||||
|
meta,
|
||||||
|
ClientService.Instance.RemotePartyClient);
|
||||||
|
|
||||||
|
Queue.Add(remote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -245,6 +268,11 @@ namespace Aurora.Design.Views.Party
|
|||||||
Members.Add(member);
|
Members.Add(member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PlayExecute()
|
||||||
|
{
|
||||||
|
PlayerService.Instance.LoadMedia(_selectedSong);
|
||||||
|
PlayerService.Instance.Play();
|
||||||
|
}
|
||||||
#endregion Private Methods
|
#endregion Private Methods
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ namespace Aurora.Models.Media
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public string Id { get; private set; }
|
public string Id { get; protected set; }
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
|
||||||
|
83
Aurora/Models/Media/RemoteAudio.cs
Normal file
83
Aurora/Models/Media/RemoteAudio.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using Aurora.Proto.Party;
|
||||||
|
using Aurora.Proto.General;
|
||||||
|
|
||||||
|
namespace Aurora.Models.Media
|
||||||
|
{
|
||||||
|
public class RemoteAudio : BaseMedia
|
||||||
|
{
|
||||||
|
private RemotePartyService.RemotePartyServiceClient _client;
|
||||||
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
public RemoteAudio(string id, RemotePartyService.RemotePartyServiceClient client)
|
||||||
|
{
|
||||||
|
this.Id = id;
|
||||||
|
this._client = client;
|
||||||
|
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAudio(string id, AudioMetadata metadata, RemotePartyService.RemotePartyServiceClient client)
|
||||||
|
{
|
||||||
|
this.Id = id;
|
||||||
|
this._client = client;
|
||||||
|
this.Metadata = metadata;
|
||||||
|
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Constructor
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public override BaseMetadata Metadata { get; protected set; }
|
||||||
|
|
||||||
|
public override MediaTypeEnum MediaType
|
||||||
|
{
|
||||||
|
get { return MediaTypeEnum.Audio; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override load method.
|
||||||
|
/// </summary>
|
||||||
|
public override async void Load()
|
||||||
|
{
|
||||||
|
this.DataStream = new MemoryStream();
|
||||||
|
|
||||||
|
using (var call = _client.GetSongStream(new SongRequest() { Id = this.Id }))
|
||||||
|
{
|
||||||
|
while (await call.ResponseStream.MoveNext(_cancellationTokenSource.Token))
|
||||||
|
{
|
||||||
|
Chunk chunk = call.ResponseStream.Current;
|
||||||
|
byte[] buffer = chunk.Content.ToByteArray();
|
||||||
|
|
||||||
|
await this.DataStream.WriteAsync(buffer, 0, buffer.Length, _cancellationTokenSource.Token);
|
||||||
|
Console.WriteLine(string.Format("Wrote byte chunk of size {0} to output stream", buffer.Length));
|
||||||
|
}
|
||||||
|
Console.WriteLine("Done receiving stream");
|
||||||
|
|
||||||
|
}
|
||||||
|
base.Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override unload method
|
||||||
|
/// </summary>
|
||||||
|
public override void Unload()
|
||||||
|
{
|
||||||
|
if (!_cancellationTokenSource.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_cancellationTokenSource.Cancel();
|
||||||
|
|
||||||
|
//Wait for cancellation
|
||||||
|
WaitHandle.WaitAny(new[] { _cancellationTokenSource.Token.WaitHandle });
|
||||||
|
}
|
||||||
|
base.Unload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ service RemotePartyService {
|
|||||||
rpc LeaveParty(LeavePartyRequest) returns (LeavePartyResponse);
|
rpc LeaveParty(LeavePartyRequest) returns (LeavePartyResponse);
|
||||||
rpc GetPartyMembers(Aurora.Proto.General.Empty) returns (MembersResponse);
|
rpc GetPartyMembers(Aurora.Proto.General.Empty) returns (MembersResponse);
|
||||||
rpc GetQueue(Aurora.Proto.General.Empty) returns (QueueResponse);
|
rpc GetQueue(Aurora.Proto.General.Empty) returns (QueueResponse);
|
||||||
|
rpc GetSongStream(SongRequest) returns (stream Aurora.Proto.General.Chunk) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
message JoinPartyRequest {
|
message JoinPartyRequest {
|
||||||
@ -49,8 +50,13 @@ message QueueResponse{
|
|||||||
}
|
}
|
||||||
|
|
||||||
message RemoteMediaData {
|
message RemoteMediaData {
|
||||||
string title = 1;
|
string id = 1;
|
||||||
string artist = 2;
|
string title = 2;
|
||||||
string album = 3;
|
string artist = 3;
|
||||||
string duration = 4;
|
string album = 4;
|
||||||
|
string duration = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SongRequest {
|
||||||
|
string id = 1;
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package Aurora.Proto.Playback;
|
|
||||||
|
|
||||||
import "Proto/general.proto";
|
|
||||||
|
|
||||||
service RemotePlaybackService {
|
|
||||||
//Playback Service
|
|
||||||
rpc GetPartyStream(Aurora.Proto.General.Empty) returns (stream Aurora.Proto.General.Chunk) {};
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TransferStatusCode {
|
|
||||||
Unknown = 0;
|
|
||||||
Ok = 1;
|
|
||||||
Failed = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TransferStatus {
|
|
||||||
string Message = 1;
|
|
||||||
TransferStatusCode Code = 2;
|
|
||||||
}
|
|
@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Aurora.Proto.Party;
|
using Aurora.Proto.Party;
|
||||||
using Aurora.Proto.Events;
|
using Aurora.Proto.Events;
|
||||||
|
using Aurora.Proto.General;
|
||||||
using Aurora.Services.EventManager;
|
using Aurora.Services.EventManager;
|
||||||
using Aurora.Services;
|
using Aurora.Services;
|
||||||
using Aurora.Models.Media;
|
using Aurora.Models.Media;
|
||||||
@ -104,7 +105,11 @@ namespace Aurora.RemoteImpl
|
|||||||
metadata = media.Metadata as AudioMetadata;
|
metadata = media.Metadata as AudioMetadata;
|
||||||
|
|
||||||
RemoteMediaData data = new RemoteMediaData();
|
RemoteMediaData data = new RemoteMediaData();
|
||||||
data.Title = metadata.Title == null ? metadata.Title : "";
|
data.Id = media.Id;
|
||||||
|
if (metadata.Title != null)
|
||||||
|
{
|
||||||
|
data.Title = metadata.Title;
|
||||||
|
}
|
||||||
if (metadata.Artist != null)
|
if (metadata.Artist != null)
|
||||||
{
|
{
|
||||||
data.Artist = metadata.Artist;
|
data.Artist = metadata.Artist;
|
||||||
@ -130,5 +135,24 @@ namespace Aurora.RemoteImpl
|
|||||||
return Task.FromResult(mediaList);
|
return Task.FromResult(mediaList);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task GetSongStream(SongRequest request,
|
||||||
|
Grpc.Core.IServerStreamWriter<Chunk> responseStream,
|
||||||
|
Grpc.Core.ServerCallContext context)
|
||||||
|
{
|
||||||
|
BaseMedia song = LibraryService.Instance.GetSong(request.Id);
|
||||||
|
song.Load();
|
||||||
|
|
||||||
|
//Send stream
|
||||||
|
Console.WriteLine("Begin sending file");
|
||||||
|
byte[] buffer = new byte[2048]; // read in chunks of 2KB
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = song.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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,39 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.IO;
|
|
||||||
using Aurora.Proto.Playback;
|
|
||||||
using Aurora.Proto.General;
|
|
||||||
using Aurora.Models;
|
|
||||||
|
|
||||||
namespace Aurora.RemoteImpl
|
|
||||||
{
|
|
||||||
public class RemotePlaybackServiceImpl : RemotePlaybackService.RemotePlaybackServiceBase
|
|
||||||
{
|
|
||||||
|
|
||||||
public RemotePlaybackServiceImpl()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task GetPartyStream(Empty empty,
|
|
||||||
Grpc.Core.IServerStreamWriter<Chunk> responseStream,
|
|
||||||
Grpc.Core.ServerCallContext context)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Working on it");
|
|
||||||
// //Send stream
|
|
||||||
// string cwd = Directory.GetCurrentDirectory();
|
|
||||||
// using (FileStream fs = System.IO.File.OpenRead(Path.Combine(cwd, request.FileName)))
|
|
||||||
// {
|
|
||||||
// Console.WriteLine("Begin sending file");
|
|
||||||
// byte[] buffer = new byte[2048]; // read in chunks of 2KB
|
|
||||||
// int bytesRead;
|
|
||||||
// while ((bytesRead = fs.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");
|
|
||||||
// };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ using System.Threading;
|
|||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Aurora.Proto.Events;
|
using Aurora.Proto.Events;
|
||||||
using Aurora.Proto.Party;
|
using Aurora.Proto.Party;
|
||||||
using Aurora.Proto.Playback;
|
|
||||||
using Aurora.Services.ClientService;
|
using Aurora.Services.ClientService;
|
||||||
|
|
||||||
namespace Aurora.Services.ClientService
|
namespace Aurora.Services.ClientService
|
||||||
@ -12,7 +11,6 @@ namespace Aurora.Services.ClientService
|
|||||||
public class ClientService : BaseService<ClientService>
|
public class ClientService : BaseService<ClientService>
|
||||||
{
|
{
|
||||||
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
|
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
|
||||||
private RemotePlaybackService.RemotePlaybackServiceClient _remotePlaybackClient;
|
|
||||||
private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
|
private RemoteEventService.RemoteEventServiceClient _remoteEventsClient;
|
||||||
private Channel _channel;
|
private Channel _channel;
|
||||||
CancellationTokenSource _eventCancellationTokenSource;
|
CancellationTokenSource _eventCancellationTokenSource;
|
||||||
@ -32,14 +30,6 @@ namespace Aurora.Services.ClientService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemotePlaybackService.RemotePlaybackServiceClient RemotePlaybackServiceClient
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _remotePlaybackClient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RemoteEventService.RemoteEventServiceClient RemoteEventClient
|
public RemoteEventService.RemoteEventServiceClient RemoteEventClient
|
||||||
{
|
{
|
||||||
get { return _remoteEventsClient; }
|
get { return _remoteEventsClient; }
|
||||||
@ -50,8 +40,7 @@ namespace Aurora.Services.ClientService
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _remoteEventsClient != null &&
|
return _remoteEventsClient != null &&
|
||||||
_remotePartyClient != null &&
|
_remotePartyClient != null;
|
||||||
_remotePlaybackClient != null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +49,6 @@ namespace Aurora.Services.ClientService
|
|||||||
_channel = new Channel(string.Format("{0}:{1}", hostname, port), ChannelCredentials.Insecure);
|
_channel = new Channel(string.Format("{0}:{1}", hostname, port), ChannelCredentials.Insecure);
|
||||||
|
|
||||||
_remotePartyClient = new RemotePartyService.RemotePartyServiceClient(_channel);
|
_remotePartyClient = new RemotePartyService.RemotePartyServiceClient(_channel);
|
||||||
_remotePlaybackClient = new RemotePlaybackService.RemotePlaybackServiceClient(_channel);
|
|
||||||
_remoteEventsClient = new RemoteEventService.RemoteEventServiceClient(_channel);
|
_remoteEventsClient = new RemoteEventService.RemoteEventServiceClient(_channel);
|
||||||
|
|
||||||
//Assign but don't start task
|
//Assign but don't start task
|
||||||
@ -73,7 +61,6 @@ namespace Aurora.Services.ClientService
|
|||||||
await _channel.ShutdownAsync();
|
await _channel.ShutdownAsync();
|
||||||
|
|
||||||
_remotePartyClient = null;
|
_remotePartyClient = null;
|
||||||
_remotePlaybackClient = null;
|
|
||||||
_remoteEventsClient = null;
|
_remoteEventsClient = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,12 @@ namespace Aurora.Services
|
|||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BaseMedia GetSong(string Id)
|
||||||
|
{
|
||||||
|
_library.TryGetValue(Id, out BaseMedia song);
|
||||||
|
return song;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads library from files.
|
/// Loads library from files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -6,7 +6,6 @@ using Grpc.Core;
|
|||||||
using Aurora.RemoteImpl;
|
using Aurora.RemoteImpl;
|
||||||
using Aurora.Proto.Events;
|
using Aurora.Proto.Events;
|
||||||
using Aurora.Proto.Party;
|
using Aurora.Proto.Party;
|
||||||
using Aurora.Proto.Playback;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Aurora.Services
|
namespace Aurora.Services
|
||||||
@ -19,7 +18,6 @@ namespace Aurora.Services
|
|||||||
|
|
||||||
//Implementation class declarations
|
//Implementation class declarations
|
||||||
RemotePartyServiceImpl _remotePartyServiceImpl;
|
RemotePartyServiceImpl _remotePartyServiceImpl;
|
||||||
RemotePlaybackServiceImpl _remotePlaybackImpl;
|
|
||||||
RemoteEventServiceImpl _remoteEventImpl;
|
RemoteEventServiceImpl _remoteEventImpl;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -58,7 +56,6 @@ namespace Aurora.Services
|
|||||||
{
|
{
|
||||||
return (_remoteEventImpl != null &&
|
return (_remoteEventImpl != null &&
|
||||||
_remotePartyServiceImpl != null &&
|
_remotePartyServiceImpl != null &&
|
||||||
_remotePlaybackImpl != null &&
|
|
||||||
_server != null);
|
_server != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,12 +75,10 @@ namespace Aurora.Services
|
|||||||
{
|
{
|
||||||
//Construct implementations
|
//Construct implementations
|
||||||
_remotePartyServiceImpl = new RemotePartyServiceImpl();
|
_remotePartyServiceImpl = new RemotePartyServiceImpl();
|
||||||
_remotePlaybackImpl = new RemotePlaybackServiceImpl();
|
|
||||||
_remoteEventImpl = new RemoteEventServiceImpl();
|
_remoteEventImpl = new RemoteEventServiceImpl();
|
||||||
|
|
||||||
// Register grpc RemoteService with singleton server service
|
// Register grpc RemoteService with singleton server service
|
||||||
RegisterService(RemotePartyService.BindService(_remotePartyServiceImpl));
|
RegisterService(RemotePartyService.BindService(_remotePartyServiceImpl));
|
||||||
RegisterService(RemotePlaybackService.BindService(_remotePlaybackImpl));
|
|
||||||
RegisterService(RemoteEventService.BindService(_remoteEventImpl));
|
RegisterService(RemoteEventService.BindService(_remoteEventImpl));
|
||||||
}
|
}
|
||||||
_server.Start();
|
_server.Start();
|
||||||
|
Loading…
Reference in New Issue
Block a user