Exemple #1
0
        public StreamTask(DiscordClient client, StreamRequest streamRequest, Stream bufferingStream)
        {
            this.streamRequest   = streamRequest;
            this.bufferingStream = bufferingStream;
            this.client          = client;

            State = StreamTaskState.Queued;
        }
Exemple #2
0
        public void CancelStreaming()
        {
            if (State != StreamTaskState.Queued && State != StreamTaskState.Playing)
            {
                return;
            }

            tokenSource?.Cancel(false);
            audioTask?.Wait();
            State = StreamTaskState.Completed;
        }
Exemple #3
0
        public void StartStreaming()
        {
            if (State != StreamTaskState.Queued)
            {
                return;
            }

            State       = StreamTaskState.Playing;
            tokenSource = new CancellationTokenSource();
            audioTask   = Task.Run(StreamFunc, tokenSource.Token);
        }
Exemple #4
0
        async Task StreamFunc()
        {
            CancellationToken cancellationToken = tokenSource.Token;
            IAudioClient      voiceClient       = null;
            TranscodingTask   streamer          = null;

            try {
                uint byteCounter = 0;

                // Download and read audio from the url
                streamer = new TranscodingTask(streamRequest, bufferingStream);
                streamer.Start();

                // Wait until we have at least a few kb transcoded or network stream done
                while (true)
                {
                    if (streamRequest.NetworkDone)
                    {
                        await Task.Delay(600);

                        break;
                    }
                    if (streamer.ReadyBytesLeft > 5 * 1024)
                    {
                        break;
                    }
                    await Task.Delay(200);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                // Start streaming to voice
                await streamRequest.Channel.SendMessage($"Playing **{streamRequest.Title}** [{streamRequest.Length}]");

                var audioService = client.Audio();
                voiceClient = await audioService.Join(streamRequest.VoiceChannel);

                int    blockSize   = 1920 * audioService.Config.Channels;
                byte[] voiceBuffer = new byte[blockSize];
                var    ringBuffer  = streamer.PCMOutput;

                Stopwatch timeout = Stopwatch.StartNew();
                while (true)
                {
                    var readCount = ringBuffer.Read(voiceBuffer, 0, voiceBuffer.Length);

                    if (readCount == 0)
                    {
                        if (timeout.ElapsedMilliseconds > 1500)
                        {
                            Console.WriteLine("Audio stream timed out. Disconnecting.");
                            break;
                        }

                        await Task.Delay(200);

                        continue;
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    timeout.Restart();

                    byteCounter += (uint)voiceBuffer.Length;
                    voiceClient.Send(voiceBuffer, 0, voiceBuffer.Length);
                }

                streamer.Cancel();

                voiceClient.Wait();
            } catch (Exception ex) {
                await streamRequest.Channel.SendMessage($":musical_note: {streamRequest.User.Mention} Something went wrong, please report this. :angry: :anger:");

                Console.WriteLine("Exception while playing music: " + ex);
            } finally {
                if (voiceClient != null)
                {
                    await streamRequest.Channel.SendMessage($"Finished playing **{streamRequest.Title}**");

                    State = StreamTaskState.Completed;
                    streamer?.Cancel();
                    await voiceClient.Disconnect();

                    await Task.Delay(500);
                }
            }
        }