Ffmpeg fixx
This commit is contained in:
parent
b1bc4306eb
commit
f15a527de1
|
@ -5,6 +5,37 @@ const { EmbedBuilder } = require('discord.js');
|
|||
const fs = require('fs');
|
||||
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 = {
|
||||
name: 'play',
|
||||
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);
|
||||
fs.writeFileSync(tempVideoPath, buffer);
|
||||
|
||||
const ffmpegProcess = spawn('ffmpeg', [
|
||||
'-i', tempVideoPath,
|
||||
'-f', 'mp3',
|
||||
'-ab', '192000',
|
||||
'-vn',
|
||||
tempFilePath
|
||||
]);
|
||||
spawnFFmpegProcess(['-i', tempVideoPath, '-f', 'mp3', '-ab', '192000', '-vn', tempFilePath], (err) => {
|
||||
if (err) {
|
||||
console.error('Error converting file:', err);
|
||||
message.reply('Failed to convert the video file.');
|
||||
return;
|
||||
}
|
||||
|
||||
ffmpegProcess.on('close', () => {
|
||||
console.log(`Converted and saved: ${tempFilePath}`);
|
||||
fs.unlinkSync(tempVideoPath);
|
||||
|
||||
|
@ -112,11 +141,6 @@ module.exports = {
|
|||
playNextInQueue(message.guild.id);
|
||||
});
|
||||
|
||||
ffmpegProcess.on('error', (err) => {
|
||||
console.error('Error converting file:', err);
|
||||
message.reply('Failed to convert the video file.');
|
||||
});
|
||||
|
||||
return;
|
||||
} else {
|
||||
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]));
|
||||
fs.writeFileSync(tempVideoPath, buffer);
|
||||
|
||||
const ffmpegProcess = spawn('ffmpeg', [
|
||||
'-i', tempVideoPath,
|
||||
'-f', 'mp3',
|
||||
'-ab', '192000',
|
||||
'-vn',
|
||||
tempFilePath
|
||||
]);
|
||||
spawnFFmpegProcess(['-i', tempVideoPath, '-f', 'mp3', '-ab', '192000', '-vn', tempFilePath], (err) => {
|
||||
if (err) {
|
||||
console.error('Error converting file:', err);
|
||||
message.reply('Failed to convert the video file.');
|
||||
return;
|
||||
}
|
||||
|
||||
ffmpegProcess.on('close', () => {
|
||||
console.log(`Converted and saved: ${tempFilePath}`);
|
||||
fs.unlinkSync(tempVideoPath);
|
||||
|
||||
|
@ -200,11 +222,6 @@ module.exports = {
|
|||
playNextInQueue(message.guild.id);
|
||||
});
|
||||
|
||||
ffmpegProcess.on('error', (err) => {
|
||||
console.error('Error converting file:', err);
|
||||
message.reply('Failed to convert the video file.');
|
||||
});
|
||||
|
||||
} else {
|
||||
fs.writeFileSync(tempFilePath, buffer);
|
||||
console.log(`Downloaded and saved: ${tempFilePath}`);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const { createAudioPlayer, createAudioResource, AudioPlayerStatus, joinVoiceChannel } = require('@discordjs/voice');
|
||||
const fs = require('fs');
|
||||
const { spawn } = require('child_process')
|
||||
|
||||
const queueMap = new Map();
|
||||
const playerMap = new Map();
|
||||
|
@ -94,45 +95,70 @@ function playTrack(guildId, voiceChannel, track) {
|
|||
adapterCreator: voiceChannel.guild.voiceAdapterCreator,
|
||||
});
|
||||
|
||||
const audioPlayer = playerMap.get(guildId) || createAudioPlayer();
|
||||
playerMap.set(guildId, audioPlayer);
|
||||
let audioPlayer = playerMap.get(guildId);
|
||||
|
||||
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)) {
|
||||
console.error('Audio file not found:', track.filePath);
|
||||
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);
|
||||
connection.subscribe(audioPlayer);
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue