Lot more work, fixes, addition, untested new implementations...
This commit is contained in:
parent
9889baf8bd
commit
3731994061
@ -48,7 +48,7 @@ namespace NadekoBot.DataStructures
|
|||||||
|
|
||||||
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
|
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
public PoopyRingBuffer(int capacity = 38400)
|
public PoopyRingBuffer(int capacity = 3640 * 200)
|
||||||
{
|
{
|
||||||
this.Capacity = capacity + 1;
|
this.Capacity = capacity + 1;
|
||||||
this.buffer = new byte[this.Capacity];
|
this.buffer = new byte[this.Capacity];
|
||||||
|
@ -111,11 +111,15 @@ namespace NadekoBot.Modules.Music
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//todo add play command. .play = .n, .play whatever = .q whatever
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task Queue([Remainder] string query)
|
public async Task Queue([Remainder] string query)
|
||||||
{
|
{
|
||||||
|
//todo add a notice that player is stopped if user queues a song while it is
|
||||||
var mp = await _music.GetOrCreatePlayer(Context);
|
var mp = await _music.GetOrCreatePlayer(Context);
|
||||||
var songInfo = await _music.ResolveSong(query, Context.User.ToString());
|
var songInfo = await _music.ResolveSong(query, Context.User.ToString());
|
||||||
await InternalQueue(mp, songInfo, false);
|
await InternalQueue(mp, songInfo, false);
|
||||||
@ -209,11 +213,9 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
if (mp.RepeatCurrentSong)
|
if (mp.RepeatCurrentSong)
|
||||||
desc = "🔂 " + GetText("repeating_cur_song") + "\n\n" + desc;
|
desc = "🔂 " + GetText("repeating_cur_song") + "\n\n" + desc;
|
||||||
//else if (musicPlayer.RepeatPlaylist)
|
else if (mp.Shuffle)
|
||||||
// desc = "🔁 " + GetText("repeating_playlist") + "\n\n" + desc;
|
desc = "🔀 " + GetText("shuffling_playlist") + "\n\n" + desc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = new EmbedBuilder()
|
||||||
.WithAuthor(eab => eab.WithName(GetText("player_queue", curPage + 1, lastPage + 1))
|
.WithAuthor(eab => eab.WithName(GetText("player_queue", curPage + 1, lastPage + 1))
|
||||||
.WithMusicIcon())
|
.WithMusicIcon())
|
||||||
@ -307,7 +309,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
{
|
{
|
||||||
var song = mp.RemoveAt(index - 1);
|
var song = mp.RemoveAt(index - 1);
|
||||||
var embed = new EmbedBuilder()
|
var embed = new EmbedBuilder()
|
||||||
.WithAuthor(eab => eab.WithName(GetText("removed_song") + " #" + (index + 1)).WithMusicIcon())
|
.WithAuthor(eab => eab.WithName(GetText("removed_song") + " #" + (index)).WithMusicIcon())
|
||||||
.WithDescription(song.PrettyName)
|
.WithDescription(song.PrettyName)
|
||||||
.WithFooter(ef => ef.WithText(song.PrettyInfo))
|
.WithFooter(ef => ef.WithText(song.PrettyInfo))
|
||||||
.WithErrorColor();
|
.WithErrorColor();
|
||||||
@ -519,22 +521,18 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
//todo test shuffle
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
//public async Task ShufflePlaylist()
|
public async Task ShufflePlaylist()
|
||||||
//{
|
{
|
||||||
// MusicPlayer musicPlayer;
|
var mp = await _music.GetOrCreatePlayer(Context);
|
||||||
// if ((musicPlayer = _music.GetPlayer(Context.Guild.Id)) == null)
|
var val = mp.ToggleShuffle();
|
||||||
// return;
|
if(val)
|
||||||
// if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
await ReplyConfirmLocalized("songs_shuffle_enable").ConfigureAwait(false);
|
||||||
// return;
|
else
|
||||||
// if (musicPlayer.Playlist.Count < 2)
|
await ReplyConfirmLocalized("songs_shuffle_disable").ConfigureAwait(false);
|
||||||
// return;
|
}
|
||||||
|
|
||||||
// musicPlayer.Shuffle();
|
|
||||||
// await ReplyConfirmLocalized("songs_shuffled").ConfigureAwait(false);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
//[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
//[RequireContext(ContextType.Guild)]
|
||||||
@ -687,17 +685,22 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
//public async Task Move()
|
public async Task Move()
|
||||||
//{
|
{
|
||||||
|
var vch = ((IGuildUser)Context.User).VoiceChannel;
|
||||||
|
|
||||||
// MusicPlayer musicPlayer;
|
if (vch == null)
|
||||||
// var voiceChannel = ((IGuildUser)Context.User).VoiceChannel;
|
return;
|
||||||
// if (voiceChannel == null || voiceChannel.Guild != Context.Guild || !MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
|
|
||||||
// return;
|
var mp = _music.GetPlayerOrDefault(Context.Guild.Id);
|
||||||
// await musicPlayer.MoveToVoiceChannel(voiceChannel);
|
|
||||||
//}
|
if (mp == null)
|
||||||
|
return;
|
||||||
|
//todo test move
|
||||||
|
mp.SetVoiceChannel(vch);
|
||||||
|
}
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
//[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
//[RequireContext(ContextType.Guild)]
|
||||||
@ -745,21 +748,21 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
//public async Task SetMaxQueue(uint size = 0)
|
public async Task SetMaxQueue(uint size = 0)
|
||||||
//{
|
{
|
||||||
// MusicPlayer musicPlayer;
|
if (size < 0)
|
||||||
// if ((musicPlayer = _music.GetPlayer(Context.Guild.Id)) == null)
|
return;
|
||||||
// return;
|
var mp = await _music.GetOrCreatePlayer(Context);
|
||||||
|
|
||||||
// musicPlayer.MaxQueueSize = size;
|
mp.SetMaxQueueSize(size);
|
||||||
|
|
||||||
// if(size == 0)
|
if (size == 0)
|
||||||
// await ReplyConfirmLocalized("max_queue_unlimited").ConfigureAwait(false);
|
await ReplyConfirmLocalized("max_queue_unlimited").ConfigureAwait(false);
|
||||||
// else
|
else
|
||||||
// await ReplyConfirmLocalized("max_queue_x", size).ConfigureAwait(false);
|
await ReplyConfirmLocalized("max_queue_x", size).ConfigureAwait(false);
|
||||||
//}
|
}
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
//[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
//[RequireContext(ContextType.Guild)]
|
||||||
@ -800,19 +803,17 @@ namespace NadekoBot.Modules.Music
|
|||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
//public async Task RepeatPl()
|
public async Task RepeatPl()
|
||||||
//{
|
{
|
||||||
// MusicPlayer musicPlayer;
|
var mp = await _music.GetOrCreatePlayer(Context);
|
||||||
// if ((musicPlayer = _music.GetPlayer(Context.Guild.Id)) == null)
|
var currentValue = mp.ToggleRepeatPlaylist();
|
||||||
// return;
|
if (currentValue)
|
||||||
// var currentValue = musicPlayer.ToggleRepeatPlaylist();
|
await ReplyConfirmLocalized("rpl_enabled").ConfigureAwait(false);
|
||||||
// if(currentValue)
|
else
|
||||||
// await ReplyConfirmLocalized("rpl_enabled").ConfigureAwait(false);
|
await ReplyConfirmLocalized("rpl_disabled").ConfigureAwait(false);
|
||||||
// else
|
}
|
||||||
// await ReplyConfirmLocalized("rpl_disabled").ConfigureAwait(false);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
//[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
//[RequireContext(ContextType.Guild)]
|
||||||
@ -849,19 +850,17 @@ namespace NadekoBot.Modules.Music
|
|||||||
// await ReplyConfirmLocalized("skipped_to", minutes, seconds).ConfigureAwait(false);
|
// await ReplyConfirmLocalized("skipped_to", minutes, seconds).ConfigureAwait(false);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
//[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
//public async Task Autoplay()
|
public async Task Autoplay()
|
||||||
//{
|
{
|
||||||
// MusicPlayer musicPlayer;
|
var mp = await _music.GetOrCreatePlayer(Context);
|
||||||
// if ((musicPlayer = _music.GetPlayer(Context.Guild.Id)) == null)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// if (!musicPlayer.ToggleAutoplay())
|
if (!mp.ToggleAutoplay())
|
||||||
// await ReplyConfirmLocalized("autoplay_disabled").ConfigureAwait(false);
|
await ReplyConfirmLocalized("autoplay_disabled").ConfigureAwait(false);
|
||||||
// else
|
else
|
||||||
// await ReplyConfirmLocalized("autoplay_enabled").ConfigureAwait(false);
|
await ReplyConfirmLocalized("autoplay_enabled").ConfigureAwait(false);
|
||||||
//}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
@ -183,7 +183,7 @@ namespace NadekoBot
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var clashService = new ClashOfClansService(Client, Db, Localization, Strings, uow, startingGuildIdList);
|
var clashService = new ClashOfClansService(Client, Db, Localization, Strings, uow, startingGuildIdList);
|
||||||
var musicService = new MusicService(GoogleApi, Strings, Localization, Db, soundcloudApiService, Credentials, AllGuildConfigs);
|
var musicService = new MusicService(Client, GoogleApi, Strings, Localization, Db, soundcloudApiService, Credentials, AllGuildConfigs);
|
||||||
var crService = new CustomReactionsService(permissionsService, Db, Strings, Client, CommandHandler, BotConfig, uow);
|
var crService = new CustomReactionsService(permissionsService, Db, Strings, Client, CommandHandler, BotConfig, uow);
|
||||||
|
|
||||||
#region Games
|
#region Games
|
||||||
|
@ -18,7 +18,7 @@ namespace NadekoBot.Services.Music
|
|||||||
public class MusicPlayer
|
public class MusicPlayer
|
||||||
{
|
{
|
||||||
private readonly Task _player;
|
private readonly Task _player;
|
||||||
private readonly IVoiceChannel VoiceChannel;
|
private IVoiceChannel VoiceChannel { get; set; }
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
private MusicQueue Queue { get; } = new MusicQueue();
|
private MusicQueue Queue { get; } = new MusicQueue();
|
||||||
@ -42,9 +42,13 @@ namespace NadekoBot.Services.Music
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool RepeatCurrentSong { get; private set; }
|
public bool RepeatCurrentSong { get; private set; }
|
||||||
|
public bool Shuffle { get; private set; }
|
||||||
|
public bool Autoplay { get; private set; }
|
||||||
|
public bool RepeatPlaylist { get; private set; } = true;
|
||||||
|
|
||||||
private IAudioClient _audioClient;
|
private IAudioClient _audioClient;
|
||||||
private readonly object locker = new object();
|
private readonly object locker = new object();
|
||||||
|
private MusicService _musicService;
|
||||||
|
|
||||||
#region events
|
#region events
|
||||||
public event Action<MusicPlayer, SongInfo> OnStarted;
|
public event Action<MusicPlayer, SongInfo> OnStarted;
|
||||||
@ -59,6 +63,7 @@ namespace NadekoBot.Services.Music
|
|||||||
this.VoiceChannel = vch;
|
this.VoiceChannel = vch;
|
||||||
this.SongCancelSource = new CancellationTokenSource();
|
this.SongCancelSource = new CancellationTokenSource();
|
||||||
this.OutputTextChannel = output;
|
this.OutputTextChannel = output;
|
||||||
|
this._musicService = musicService;
|
||||||
|
|
||||||
_player = Task.Run(async () =>
|
_player = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@ -96,42 +101,43 @@ namespace NadekoBot.Services.Music
|
|||||||
// i don't want to spam connection attempts
|
// i don't want to spam connection attempts
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var pcm = ac.CreatePCMStream(AudioApplication.Music);
|
using (var pcm = ac.CreatePCMStream(AudioApplication.Music))
|
||||||
|
|
||||||
OnStarted?.Invoke(this, data.Song);
|
|
||||||
|
|
||||||
byte[] buffer = new byte[3840];
|
|
||||||
int bytesRead = 0;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
while ((bytesRead = await b.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false)) > 0)
|
OnStarted?.Invoke(this, data.Song);
|
||||||
|
|
||||||
|
byte[] buffer = new byte[3840];
|
||||||
|
int bytesRead = 0;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var vol = Volume;
|
while ((bytesRead = await b.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false)) > 0)
|
||||||
if (vol != 1)
|
{
|
||||||
AdjustVolume(buffer, vol);
|
var vol = Volume;
|
||||||
await Task.WhenAll(Task.Delay(10), pcm.WriteAsync(buffer, 0, bytesRead, cancelToken)).ConfigureAwait(false);
|
if (vol != 1)
|
||||||
|
AdjustVolume(buffer, vol);
|
||||||
|
await Task.WhenAll(Task.Delay(10), pcm.WriteAsync(buffer, 0, bytesRead, cancelToken)).ConfigureAwait(false);
|
||||||
|
|
||||||
await (pauseTaskSource?.Task ?? Task.CompletedTask);
|
await (pauseTaskSource?.Task ?? Task.CompletedTask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (OperationCanceledException)
|
||||||
catch (OperationCanceledException)
|
{
|
||||||
{
|
_log.Info("Song Canceled");
|
||||||
_log.Info("Song Canceled");
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
catch (Exception ex)
|
{
|
||||||
{
|
_log.Warn(ex);
|
||||||
_log.Warn(ex);
|
}
|
||||||
}
|
finally
|
||||||
finally
|
{
|
||||||
{
|
//flush is known to get stuck from time to time, just cancel it if it takes more than 1 second
|
||||||
//flush is known to get stuck from time to time, just cancel it if it takes more than 1 second
|
var flushCancel = new CancellationTokenSource();
|
||||||
var flushCancel = new CancellationTokenSource();
|
var flushToken = flushCancel.Token;
|
||||||
var flushToken = flushCancel.Token;
|
var flushDelay = Task.Delay(1000, flushToken);
|
||||||
var flushDelay = Task.Delay(1000, flushToken);
|
await Task.WhenAny(flushDelay, pcm.FlushAsync(flushToken));
|
||||||
await Task.WhenAny(flushDelay, pcm.FlushAsync(flushToken));
|
flushCancel.Cancel();
|
||||||
flushCancel.Cancel();
|
|
||||||
|
|
||||||
OnCompleted?.Invoke(this, data.Song);
|
OnCompleted?.Invoke(this, data.Song);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,8 +149,35 @@ namespace NadekoBot.Services.Music
|
|||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
while (Stopped && !Exited);
|
while (Stopped && !Exited);
|
||||||
if(!RepeatCurrentSong)
|
if (!RepeatCurrentSong) //if repeating current song, just ignore other settings, and play this song again (don't change the index)
|
||||||
Queue.Next();
|
{
|
||||||
|
if (Shuffle)
|
||||||
|
Queue.Random(); //if shuffle is set, set current song index to a random number
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if last song, and autoplay is enabled, and if it's a youtube song
|
||||||
|
// do autplay magix
|
||||||
|
if (Queue.Count == data.Index && Autoplay && data.Song?.Provider == "YouTube")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//todo test autoplay
|
||||||
|
await _musicService.TryQueueRelatedSongAsync(data.Song.Query, OutputTextChannel, VoiceChannel);
|
||||||
|
Queue.Next();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
else if (Queue.Count == data.Index && !RepeatPlaylist)
|
||||||
|
{
|
||||||
|
//todo test repeatplaylist
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Queue.Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, SongCancelSource.Token);
|
}, SongCancelSource.Token);
|
||||||
@ -313,6 +346,41 @@ namespace NadekoBot.Services.Music
|
|||||||
await ac.StopAsync();
|
await ac.StopAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ToggleShuffle()
|
||||||
|
{
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
return Shuffle = !Shuffle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ToggleAutoplay()
|
||||||
|
{
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
return Autoplay = !Autoplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ToggleRepeatPlaylist()
|
||||||
|
{
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
return RepeatPlaylist = !RepeatPlaylist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMaxQueueSize(uint size)
|
||||||
|
{
|
||||||
|
Queue.SetMaxQueueSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetVoiceChannel(IVoiceChannel vch)
|
||||||
|
{
|
||||||
|
VoiceChannel = vch;
|
||||||
|
Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//private IAudioClient AudioClient { get; set; }
|
//private IAudioClient AudioClient { get; set; }
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using NadekoBot.Extensions;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -49,17 +50,23 @@ namespace NadekoBot.Services.Music
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint maxQueueSize { get; private set; }
|
||||||
|
|
||||||
public void Add(SongInfo song)
|
public void Add(SongInfo song)
|
||||||
{
|
{
|
||||||
|
song.ThrowIfNull(nameof(song));
|
||||||
lock (locker)
|
lock (locker)
|
||||||
{
|
{
|
||||||
|
if(CurrentIndex >= maxQueueSize)
|
||||||
|
throw new PlaylistFullException();
|
||||||
Songs.AddLast(song);
|
Songs.AddLast(song);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Next()
|
public void Next()
|
||||||
{
|
{
|
||||||
CurrentIndex++;
|
lock(locker)
|
||||||
|
CurrentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@ -118,5 +125,24 @@ namespace NadekoBot.Services.Music
|
|||||||
CurrentIndex = 0;
|
CurrentIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Random()
|
||||||
|
{
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
CurrentIndex = new NadekoRandom().Next(Songs.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMaxQueueSize(uint size)
|
||||||
|
{
|
||||||
|
if (size < 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(size));
|
||||||
|
|
||||||
|
lock (locker)
|
||||||
|
{
|
||||||
|
maxQueueSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ using System.IO;
|
|||||||
using VideoLibrary;
|
using VideoLibrary;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
namespace NadekoBot.Services.Music
|
namespace NadekoBot.Services.Music
|
||||||
{
|
{
|
||||||
@ -25,13 +26,15 @@ namespace NadekoBot.Services.Music
|
|||||||
private readonly SoundCloudApiService _sc;
|
private readonly SoundCloudApiService _sc;
|
||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly ConcurrentDictionary<ulong, float> _defaultVolumes;
|
private readonly ConcurrentDictionary<ulong, float> _defaultVolumes;
|
||||||
|
private readonly DiscordSocketClient _client;
|
||||||
|
|
||||||
public ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers { get; } = new ConcurrentDictionary<ulong, MusicPlayer>();
|
public ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers { get; } = new ConcurrentDictionary<ulong, MusicPlayer>();
|
||||||
|
|
||||||
public MusicService(IGoogleApiService google,
|
public MusicService(DiscordSocketClient client, IGoogleApiService google,
|
||||||
NadekoStrings strings, ILocalization localization, DbService db,
|
NadekoStrings strings, ILocalization localization, DbService db,
|
||||||
SoundCloudApiService sc, IBotCredentials creds, IEnumerable<GuildConfig> gcs)
|
SoundCloudApiService sc, IBotCredentials creds, IEnumerable<GuildConfig> gcs)
|
||||||
{
|
{
|
||||||
|
_client = client;
|
||||||
_google = google;
|
_google = google;
|
||||||
_strings = strings;
|
_strings = strings;
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
@ -187,6 +190,25 @@ namespace NadekoBot.Services.Music
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MusicPlayer GetPlayerOrDefault(ulong guildId)
|
||||||
|
{
|
||||||
|
if (MusicPlayers.TryGetValue(guildId, out var mp))
|
||||||
|
return mp;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task TryQueueRelatedSongAsync(string query, ITextChannel txtCh, IVoiceChannel vch)
|
||||||
|
{
|
||||||
|
var related = (await _google.GetRelatedVideosAsync(query, 4)).ToArray();
|
||||||
|
if (!related.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var si = await ResolveSong(related[new NadekoRandom().Next(related.Length)], _client.CurrentUser.ToString(), MusicType.Normal);
|
||||||
|
var mp = await GetOrCreatePlayer(txtCh.GuildId, vch, txtCh);
|
||||||
|
mp.Enqueue(si);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<SongInfo> ResolveSong(string query, string queuerName, MusicType musicType = MusicType.Normal)
|
public async Task<SongInfo> ResolveSong(string query, string queuerName, MusicType musicType = MusicType.Normal)
|
||||||
{
|
{
|
||||||
query.ThrowIfNull(nameof(query));
|
query.ThrowIfNull(nameof(query));
|
||||||
|
@ -24,7 +24,7 @@ namespace NadekoBot.Services.Music
|
|||||||
this.p = Process.Start(new ProcessStartInfo
|
this.p = Process.Start(new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = "ffmpeg",
|
FileName = "ffmpeg",
|
||||||
Arguments = $"-i {songUri} -f s16le -ar 48000 -vn -ac 2 pipe:1 -loglevel quiet",
|
Arguments = $"-i {songUri} -f s16le -ar 48000 -vn -b:a 128k -ac 2 pipe:1 -loglevel quiet -nostdin",
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
RedirectStandardOutput = true,
|
RedirectStandardOutput = true,
|
||||||
RedirectStandardError = false,
|
RedirectStandardError = false,
|
||||||
|
@ -4,6 +4,7 @@ using NadekoBot.Services.Database.Models;
|
|||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace NadekoBot.Services.Music
|
namespace NadekoBot.Services.Music
|
||||||
{
|
{
|
||||||
|
@ -442,12 +442,14 @@
|
|||||||
"music_repeating_playlist": "Repeating playlist",
|
"music_repeating_playlist": "Repeating playlist",
|
||||||
"music_repeating_track": "Repeating track",
|
"music_repeating_track": "Repeating track",
|
||||||
"music_repeating_track_stopped": "Current track repeat stopped.",
|
"music_repeating_track_stopped": "Current track repeat stopped.",
|
||||||
|
"music_shuffling_playlist": "Shuffling songs",
|
||||||
"music_resumed": "Music playback resumed.",
|
"music_resumed": "Music playback resumed.",
|
||||||
"music_rpl_disabled": "Repeat playlist disabled.",
|
"music_rpl_disabled": "Repeat playlist disabled.",
|
||||||
"music_rpl_enabled": "Repeat playlist enabled.",
|
"music_rpl_enabled": "Repeat playlist enabled.",
|
||||||
"music_set_music_channel": "I will now output playing, finished, paused and removed songs in this channel.",
|
"music_set_music_channel": "I will now output playing, finished, paused and removed songs in this channel.",
|
||||||
"music_skipped_to": "Skipped to `{0}:{1}`",
|
"music_skipped_to": "Skipped to `{0}:{1}`",
|
||||||
"music_songs_shuffled": "Songs shuffled",
|
"music_songs_shuffle_enable": "Songs will shuffle from now on.",
|
||||||
|
"music_songs_shuffle_disable": "Songs will no longer shuffle.",
|
||||||
"music_song_moved": "Song moved",
|
"music_song_moved": "Song moved",
|
||||||
"music_song_not_found": "No song found.",
|
"music_song_not_found": "No song found.",
|
||||||
"music_time_format": "{0}h {1}m {2}s",
|
"music_time_format": "{0}h {1}m {2}s",
|
||||||
|
Loading…
Reference in New Issue
Block a user