Initial commit
This commit is contained in:
158
TechMedia.Core/TechMediaCore.cs
Normal file
158
TechMedia.Core/TechMediaCore.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using TechMedia.Core.Backend;
|
||||
using TechMedia.Core.Model;
|
||||
|
||||
namespace TechMedia.Core
|
||||
{
|
||||
public class TechMediaCore : ITechMediaCore
|
||||
{
|
||||
private readonly IAudioBackend _backend;
|
||||
private List<Track> _currentPlaylist = new();
|
||||
private Queue<Track> _requestQueue = new();
|
||||
|
||||
private IProgress<Track>? _trackReporter;
|
||||
private IProgress<float>? _progressReporter;
|
||||
private IProgress<List<Track>>? _playlistWatcher;
|
||||
private int _playbackIndex = 0;
|
||||
|
||||
public TechMediaCore(IAudioBackend backend)
|
||||
{
|
||||
_backend = backend;
|
||||
_backend.RegisterTrackEndHandler(TrackEndHandler);
|
||||
}
|
||||
|
||||
public void StartPlaylistPlayback(IProgress<Track>? trackReporter = null, IProgress<float>? progressReporter = null)
|
||||
{
|
||||
if (trackReporter != null)
|
||||
_trackReporter = trackReporter;
|
||||
|
||||
if (progressReporter != null)
|
||||
{
|
||||
if (_progressReporter != null)
|
||||
{
|
||||
_backend.RemoveProgressWatcher(_progressReporter);
|
||||
}
|
||||
_progressReporter = progressReporter;
|
||||
_backend.RegisterProgressWatcher(progressReporter);
|
||||
}
|
||||
|
||||
var firstTrack = _currentPlaylist[_playbackIndex++];
|
||||
_backend.PlayFile(firstTrack.Filename);
|
||||
_trackReporter?.Report(firstTrack);
|
||||
}
|
||||
|
||||
private void QueueFilePlayback(string filename)
|
||||
{
|
||||
// LibVLC has a famous bug when calling LibVLC from a LibVLC callback (which is what this method is) that results in a deadlock.
|
||||
// Workaround is to queue the action on another thread.
|
||||
ThreadPool.QueueUserWorkItem(_ => _backend.PlayFile(filename));
|
||||
}
|
||||
|
||||
public void TrackEndHandler(object? sender, EventArgs args)
|
||||
{
|
||||
if (_requestQueue.Count > 0)
|
||||
{
|
||||
var requestTrack = _requestQueue.Dequeue();
|
||||
_trackReporter?.Report(requestTrack);
|
||||
QueueFilePlayback(requestTrack.Filename);
|
||||
}
|
||||
else if (_playbackIndex < _currentPlaylist.Count)
|
||||
{
|
||||
var nextTrack = _currentPlaylist[_playbackIndex++];
|
||||
_trackReporter?.Report(nextTrack);
|
||||
QueueFilePlayback(nextTrack.Filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
ShuffleCurrentPlaylist();
|
||||
StartPlaylistPlayback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_backend.StopPlayback();
|
||||
_playbackIndex = 0;
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void NextTrack()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void PreviousTrack()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void GetNextTrackInfo()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void GetCurrentTrackInfo()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OpenMediaFile(string filename)
|
||||
{
|
||||
_backend.PlayFile(filename);
|
||||
}
|
||||
|
||||
public void OpenPlaylistFile()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<int> LoadFiles(List<string> files, IProgress<int>? progress = null)
|
||||
{
|
||||
_currentPlaylist = new List<Track>();
|
||||
foreach (var (file, index) in files.Select((filename, index) => (filename, index)))
|
||||
{
|
||||
var track = await _backend.GetFileMetadata(file);
|
||||
progress?.Report(index);
|
||||
if (track != null)
|
||||
_currentPlaylist.Add(track);
|
||||
}
|
||||
return _currentPlaylist.Count;
|
||||
}
|
||||
|
||||
public List<Track> ShuffleCurrentPlaylist()
|
||||
{
|
||||
_backend.StopPlayback();
|
||||
_playbackIndex = 0;
|
||||
var random = new Random();
|
||||
_currentPlaylist = _currentPlaylist.OrderBy(t => random.Next()).ToList();
|
||||
_playlistWatcher?.Report(_currentPlaylist);
|
||||
return _currentPlaylist;
|
||||
}
|
||||
|
||||
public List<Track> GetCurrentPlaylist() => _currentPlaylist;
|
||||
public void RegisterPlaylistChangeListener(IProgress<List<Track>> playlistWatcher)
|
||||
{
|
||||
_playlistWatcher = playlistWatcher;
|
||||
}
|
||||
|
||||
public Track? SubmitRequest(string filename)
|
||||
{
|
||||
var requestedTrack = _currentPlaylist.FirstOrDefault(t => t.Filename.Equals(filename, StringComparison.OrdinalIgnoreCase));
|
||||
if (requestedTrack != null)
|
||||
_requestQueue.Enqueue(requestedTrack);
|
||||
|
||||
return requestedTrack;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user