Discord의 Bot으로 음성 채널에 음악을 흘립니다.

18106 단어 C#디스코드
검색해도 좀처럼 나오지 않고 엄청 빠졌기 때문에 씁니다.
지금 유행의 Discord의 Bot을 엄청 쉽게 만들 수 있는 「Discord.Net」이라는 신 라이브러리가 있습니다만,
그것을 사용하여 음성 채널에 mp3를 흘리는 방법입니다.
Discord.Net의 기본 사항은 여기을 읽으면 이해하기 쉽습니다.

환경


  • Windows10
  • Visual Studio
  • Discord.Net

  • 절차


  • Discord.Net 및 Discord.Net.Audio를 Nuget으로 검색하고 넣습니다.

  • 필요한 두 개의 DLL을 넣습니다 (중요)
  • NAudio도 Nuget에서 넣습니다
  • 샘플 코드대로 쓴다

  • 또한 재생할 파일은 mp3입니다.

    참고



    Voice — Discord.Net 0.9.4 documentation

    여기에 모두 실려 있었다. 영어를 읽을 수 없었다 (소나미)

    DLL 다운로드



    Nuget을 사용하는 라이브러리는 좋다고 해서, 그것과는 별도로 exe 파일과 같은 장소(디버그중이라면 bin/DEBUG)에 넣어야 할 DLL이 2개 있습니다.
    ↓이미지

    ↑ 화살표의 링크를 클릭하고 GitHub의 다운로드 버튼을 눌러 다운로드합니다.
    DL 한 libsodium.dll"opus.dll"을 exe 파일과 같은 위치에 복사하십시오.

    코드



    Client가 Audio를 사용한다는 선언


    var _client = new DiscordClient();
    
    _client.UsingAudio(x => 
    {
            x.Mode = AudioMode.Outgoing;
    });
    

    이것을 사용하기 전에 어딘가에서 실행하십시오.

    음성 채널 참여(Join)


    var voiceClient = await _client.GetService<AudioService>().Join(voiceChannel);
    

    이 voiceClient를 사용하여 소리를 보냅니다. voiceChannel 는 예를 들어 MessageEventArgs의 .User.VoiceChannel 에 액세스하면 해당 사용자가 참여하는 음성 채널을 얻을 수 있습니다.
    예를 들어
    _client.MessageReceived += (s,e) => { var vc = e.User.VoiceChannel;};
    

    NAudio로 오디오 바이트 데이터 보내기



    조금 전의 페이지로부터의 인용입니다.
    using NAudio;
    using NAudio.Wave;
    using NAudio.CoreAudioApi;
    
    public void SendAudio(string filePath)
    {
            var channelCount = _client.GetService<AudioService>().Config.Channels; // Get the number of AudioChannels our AudioService has been configured to use.
            var OutFormat = new WaveFormat(48000, 16, channelCount); // Create a new Output Format, using the spec that Discord will accept, and with the number of channels that our client supports.
            using (var MP3Reader = new Mp3FileReader(filePath)) // Create a new Disposable MP3FileReader, to read audio from the filePath parameter
            using (var resampler = new MediaFoundationResampler(MP3Reader, OutFormat)) // Create a Disposable Resampler, which will convert the read MP3 data to PCM, using our Output Format
            {
                    resampler.ResamplerQuality = 60; // Set the quality of the resampler to 60, the highest quality
                    int blockSize = OutFormat.AverageBytesPerSecond / 50; // Establish the size of our AudioBuffer
                    byte[] buffer = new byte[blockSize];
                    int byteCount;
    
                    while((byteCount = resampler.Read(buffer, 0, blockSize)) > 0) // Read audio into our buffer, and keep a loop open while data is present
                    {
                            if (byteCount < blockSize)
                            {
                                    // Incomplete Frame
                                    for (int i = byteCount; i < blockSize; i++)
                                            buffer[i] = 0;
                            }
                            _vClient.Send(buffer, 0, blockSize); // Send the buffer to Discord
                    }
            }
    
    }
    

    NAudio에 대해서는 몰랐기 때문에 그대로 복사하여 사용했습니다.

    정리한 클래스


    using Discord;
    using Discord.Audio;
    using System;
    using System.Threading.Tasks;
    using NAudio.Wave;
    
    namespace SinobigamiBot
    {
        class VoiceSample
        {
            private DiscordClient Client { get; set; }
            public IAudioClient VoiceClient { get; set; }
    
            public VoiceSample(DiscordClient client)
            {
                Client = client;
            }
    
            /// <summary>
            /// これを呼び出して使う
            /// </summary>
            /// <returns></returns>
            public async Task SendAudio(Channel vChannel, string filepath)
            {
                await JoinChannel(vChannel);
                SendAudio(filepath);
            }
    
            private async Task JoinChannel(Channel vChannel)
            {
                VoiceClient = await Client.GetService<AudioService>().Join(vChannel);
    
            }
    
            private void SendAudio(string filepath)
            {
                if (!System.IO.File.Exists(filepath))
                    throw new Exception("not found!!!!" + filepath);
    
                var channelCount = Client.GetService<AudioService>().Config.Channels; // Get the number of AudioChannels our AudioService has been configured to use.
                var OutFormat = new WaveFormat(48000, 16, channelCount); // Create a new Output Format, using the spec that Discord will accept, and with the number of channels that our client supports.
                using (var MP3Reader = new Mp3FileReader(filepath)) // Create a new Disposable MP3FileReader, to read audio from the filePath parameter
                using (var resampler = new MediaFoundationResampler(MP3Reader, OutFormat)) // Create a Disposable Resampler, which will convert the read MP3 data to PCM, using our Output Format
                {
                    resampler.ResamplerQuality = 60; // Set the quality of the resampler to 60, the highest quality
                    int blockSize = OutFormat.AverageBytesPerSecond / 50; // Establish the size of our AudioBuffer
                    byte[] buffer = new byte[blockSize];
                    int byteCount;
    
                    while ((byteCount = resampler.Read(buffer, 0, blockSize)) > 0) // Read audio into our buffer, and keep a loop open while data is present
                    {
                        if (byteCount < blockSize)
                        {
                            // Incomplete Frame
                            for (int i = byteCount; i < blockSize; i++)
                                buffer[i] = 0;
                        }
                        VoiceClient.Send(buffer, 0, blockSize); // Send the buffer to Discord
                    }
                }
    
            }
        }
    }
    

    인스턴스를 생성하고 SendAudio 에 인수를 전달하면 재생할 수 있습니다!

    요약



    두 개의 DLL 다운로드를 잊지 마세요!
    그리고는 공식 페이지를 읽는다!

    좋은 웹페이지 즐겨찾기