rewrite started
This commit is contained in:
parent
7567f28baa
commit
b506064d37
@ -2,7 +2,9 @@
|
||||
using Discord.Audio;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
namespace NadekoBot.Modules.Music.Classes
|
||||
@ -52,6 +54,8 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
public bool Autoplay { get; set; } = false;
|
||||
public uint MaxQueueSize { get; set; } = 0;
|
||||
|
||||
private ConcurrentQueue<Action> actionQueue { get; set; } = new ConcurrentQueue<Action>();
|
||||
|
||||
public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume)
|
||||
{
|
||||
if (startingVoiceChannel == null)
|
||||
@ -66,65 +70,92 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (!Destroyed)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
if (audioClient?.State != ConnectionState.Connected)
|
||||
audioClient = await PlaybackVoiceChannel.JoinAudio().ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
continue;
|
||||
}
|
||||
CurrentSong = GetNextSong();
|
||||
var curSong = CurrentSong;
|
||||
if (curSong != null)
|
||||
while (!Destroyed)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnStarted(this, curSong);
|
||||
await curSong.Play(audioClient, cancelToken).ConfigureAwait(false);
|
||||
Action action;
|
||||
if (actionQueue.TryDequeue(out action))
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
finally
|
||||
{
|
||||
Console.WriteLine("Song canceled");
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception in PlaySong: {ex}");
|
||||
}
|
||||
OnCompleted(this, curSong);
|
||||
curSong = CurrentSong; //to check if its null now
|
||||
if (curSong != null)
|
||||
if (RepeatSong)
|
||||
playlist.Insert(0, curSong);
|
||||
else if (RepeatPlaylist)
|
||||
playlist.Insert(playlist.Count, curSong);
|
||||
SongCancelSource = new CancellationTokenSource();
|
||||
cancelToken = SongCancelSource.Token;
|
||||
}
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Action queue crashed");
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var t = new Thread(new ThreadStart(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!Destroyed)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (audioClient.State != ConnectionState.Connected)
|
||||
{
|
||||
audioClient = await PlaybackVoiceChannel.JoinAudio();
|
||||
continue;
|
||||
}
|
||||
|
||||
var song = CurrentSong;
|
||||
|
||||
if (song == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
await song.Play(audioClient, cancelToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Console.WriteLine("Song canceled");
|
||||
SongCancelSource = new CancellationTokenSource();
|
||||
cancelToken = SongCancelSource.Token;
|
||||
}
|
||||
OnCompleted(this, song);
|
||||
|
||||
if (RepeatPlaylist)
|
||||
AddSong(song, song.QueuerName);
|
||||
|
||||
if (RepeatSong)
|
||||
AddSong(song, 0);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await Task.Delay(300).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Console.WriteLine("Music thread crashed.");
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}));
|
||||
|
||||
t.Start();
|
||||
}
|
||||
|
||||
public void Next()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
{
|
||||
Paused = false;
|
||||
SongCancelSource.Cancel();
|
||||
}
|
||||
}
|
||||
Paused = false;
|
||||
SongCancelSource.Cancel();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Clear();
|
||||
CurrentSong = null;
|
||||
@ -132,19 +163,11 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
RepeatSong = false;
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
SongCancelSource.Cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void TogglePause() => Paused = !Paused;
|
||||
|
||||
public void Shuffle()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
playlist.Shuffle();
|
||||
}
|
||||
}
|
||||
|
||||
public int SetVolume(int volume)
|
||||
{
|
||||
if (volume < 0)
|
||||
@ -156,16 +179,15 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
return volume;
|
||||
}
|
||||
|
||||
private Song GetNextSong()
|
||||
private Song GetNextSong() =>
|
||||
playlist.FirstOrDefault();
|
||||
|
||||
public void Shuffle()
|
||||
{
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
if (playlist.Count == 0)
|
||||
return null;
|
||||
var toReturn = playlist[0];
|
||||
playlist.RemoveAt(0);
|
||||
return toReturn;
|
||||
}
|
||||
playlist.Shuffle();
|
||||
});
|
||||
}
|
||||
|
||||
public void AddSong(Song s, string username)
|
||||
@ -173,42 +195,63 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
if (s == null)
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
ThrowIfQueueFull();
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
s.MusicPlayer = this;
|
||||
s.QueuerName = username.TrimTo(10);
|
||||
playlist.Add(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void AddSong(Song s, int index)
|
||||
{
|
||||
if (s == null)
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Insert(index, s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveSong(Song s)
|
||||
{
|
||||
if (s == null)
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Remove(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveSongAt(int index)
|
||||
{
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
if (index < 0 || index >= playlist.Count)
|
||||
throw new ArgumentException("Invalid index");
|
||||
return;
|
||||
playlist.RemoveAt(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
internal void ClearQueue()
|
||||
{
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Clear();
|
||||
Destroyed = true;
|
||||
CurrentSong = null;
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
SongCancelSource.Cancel();
|
||||
audioClient.Disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
internal Task MoveToVoiceChannel(Channel voiceChannel)
|
||||
@ -219,27 +262,6 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
return PlaybackVoiceChannel.JoinAudio();
|
||||
}
|
||||
|
||||
internal void ClearQueue()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
playlist.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
playlist.Clear();
|
||||
Destroyed = true;
|
||||
CurrentSong = null;
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
SongCancelSource.Cancel();
|
||||
audioClient.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong;
|
||||
|
||||
internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist;
|
||||
|
Loading…
Reference in New Issue
Block a user