Removing NAudio dependency so it will work on Linux

This commit is contained in:
José Henrique Ivanchechen 2023-01-31 21:05:31 -03:00
parent 6744736ffd
commit 10323daaa1
6 changed files with 75 additions and 36 deletions

View File

@ -1,8 +1,8 @@
name: CI
on:
push:
branches: [ "master" ]
# push:
# branches: [ "master" ]
pull_request:
branches: [ "master" ]

2
.gitignore vendored
View File

@ -1,6 +1,8 @@
appsettings.*.json
.env*
Properties/launchSettings.json
.vs
.vscode
bin

View File

@ -10,7 +10,6 @@
<ItemGroup>
<PackageReference Include="Discord.Net" Version="3.9.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="NAudio" Version="2.1.0" />
<PackageReference Include="YoutubeExplode" Version="6.2.5" />
</ItemGroup>

View File

@ -1,10 +1,7 @@
using Discord;
using Discord.Audio;
using Discord.Commands;
using Kasbot.Services;
using NAudio.Wave;
using TextCommandFramework.Services;
using YoutubeExplode;
namespace TextCommandFramework.Modules
{

View File

@ -37,7 +37,7 @@ namespace TextCommandFramework.Services
return;
var argPos = 0;
var prefix = "!";
var prefix = "-";
//Check if the message sent has the specified prefix
if (!message.HasStringPrefix(prefix, ref argPos)) return;

View File

@ -1,9 +1,15 @@
using Discord;
using AngleSharp;
using Discord;
using Discord.Audio;
using Discord.Audio.Streams;
using Discord.Commands;
using Discord.WebSocket;
using NAudio.Wave;
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using YoutubeExplode;
using YoutubeExplode.Videos.Streams;
namespace Kasbot.Services
{
@ -16,50 +22,83 @@ namespace Kasbot.Services
Clients = new Dictionary<SocketGuild, Media>();
}
private async Task<Stream> DownloadAudioFromYoutube(string youtubeUrl)
private async Task<string> DownloadAudioFromYoutube(string youtubeUrl)
{
var youtube = new YoutubeClient();
var videoId = await youtube.Search.GetVideosAsync(youtubeUrl).FirstOrDefaultAsync();
var streamInfoSet = await youtube.Videos.Streams.GetManifestAsync(videoId.Id);
var highestAudioStreamInfo = streamInfoSet.GetAudioStreams().OrderByDescending(s => s.Bitrate).FirstOrDefault();
var streamVideo = await youtube.Videos.Streams.GetAsync(highestAudioStreamInfo);
var memoryStream = new MemoryStream();
await streamVideo.CopyToAsync(memoryStream);
memoryStream.Position = 0;
return memoryStream;
var streamInfo = streamInfoSet.GetAudioOnlyStreams().GetWithHighestBitrate();
var streamVideo = await youtube.Videos.Streams.GetAsync(streamInfo);
var fileName = $"{videoId.Id}.mp3";
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await streamVideo.CopyToAsync(fileStream);
}
return fileName;
}
public async Task Play(SocketCommandContext Context, string arguments)
{
IVoiceChannel channel = (Context.User as IVoiceState).VoiceChannel;
var audioStream = await DownloadAudioFromYoutube(arguments);
if (audioStream is null)
string filename = string.Empty;
try
{
await Context.Channel.SendMessageAsync("Failed to download audio from YouTube.");
return;
filename = await DownloadAudioFromYoutube(arguments);
}
catch (Exception ex)
{
throw new Exception("Error while downloading video from YouTube!");
}
var audioClient = await channel.ConnectAsync();
using (var mp3Reader = new StreamMediaFoundationReader(audioStream))
using (var ffmpeg = CreateStream(filename))
using (var output = ffmpeg.StandardOutput.BaseStream)
using (var discord = audioClient.CreatePCMStream(AudioApplication.Mixed))
{
var audioOut = audioClient.CreatePCMStream(AudioApplication.Music);
await audioClient.SetSpeakingAsync(true);
var media = new Media
try
{
AudioClient = audioClient,
Message = Context.Message,
Name = "",
AudioOutStream = audioOut,
};
Clients.Add(Context.Guild, media);
await mp3Reader.CopyToAsync(audioOut);
await audioClient.SetSpeakingAsync(false);
var media = new Media()
{
AudioClient = audioClient,
AudioOutStream = discord,
FileName = filename,
Message = Context.Message,
Name = ""
};
Clients.Add(Context.Guild, media);
await output.CopyToAsync(discord);
}
finally
{
await discord.FlushAsync();
File.Delete(filename);
}
}
}
private Process CreateStream(string filename)
{
var process = Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-hide_banner -loglevel panic -i {filename} -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true
});
if (process == null || process.HasExited)
{
throw new Exception("Sorry, ffmpeg killed himself! Bah.");
}
return process;
}
public async Task Stop(SocketCommandContext Context)
{
if (!Clients.ContainsKey(Context.Guild))
@ -68,6 +107,7 @@ namespace Kasbot.Services
var media = Clients[Context.Guild];
Clients.Remove(Context.Guild);
File.Delete(media.FileName);
await Context.Message.DeleteAsync();
await media.Message.DeleteAsync();
await media.AudioOutStream.DisposeAsync();
@ -80,6 +120,7 @@ namespace Kasbot.Services
public class Media
{
public string Name { get; set; }
public string FileName { get; set; }
public IAudioClient AudioClient { get; set; }
public AudioOutStream AudioOutStream { get; set; }
public SocketUserMessage Message { get; set; }