示例#1
0
        private void SendAudioData(IAudioClient audioClient, PlayRequest request)
        {
            try
            {
                var file = request.File;
                var cancellationToken = request.TokenSource.Token;

                using (var reader = File.OpenRead(file))
                {
                    byte[] buffer = new byte[BLOCK_SIZE];
                    int    byteCount;

                    while ((byteCount = reader.Read(buffer, 0, BLOCK_SIZE)) > 0)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            audioClient.Clear();
                            return;
                        }

                        audioClient.Send(buffer, 0, byteCount);
                    }
                }

                audioClient.Wait();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message, ex);
            }
        }
示例#2
0
        private async Task SendSound(string song)
        {
            if (!_playing)
            {
                _vclient = await _client.GetService <AudioService>().Join(channel);

                _playing = true;
            }
            _skipThis = false;
            await Task.Run(() =>
            {
                int channelCount     = _client.GetService <AudioService>().Config.Channels;
                WaveFormat outFormat = new WaveFormat(48000, 16, channelCount);
                AudioFileReader r    = new AudioFileReader(song);
                using (MediaFoundationResampler resampler = new MediaFoundationResampler(r, outFormat))
                {
                    resampler.ResamplerQuality = 60;
                    int blockSize = outFormat.AverageBytesPerSecond / 50;
                    byte[] buffer = new byte[blockSize];
                    int byteCount;

                    while ((byteCount = resampler.Read(buffer, 0, blockSize)) > 0 && _playing == true)
                    {
                        r.Volume = volume;
                        if (byteCount < blockSize)
                        {
                            // Incomplete Frame
                            for (int i = byteCount; i < blockSize; i++)
                            {
                                buffer[i] = 0;
                                if (_skipThis)
                                {
                                    _vclient.Clear();
                                    break;
                                }
                            }
                        }
                        _vclient.Send(buffer, 0, blockSize);
                        _vclient.Wait();
                    }

                    GetNextSong();
                }
            });
        }
示例#3
0
文件: Song.cs 项目: neerh/NadekoBot
        internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
        {
            var       bufferTask     = BufferSong(cancelToken).ConfigureAwait(false);
            var       bufferAttempts = 0;
            const int waitPerAttempt = 500;
            var       toAttemptTimes = SongInfo.ProviderType != MusicType.Normal ? 5 : 9;

            while (!prebufferingComplete && bufferAttempts++ < toAttemptTimes)
            {
                await Task.Delay(waitPerAttempt, cancelToken).ConfigureAwait(false);
            }
            cancelToken.ThrowIfCancellationRequested();
            Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}");
            const int blockSize = 3840;
            var       attempt   = 0;

            while (!cancelToken.IsCancellationRequested)
            {
                //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
                byte[] buffer = new byte[blockSize];
                var    read   = songBuffer.Read(buffer, blockSize);
                unchecked
                {
                    bytesSent += (ulong)read;
                }
                if (read == 0)
                {
                    if (attempt++ == 20)
                    {
                        voiceClient.Wait();
                        Console.WriteLine($"Song finished. [{songBuffer.ContentLength}]");
                        break;
                    }
                    else
                    {
                        await Task.Delay(100, cancelToken).ConfigureAwait(false);
                    }
                }
                else
                {
                    attempt = 0;
                }

                while (this.MusicPlayer.Paused)
                {
                    await Task.Delay(200, cancelToken).ConfigureAwait(false);
                }
                buffer = AdjustVolume(buffer, MusicPlayer.Volume);
                voiceClient.Send(buffer, 0, read);
            }
            Console.WriteLine("Awiting buffer task");
            await bufferTask;

            Console.WriteLine("Buffer task done.");
            voiceClient.Clear();
            cancelToken.ThrowIfCancellationRequested();
        }
