Skip to content

Instantly share code, notes, and snippets.

@Joe4evr
Last active October 18, 2023 15:32
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save Joe4evr/773d3ce6cc10dbea6924d59bbfa3c62a to your computer and use it in GitHub Desktop.
Save Joe4evr/773d3ce6cc10dbea6924d59bbfa3c62a to your computer and use it in GitHub Desktop.
D.Net 1.0 audio example
using System.Threading.Tasks;
using Discord.Commands;
public class AudioModule : ModuleBase<ICommandContext>
{
// Scroll down further for the AudioService.
// Like, way down
private readonly AudioService _service;
// Remember to add an instance of the AudioService
// to your IServiceCollection when you initialize your bot
public AudioModule(AudioService service)
{
_service = service;
}
// You *MUST* mark these commands with 'RunMode.Async'
// otherwise the bot will not respond until the Task times out.
[Command("join", RunMode = RunMode.Async)]
public async Task JoinCmd()
{
await _service.JoinAudio(Context.Guild, (Context.User as IVoiceState).VoiceChannel);
}
// Remember to add preconditions to your commands,
// this is merely the minimal amount necessary.
// Adding more commands of your own is also encouraged.
[Command("leave", RunMode = RunMode.Async)]
public async Task LeaveCmd()
{
await _service.LeaveAudio(Context.Guild);
}
[Command("play", RunMode = RunMode.Async)]
public async Task PlayCmd([Remainder] string song)
{
await _service.SendAudioAsync(Context.Guild, Context.Channel, song);
}
}
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Discord;
using Discord.Audio;
public class AudioService
{
private readonly ConcurrentDictionary<ulong, IAudioClient> ConnectedChannels = new ConcurrentDictionary<ulong, IAudioClient>();
public async Task JoinAudio(IGuild guild, IVoiceChannel target)
{
IAudioClient client;
if (ConnectedChannels.TryGetValue(guild.Id, out client))
{
return;
}
if (target.Guild.Id != guild.Id)
{
return;
}
var audioClient = await target.ConnectAsync();
if (ConnectedChannels.TryAdd(guild.Id, audioClient))
{
// If you add a method to log happenings from this service,
// you can uncomment these commented lines to make use of that.
//await Log(LogSeverity.Info, $"Connected to voice on {guild.Name}.");
}
}
public async Task LeaveAudio(IGuild guild)
{
IAudioClient client;
if (ConnectedChannels.TryRemove(guild.Id, out client))
{
await client.StopAsync();
//await Log(LogSeverity.Info, $"Disconnected from voice on {guild.Name}.");
}
}
public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path)
{
// Your task: Get a full path to the file if the value of 'path' is only a filename.
if (!File.Exists(path))
{
await channel.SendMessageAsync("File does not exist.");
return;
}
IAudioClient client;
if (ConnectedChannels.TryGetValue(guild.Id, out client))
{
//await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}");
using (var ffmpeg = CreateProcess(path))
using (var stream = client.CreatePCMStream(AudioApplication.Music))
{
try { await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream); }
finally { await stream.FlushAsync(); }
}
}
}
private Process CreateProcess(string path)
{
return Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg.exe",
Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false,
RedirectStandardOutput = true
});
}
}
@Mikusho
Copy link

Mikusho commented Dec 22, 2020

How to Stream desktop audio??

@aggiczy
Copy link

aggiczy commented Feb 28, 2021

My bot joins and then instantly disconnects from the voice channel. How do I fix this?

Same. How do I fix this?

@Mikusho
Copy link

Mikusho commented Feb 28, 2021 via email

@ABeer905
Copy link

ABeer905 commented Mar 24, 2021

I can only get the audio to play once following the SendAudioAsync method. When I call the audio command again the bot lights up green as if it were talking but no audio comes through. In order to play the audio file again the bot has to leave and rejoin. Any ideas?

@Nessitro
Copy link

@Sombody101
Copy link

Can we start making a more updated version of this? I say we, but I don't really know what I'm doing.
I used this tutorial to try and make a music bot, but it didn't work. I'm not sure if that's because the libraries aren't set up right, or because I'm feeding it .mp3 files. But it no workie, and I can't find any other tutorials.
I did what the tutorial said and renamed one of the .dll files, and placed both inside my bin/debug folder (Strange that you don't want to reference it, unless FFmpeg does on its own. I'm not sure), and it didn't do anything. I think I would have felt better if it threw an error so I could know what was wrong with it.

@Pretzl65
Copy link

Pretzl65 commented Aug 1, 2022

Can we start making a more updated version of this? I say we, but I don't really know what I'm doing. I used this tutorial to try and make a music bot, but it didn't work. I'm not sure if that's because the libraries aren't set up right, or because I'm feeding it .mp3 files. But it no workie, and I can't find any other tutorials. I did what the tutorial said and renamed one of the .dll files, and placed both inside my bin/debug folder (Strange that you don't want to reference it, unless FFmpeg does on its own. I'm not sure), and it didn't do anything. I think I would have felt better if it threw an error so I could know what was wrong with it.

Same goes for me... the only thing I was able to find out is that it seems to get stuck at Line 59 ("await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream);") ... no idea why or how to fix it though! :/

@Sombody101
Copy link

Same goes for me... the only thing I was able to find out is that it seems to get stuck at Line 59 ("await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream);") ... no idea why or how to fix it though! :/

I got it working at some point, but I then switched to LavaLink. It requires you to have Java installed and to have a second terminal open to run it, but works great. It automatically searches for the song. You don't even need to install .mp3 files (you can if you want to still, just might not work with LavaLink). It would also be a good idea to switch over to DSharpPlus (if you decide to use LavaLink) because they have that linked with their API. So you don't have to do much to get it connected with the terminal that hosts LavaLink.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment