242 lines
7.3 KiB
C#
242 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using KaraokePlayer.Interfaces;
|
|
using KaraokePlayer.Enums;
|
|
using FireSharp.Interfaces;
|
|
using FireSharp.Config;
|
|
using FireSharp;
|
|
|
|
namespace KaraokePlayer.Classes
|
|
{
|
|
public class FirebaseSong : ISong
|
|
{
|
|
public int Id { get; set; }
|
|
public int Order { get; set; }
|
|
public string Title { get; set; }
|
|
public string Artist { get; set; }
|
|
public FileType FileType { get; set; }
|
|
public string Path { get; set; }
|
|
public string Description { get { return Artist + " - " + Title; } }
|
|
}
|
|
|
|
public class FirebaseController : IController
|
|
{
|
|
private IFirebaseConfig config = new FirebaseConfig
|
|
{
|
|
AuthSecret = "wj0ERDFZqNSysTtIXcCgCr8Itahr6pJOBeqCjvDF",
|
|
BasePath = "https://karaokecontroller.firebaseio.com/"
|
|
};
|
|
private string _state = "stop";
|
|
private IFirebaseClient _client;
|
|
private ControllerStateChangedEventHandler _stateChanged;
|
|
private ControllerSongChangedEventHandler _songChanged;
|
|
private ControllerPlayQueueChangedEventHandler _playQueueChanged;
|
|
|
|
private string StatePath
|
|
{
|
|
get { return string.Format("Controllers/{0}/State", this.Id); }
|
|
}
|
|
private string PlayQueuePath
|
|
{
|
|
get { return string.Format("Controllers/{0}/PlayQueue", this.Id); }
|
|
}
|
|
private string CurrentSongPath
|
|
{
|
|
get { return string.Format("Controllers/{0}/CurrentSong", this.Id); }
|
|
}
|
|
|
|
public int Id { get; set; }
|
|
public ISong CurrentSong { get; set; }
|
|
public List<ISong> PlayQueue { get; set; }
|
|
|
|
public string State {
|
|
get { return State; }
|
|
set {
|
|
_state = value;
|
|
Update(string.Format("Controllers/{0}", this.Id), new { State = _state });
|
|
}
|
|
}
|
|
|
|
public FirebaseController(int clientId = 1, ControllerStateChangedEventHandler stateChanged = null, ControllerSongChangedEventHandler songChanged = null, ControllerPlayQueueChangedEventHandler playQueueChanged = null)
|
|
{
|
|
Id = clientId;
|
|
_stateChanged = stateChanged;
|
|
_songChanged = songChanged;
|
|
_playQueueChanged = playQueueChanged;
|
|
PlayQueue = new List<ISong>();
|
|
_client = new FirebaseClient(config);
|
|
Reset();
|
|
SetupListener();
|
|
}
|
|
|
|
public void NextSong()
|
|
{
|
|
ISong song = PlayQueue.FirstOrDefault();
|
|
Stop();
|
|
if(song != null) { PlaySong(song); }
|
|
}
|
|
|
|
public void PlaySong(ISong song) { Update(string.Format("Controllers/{0}", this.Id), new { CurrentSong = song }); }
|
|
|
|
public void AddSong(ISong song) { Update(string.Format("Controllers/{0}/PlayQueue/{1}", this.Id, song.Id), song); }
|
|
|
|
public void RemoveSong(ISong song)
|
|
{
|
|
ISong found = PlayQueue.FirstOrDefault(s => s.Id == song.Id);
|
|
if (found != null)
|
|
{
|
|
PlayQueue.Remove(found);
|
|
Delete(PlayQueuePath + "/" + song.Id);
|
|
}
|
|
}
|
|
|
|
public void SkipSong()
|
|
{
|
|
ISong song = null;
|
|
int count = PlayQueue.Count();
|
|
int index = PlayQueue.FindIndex(s => s.Id == CurrentSong.Id);
|
|
if (index + 1 == count && count > 1)
|
|
{
|
|
song = PlayQueue.First();
|
|
}
|
|
else {
|
|
if (PlayQueue.Count() > index)
|
|
{
|
|
song = PlayQueue[index + 1];
|
|
}
|
|
}
|
|
Stop();
|
|
if(song != null)
|
|
{
|
|
PlaySong(song);
|
|
}
|
|
}
|
|
|
|
public void Next() { this.State = "Next"; }
|
|
|
|
public void Play() { this.State = "Play"; }
|
|
|
|
public void Stop() { this.State = "Stop"; }
|
|
|
|
public void Pause() { this.State = "Pause"; }
|
|
|
|
private void Delete(string path) { _client.DeleteAsync(path); }
|
|
|
|
private void Update(string path, object data) { _client.UpdateAsync(path, data); }
|
|
|
|
private void Reset()
|
|
{
|
|
Stop();
|
|
Delete(PlayQueuePath);
|
|
Delete(CurrentSongPath);
|
|
}
|
|
|
|
private async void SetupListener()
|
|
{
|
|
await _client.OnAsync(CurrentSongPath,
|
|
added: (s, args, obj) =>
|
|
{
|
|
if (args.Path.Contains("Id"))
|
|
{
|
|
CurrentSongDidChange();
|
|
}
|
|
},
|
|
changed: (s, args, obj) =>
|
|
{
|
|
if (args.Path.Contains("Id"))
|
|
{
|
|
CurrentSongDidChange();
|
|
}
|
|
},
|
|
removed: null
|
|
);
|
|
|
|
await _client.OnAsync(PlayQueuePath,
|
|
added: (s, args, obj) =>
|
|
{
|
|
if (args.Path.Contains("Id"))
|
|
{
|
|
PlayQueueDidChange();
|
|
}
|
|
},
|
|
changed: (s, args, obj) =>
|
|
{
|
|
if (args.Path.Contains("Id"))
|
|
{
|
|
PlayQueueDidChange();
|
|
}
|
|
},
|
|
removed: (s, args, obj) =>
|
|
{
|
|
PlayQueueDidChange();
|
|
}
|
|
);
|
|
|
|
await _client.OnAsync(StatePath,
|
|
added: (s, args, obj) =>
|
|
{
|
|
StateDidChange(args.Data);
|
|
},
|
|
changed: (s, args, obj) =>
|
|
{
|
|
StateDidChange(args.Data);
|
|
},
|
|
removed: null
|
|
);
|
|
}
|
|
|
|
private void PlayQueueDidChange()
|
|
{
|
|
bool autoPlay = PlayQueue.Count() == 0;
|
|
var response = _client.Get(PlayQueuePath);
|
|
var dict = response.ResultAs<Dictionary<string, FirebaseSong>>();
|
|
|
|
PlayQueue.Clear();
|
|
if (dict != null && dict.Count() > 0)
|
|
{
|
|
var array = dict.Values.OrderBy(s => s.Order).ToArray();
|
|
PlayQueue.AddRange(array);
|
|
if (autoPlay)
|
|
{
|
|
NextSong();
|
|
}
|
|
}
|
|
if (_playQueueChanged != null) { _playQueueChanged(); }
|
|
}
|
|
|
|
private void CurrentSongDidChange()
|
|
{
|
|
var response = _client.Get(CurrentSongPath);
|
|
var song = response.ResultAs<FirebaseSong>();
|
|
if (song != null)
|
|
{
|
|
CurrentSong = song;
|
|
_songChanged(new ControllerSongChangedEventArgs(false, song));
|
|
}
|
|
}
|
|
|
|
private void StateDidChange(string state)
|
|
{
|
|
_state = state;
|
|
PlayerState s = PlayerState.Play;
|
|
if (state.ToLower() == "pause")
|
|
{
|
|
s = PlayerState.Pause;
|
|
}
|
|
else if (state.ToLower() == "stop")
|
|
{
|
|
s = PlayerState.Stop;
|
|
}
|
|
else if (state == "next")
|
|
{
|
|
s = PlayerState.Next;
|
|
}
|
|
_stateChanged(new ControllerStateChangedEventArgs(s));
|
|
}
|
|
|
|
}
|
|
}
|