示例#4
0
        internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
        {
            var filename = Path.Combine(MusicModule.MusicDataPath, DateTime.Now.UnixTimestamp().ToString());

            SongBuffer sb         = new SongBuffer(filename, SongInfo, skipTo);
            var        bufferTask = sb.BufferSong(cancelToken).ConfigureAwait(false);

            var inStream = new FileStream(sb.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write);;

            bytesSent = 0;

            try
            {
                var attempt = 0;

                var prebufferingTask = CheckPrebufferingAsync(inStream, sb, cancelToken);
                var sw = new Stopwatch();
                sw.Start();
                var t = await Task.WhenAny(prebufferingTask, Task.Delay(5000, cancelToken));

                if (t != prebufferingTask)
                {
                    Console.WriteLine("Prebuffering timed out or canceled. Cannot get any data from the stream.");
                    return;
                }
                else if (prebufferingTask.IsCanceled)
                {
                    Console.WriteLine("Prebuffering timed out. Cannot get any data from the stream.");
                    return;
                }
                sw.Stop();
                Console.WriteLine("Prebuffering successfully completed in " + sw.Elapsed);

                const int blockSize = 3840;
                byte[]    buffer    = new byte[blockSize];
                while (!cancelToken.IsCancellationRequested)
                {
                    //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
                    var read = inStream.Read(buffer, 0, buffer.Length);
                    //await inStream.CopyToAsync(voiceClient.OutputStream);
                    unchecked
                    {
                        bytesSent += (ulong)read;
                    }
                    if (read < blockSize)
                    {
                        if (sb.IsNextFileReady())
                        {
                            inStream.Dispose();
                            inStream = new FileStream(sb.GetNextFile(), FileMode.Open, FileAccess.Read, FileShare.Write);
                            read    += inStream.Read(buffer, read, buffer.Length - read);
                            attempt  = 0;
                        }
                        if (read == 0)
                        {
                            if (sb.BufferingCompleted)
                            {
                                break;
                            }
                            if (attempt++ == 20)
                            {
                                voiceClient.Wait();
                                MusicPlayer.SongCancelSource.Cancel();
                                break;
                            }
                            else
                            {
                                await Task.Delay(100, cancelToken).ConfigureAwait(false);
                            }
                        }
                        else
                        {
                            attempt = 0;
                        }
                    }
                    else
                    {
                        attempt = 0;
                    }

                    while (this.MusicPlayer.Paused)
                    {
                        await Task.Delay(200, cancelToken).ConfigureAwait(false);
                    }

                    buffer = AdjustVolume(buffer, MusicPlayer.Volume);
                    voiceClient.Send(buffer, 0, read);
                }
            }
            finally
            {
                await bufferTask;
                await Task.Run(() => voiceClient.Clear());

                if (inStream != null)
                {
                    inStream.Dispose();
                }
                Console.WriteLine("l");
                sb.CleanFiles();
            }
        }
示例#5
0
        internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
        {
            var bufferTask = BufferSong(cancelToken).ConfigureAwait(false);
            var bufferAttempts = 0;
            const int waitPerAttempt = 500;
            var toAttemptTimes = SongInfo.ProviderType != MusicType.Normal ? 5 : 9;
            while (!prebufferingComplete && bufferAttempts++ < toAttemptTimes)
            {
                await Task.Delay(waitPerAttempt, cancelToken);
            }
            cancelToken.ThrowIfCancellationRequested();
            Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}");
            const int blockSize = 3840;
            var attempt = 0;
            while (!cancelToken.IsCancellationRequested)
            {
                //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
                byte[] buffer = new byte[blockSize];
                var read = songBuffer.Read(buffer, blockSize);
                unchecked
                {
                    bytesSent += (ulong)read;
                }
                if (read == 0)
                    if (attempt++ == 20)
                    {
                        voiceClient.Wait();
                        Console.WriteLine($"Song finished. [{songBuffer.ContentLength}]");
                        break;
                    }
                    else
                        await Task.Delay(100, cancelToken);
                else
                    attempt = 0;

                while (this.MusicPlayer.Paused)
                    await Task.Delay(200, cancelToken);
                buffer = AdjustVolume(buffer, MusicPlayer.Volume);
                voiceClient.Send(buffer, 0, read);
            }
            Console.WriteLine("Awiting buffer task");
            await bufferTask;
            Console.WriteLine("Buffer task done.");
            voiceClient.Clear();
            cancelToken.ThrowIfCancellationRequested();
        }
示例#6
0
        internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
        {
            var bufferTask = new ConfiguredTaskAwaitable();

            try {
                bufferTask = BufferSong(cancelToken).ConfigureAwait(false);
            }
            catch (Exception ex) {
                var clr = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"ERR BUFFER START : {ex.Message}\n{ex}");
                Console.ForegroundColor = clr;
            }
            var       bufferAttempts = 0;
            const int waitPerAttempt = 500;
            var       toAttemptTimes = SongInfo.ProviderType != MusicType.Normal ? 5 : 9;

            while (!prebufferingComplete && bufferAttempts++ < toAttemptTimes)
            {
                await Task.Delay(waitPerAttempt, cancelToken);
            }
            cancelToken.ThrowIfCancellationRequested();
            Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}");
            const int blockSize = 3840;
            var       attempt   = 0;

            while (!cancelToken.IsCancellationRequested)
            {
                //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
                byte[] buffer = new byte[blockSize];
                var    read   = songBuffer.Read(buffer, blockSize);
                if (read == 0)
                {
                    if (attempt++ == 20)
                    {
                        Console.WriteLine("Waiting to empty out buffer.");
                        voiceClient.Wait();
                        Console.WriteLine($"Song finished. [{songBuffer.ContentLength}]");
                        break;
                    }
                    else
                    {
                        await Task.Delay(100, cancelToken);
                    }
                }
                else
                {
                    attempt = 0;
                }

                while (this.MusicPlayer.Paused)
                {
                    await Task.Delay(200, cancelToken);
                }
                buffer = AdjustVolume(buffer, MusicPlayer.Volume);
                voiceClient.Send(buffer, 0, read);
            }
            await bufferTask;

            voiceClient.Clear();
            cancelToken.ThrowIfCancellationRequested();
        }
