Ffmpeg fixx

This commit is contained in:
Wizzard 2024-08-18 04:49:20 -04:00
parent b1bc4306eb
commit f15a527de1
2 changed files with 98 additions and 55 deletions

View File

@ -5,6 +5,37 @@ const { EmbedBuilder } = require('discord.js');
const fs = require('fs'); const fs = require('fs');
const { exec, spawn, execSync } = require('child_process'); const { exec, spawn, execSync } = require('child_process');
const MAX_RETRIES = 3;
const RETRY_DELAY = 1000;
function spawnFFmpegProcess(args, callback, retries = 0) {
const ffmpegProcess = spawn('ffmpeg', args);
ffmpegProcess.on('close', (code) => {
if (code === 0) {
callback(null);
} else if (retries < MAX_RETRIES) {
console.warn(`FFmpeg process failed, retrying (${retries + 1}/${MAX_RETRIES})...`);
setTimeout(() => {
spawnFFmpegProcess(args, callback, retries + 1);
}, RETRY_DELAY);
} else {
callback(new Error(`FFmpeg process failed after ${MAX_RETRIES} retries.`));
}
});
ffmpegProcess.on('error', (err) => {
if (retries < MAX_RETRIES) {
console.warn(`FFmpeg process error, retrying (${retries + 1}/${MAX_RETRIES})...`, err);
setTimeout(() => {
spawnFFmpegProcess(args, callback, retries + 1);
}, RETRY_DELAY);
} else {
callback(err);
}
});
}
module.exports = { module.exports = {
name: 'play', name: 'play',
description: 'Play a song from YouTube, a URL, or an uploaded media file', description: 'Play a song from YouTube, a URL, or an uploaded media file',
@ -84,15 +115,13 @@ module.exports = {
const tempVideoPath = path.join(__dirname, '../utils/tmp', attachment.name); const tempVideoPath = path.join(__dirname, '../utils/tmp', attachment.name);
fs.writeFileSync(tempVideoPath, buffer); fs.writeFileSync(tempVideoPath, buffer);
const ffmpegProcess = spawn('ffmpeg', [ spawnFFmpegProcess(['-i', tempVideoPath, '-f', 'mp3', '-ab', '192000', '-vn', tempFilePath], (err) => {
'-i', tempVideoPath, if (err) {
'-f', 'mp3', console.error('Error converting file:', err);
'-ab', '192000', message.reply('Failed to convert the video file.');
'-vn', return;
tempFilePath }
]);
ffmpegProcess.on('close', () => {
console.log(`Converted and saved: ${tempFilePath}`); console.log(`Converted and saved: ${tempFilePath}`);
fs.unlinkSync(tempVideoPath); fs.unlinkSync(tempVideoPath);
@ -112,11 +141,6 @@ module.exports = {
playNextInQueue(message.guild.id); playNextInQueue(message.guild.id);
}); });
ffmpegProcess.on('error', (err) => {
console.error('Error converting file:', err);
message.reply('Failed to convert the video file.');
});
return; return;
} else { } else {
console.error('Attachment is not a supported media file.'); console.error('Attachment is not a supported media file.');
@ -172,15 +196,13 @@ module.exports = {
const tempVideoPath = path.join(__dirname, '../utils/tmp', path.basename(searchQuery.split('?')[0])); const tempVideoPath = path.join(__dirname, '../utils/tmp', path.basename(searchQuery.split('?')[0]));
fs.writeFileSync(tempVideoPath, buffer); fs.writeFileSync(tempVideoPath, buffer);
const ffmpegProcess = spawn('ffmpeg', [ spawnFFmpegProcess(['-i', tempVideoPath, '-f', 'mp3', '-ab', '192000', '-vn', tempFilePath], (err) => {
'-i', tempVideoPath, if (err) {
'-f', 'mp3', console.error('Error converting file:', err);
'-ab', '192000', message.reply('Failed to convert the video file.');
'-vn', return;
tempFilePath }
]);
ffmpegProcess.on('close', () => {
console.log(`Converted and saved: ${tempFilePath}`); console.log(`Converted and saved: ${tempFilePath}`);
fs.unlinkSync(tempVideoPath); fs.unlinkSync(tempVideoPath);
@ -200,11 +222,6 @@ module.exports = {
playNextInQueue(message.guild.id); playNextInQueue(message.guild.id);
}); });
ffmpegProcess.on('error', (err) => {
console.error('Error converting file:', err);
message.reply('Failed to convert the video file.');
});
} else { } else {
fs.writeFileSync(tempFilePath, buffer); fs.writeFileSync(tempFilePath, buffer);
console.log(`Downloaded and saved: ${tempFilePath}`); console.log(`Downloaded and saved: ${tempFilePath}`);

View File

@ -1,5 +1,6 @@
const { createAudioPlayer, createAudioResource, AudioPlayerStatus, joinVoiceChannel } = require('@discordjs/voice'); const { createAudioPlayer, createAudioResource, AudioPlayerStatus, joinVoiceChannel } = require('@discordjs/voice');
const fs = require('fs'); const fs = require('fs');
const { spawn } = require('child_process')
const queueMap = new Map(); const queueMap = new Map();
const playerMap = new Map(); const playerMap = new Map();
@ -94,45 +95,70 @@ function playTrack(guildId, voiceChannel, track) {
adapterCreator: voiceChannel.guild.voiceAdapterCreator, adapterCreator: voiceChannel.guild.voiceAdapterCreator,
}); });
const audioPlayer = playerMap.get(guildId) || createAudioPlayer(); let audioPlayer = playerMap.get(guildId);
playerMap.set(guildId, audioPlayer);
if (!audioPlayer) {
audioPlayer = createAudioPlayer();
playerMap.set(guildId, audioPlayer);
audioPlayer.on(AudioPlayerStatus.Idle, () => {
if (!repeatMap.get(guildId)) {
currentTrackMap.delete(guildId);
fs.unlink(track.filePath, (err) => {
if (err) console.error('Error deleting file:', track.filePath, err);
});
}
const queue = getQueue(guildId);
if (queue.length > 0 || repeatMap.get(guildId)) {
playNextInQueue(guildId);
} else {
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
}
});
audioPlayer.on('error', (err) => {
console.error('AudioPlayer error:', err);
currentTrackMap.delete(guildId);
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
});
}
if (track.ffmpegProcess) {
try {
track.ffmpegProcess.kill();
console.log('Killed existing ffmpeg process.');
} catch (err) {
console.error('Error killing existing ffmpeg process:', err);
}
}
if (!fs.existsSync(track.filePath)) { if (!fs.existsSync(track.filePath)) {
console.error('Audio file not found:', track.filePath); console.error('Audio file not found:', track.filePath);
return false; return false;
} }
const resource = createAudioResource(track.filePath); track.ffmpegProcess = spawn('ffmpeg', [
'-i', track.filePath,
'-analyzeduration', '0',
'-loglevel', '0',
'-acodec', 'libopus',
'-f', 'opus',
'-ar', '48000',
'-ac', '2',
'pipe:1'
]);
const resource = createAudioResource(track.ffmpegProcess.stdout);
audioPlayer.play(resource); audioPlayer.play(resource);
connection.subscribe(audioPlayer); connection.subscribe(audioPlayer);
currentTrackMap.set(guildId, { ...track, resource }); currentTrackMap.set(guildId, { ...track, resource });
audioPlayer.on(AudioPlayerStatus.Idle, () => {
if (!repeatMap.get(guildId)) {
currentTrackMap.delete(guildId);
fs.unlink(track.filePath, (err) => {
if (err) console.error('Error deleting file:', track.filePath, err);
});
}
const queue = getQueue(guildId);
if (queue.length > 0 || repeatMap.get(guildId)) {
playNextInQueue(guildId);
} else {
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
}
});
audioPlayer.on('error', (err) => {
console.error('AudioPlayer error:', err);
currentTrackMap.delete(guildId);
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
});
} }
function skipTrack(guildId) { function skipTrack(guildId) {