示例#7
0
文件: Song.cs 项目: Ryonez/Lucy
        internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
        {
            var filename = Path.Combine(MusicModule.MusicDataPath, DateTime.Now.UnixTimestamp().ToString());

            SongBuffer sb = new SongBuffer(filename, SongInfo, skipTo);
            var bufferTask = sb.BufferSong(cancelToken).ConfigureAwait(false);

            var inStream = new FileStream(sb.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); ;

            bytesSent = 0;

            try
            {
                var attempt = 0;             

                var prebufferingTask = CheckPrebufferingAsync(inStream, sb, cancelToken);
                var sw = new Stopwatch();
                sw.Start();
                var t = await Task.WhenAny(prebufferingTask, Task.Delay(5000, cancelToken));
                if (t != prebufferingTask)
                {
                    Console.WriteLine("Prebuffering timed out or canceled. Cannot get any data from the stream.");
                    return;
                }
                else if(prebufferingTask.IsCanceled)
                {
                    Console.WriteLine("Prebuffering timed out. Cannot get any data from the stream.");
                    return;
                }
                sw.Stop();
                Console.WriteLine("Prebuffering successfully completed in "+ sw.Elapsed);

                const int blockSize = 3840;
                byte[] buffer = new byte[blockSize];
                while (!cancelToken.IsCancellationRequested)
                {
                    //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------");
                    var read = inStream.Read(buffer, 0, buffer.Length);
                    //await inStream.CopyToAsync(voiceClient.OutputStream);
                    unchecked
                    {
                        bytesSent += (ulong)read;
                    }
                    if (read < blockSize)
                    {
                        if (sb.IsNextFileReady())
                        {
                            inStream.Dispose();
                            inStream = new FileStream(sb.GetNextFile(), FileMode.Open, FileAccess.Read, FileShare.Write);
                            read += inStream.Read(buffer, read, buffer.Length - read);
                            attempt = 0;
                        }
                        if (read == 0)
                        {
                            if (sb.BufferingCompleted)
                                break;
                            if (attempt++ == 20)
                            {
                                voiceClient.Wait();
                                MusicPlayer.SongCancelSource.Cancel();
                                break;
                            }
                            else
                                await Task.Delay(100, cancelToken).ConfigureAwait(false);                         
                        }
                        else
                            attempt = 0;
                    }
                    else
                        attempt = 0;

                    while (this.MusicPlayer.Paused)
                        await Task.Delay(200, cancelToken).ConfigureAwait(false);

                    buffer = AdjustVolume(buffer, MusicPlayer.Volume);
                    voiceClient.Send(buffer, 0, read);
                }
            }
            finally
            {
                await bufferTask;
                await Task.Run(() => voiceClient.Clear());
                if(inStream != null)
                    inStream.Dispose();
                Console.WriteLine("l");
                sb.CleanFiles();
            }
        }
示例#8
0
        public void PlaySound(AudioService audioService, IAudioClient audioClient, TrackRequest trackRequest)
        {
            var channels   = audioService.Config.Channels;
            var timePlayed = 0;
            var outFormat  = new WaveFormat(48000, 16, channels);

            SetVolumeOfCurrentTrack(trackRequest.Volume);

            using (var audioFileStream = new MediaFoundationReader(trackRequest.Track.Path))
                using (var waveChannel32 = new WaveChannel32(audioFileStream, (_volumeOverride > 0 ? _volumeOverride : _volume) * 0.2f, 0f)
                {
                    PadWithZeroes = false
                })
                    using (var effectStream = new EffectStream(waveChannel32))
                        using (var blockAlignmentStream = new BlockAlignReductionStream(effectStream))
                            using (var resampler = new MediaFoundationResampler(blockAlignmentStream, outFormat)) {
                                resampler.ResamplerQuality = 60;
                                ApplyEffects(waveChannel32, effectStream, trackRequest);

                                // Establish the size of our AudioBuffer
                                var blockSize = outFormat.AverageBytesPerSecond / 50;
                                var buffer    = new byte[blockSize];
                                int byteCount;

                                // Read audio into our buffer, and keep a loop open while data is present
                                while ((byteCount = resampler.Read(buffer, 0, blockSize)) > 0)
                                {
                                    waveChannel32.Volume = (_volumeOverride > 0 ? _volumeOverride : _volume) * 0.2f;

                                    // Limit play length (--length)
                                    timePlayed += byteCount * 1000 / outFormat.AverageBytesPerSecond;
                                    if (trackRequest.TimeLimit > 0 && timePlayed > trackRequest.TimeLimit)
                                    {
                                        break;
                                    }

                                    if (byteCount < blockSize)
                                    {
                                        // Incomplete Frame
                                        for (var i = byteCount; i < blockSize; i++)
                                        {
                                            buffer[i] = 0;
                                        }
                                    }

                                    if (audioClient.State == ConnectionState.Disconnected || Stop)
                                    {
                                        break;
                                    }

                                    // Send the buffer to Discord
                                    try {
                                        audioClient.Send(buffer, 0, blockSize);
                                    } catch (Exception) {
                                        break;
                                    }
                                }
                                MyLogger.WriteLine("Voice finished enqueuing", ConsoleColor.Green);
                            }

            if (Stop)
            {
                audioClient.Clear();
                Stop = false;
            }

            audioClient.Wait();
        }
示例#9
0
        public async void SendOnlineAudio(CommandEventArgs e, string pathOrUrl)
        {
            try
            {
                await joinVoiceChannel(e);
            }
            catch (Exception ex)
            {
                Console.WriteLine("WARNING: Bot failed!");
                e.Channel.SendMessage("ERROR: Bot failed");
                return;
            }

            if (!isInSameVoice(e))
            {
                e.Channel.SendMessage("You are not in the same voice as me!");
                return;
            }

            YouTubeVideo ytVideo = new YouTubeVideo(pathOrUrl, e.User.Name);

            //Couldn't find a video so do not add
            if (ytVideo.title == "")
            {
                e.Channel.SendMessage("Could not find video!");
                return;
            }

            if (playingSong)
            {
                queue.Enqueue(ytVideo);
                sendMessage(ytVideo.requester + " added `" + ytVideo.title + "` **" + ytVideo.duration + "** to the queue! **[" + queue.Count + "]**");
                return;
            }

            currentSong = ytVideo;

            if (_vClient == null)
            {
                e.Channel.SendMessage("You are not in a voice channel!");
                return;
            }

            playingSong = true;
            sendMessage("Playing `" + currentSong.title + "` **" + currentSong.duration + "**");

            var process = Process.Start(new ProcessStartInfo
            {                                                                                                                                                                                           // FFmpeg requires us to spawn a process and hook into its stdout, so we will create a Process
                FileName               = "cmd.exe",
                Arguments              = "/C youtube-dl.exe -f 140  -o - " + pathOrUrl + " -q -i | ffmpeg.exe -i pipe:0 -f s16le -ar 48000 -ac 2 pipe:1 -af \"volume=" + volume + "\" -loglevel quiet", // Next, we tell it to output 16-bit 48000Hz PCM, over 2 channels, to stdout.
                UseShellExecute        = false,
                RedirectStandardOutput = true,                                                                                                                                                          // Capture the stdout of the process
                RedirectStandardError  = false,
            });

            //Thread.Sleep(1500); // Sleep for a few seconds to FFmpeg can start processing data.

            int blockSize = 3840; // The size of bytes to read per frame; 1920 for mono

            byte[] buffer = new byte[blockSize];
            int    byteCount;

            while (playingSong) // Loop forever, so data will always be read
            {
                if (!playingSong || process.HasExited)
                {
                    Console.WriteLine("task canceled");
                    break;
                }

                byteCount = process.StandardOutput.BaseStream // Access the underlying MemoryStream from the stdout of FFmpeg
                            .Read(buffer, 0, blockSize);      // Read stdout into the buffer


                if (byteCount == 0) // FFmpeg did not output anything
                {
                    break;          // Break out of the while(true) loop, since there was nothing to read.
                }
                try
                {
                    _vClient.Send(buffer, 0, byteCount); // Send our data to Discord
                }
                catch (OperationCanceledException ex)
                {
                    Console.WriteLine("Operation cancelled!");
                    break;
                }
            }

            _vClient.Clear();
            try {
                _vClient.Wait(); // Wait for the Voice Client to finish sending data, as ffMPEG may have already finished buffering out a song, and it is unsafe to return now.
            }catch (OperationCanceledException ex)
            {
                Console.WriteLine("Operation canceled");
            }
            if (!process.HasExited)
            {
                process.Kill();
                process.Dispose();
                Console.WriteLine("Killed process");
            }
            //set current votes to 0, if a vote was underway, but not enough voted to skip
            votes.Clear();

            playingSong = false;

            if (!queue.Any())
            {
                sendMessage("No songs in queue! Disconnecting...");
                leaveVoiceChannel();
                return;
            }

            string video = queue.First().url;

            queue.Dequeue();
            //Thread.Sleep(1000); //Sleep for a sec so it can stop music
            //Play next song
            //await Task.Run(() => SendOnlineAudio(e, video), ct);
            SendOnlineAudio(e, video);
        }