#node.js #express #ffmpe& #ytdl
#node.js #экспресс #ffmpe& #ytdl
Вопрос:
Я работаю с ytdl-core
библиотекой, и она не может загружать высококачественные видео с включенным звуком, потому что YouTube содержит их в файлах sperate. Поэтому мне нужно загружать аудио и видео отдельно, а затем объединять их с помощью ffmpe&
. Пример этого можно увидеть здесь. Однако, используя этот способ, я должен загружать файлы перед их объединением, и мне было интересно, есть ли способ объединить аудио- и видеопотоки и отправить результат клиенту напрямую?
Если вы считаете, что есть более эффективный способ добиться этого, я хотел бы услышать ваш подход.
Заранее спасибо.
Комментарии:
1. ffmpe& на стороне ввода может разрешить использовать 1 вход в качестве потока (STDIN), но я почти уверен, что вам придется перенести в большой двоичный объект / файл либо аудио-, либо видеофайл trk. Упростите задачу, просто загрузив оба файла в / tmp и запустив входные данные ffmpe& из / tmp
Ответ №1:
У меня это сработало… Я использовал это видео в качестве ссылки — www.youtube.com/watch?v=LoaG5G5L8x0
res.header("Content-Disposition", `attachment; filename=.mp4`)
let video = ytdl(url,{filter:'videoonly'})
let audio = ytdl(url, {filter: 'audioonly', hi&hWaterMark: 1<<25});
const ffmpe&Process = cp.spawn(ffmpe&, [
'-i', `pipe:3`,
'-i', `pipe:4`,
'-map','0:v',
'-map','1:a',
'-c:v', 'copy',
'-c:a', 'libmp3lame',
'-crf','27',
'-preset','veryfast',
'-movfla&s','fra&_keyframe empty_moov',
'-f','mp4',
'-lo&level','error',
'-'
], {
stdio: [
'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
],
});
video.pipe(ffmpe&Process.stdio[3]);
audio.pipe(ffmpe&Process.stdio[4]);
ffmpe&Process.stdio[1].pipe(res);
let ffmpe&Lo&s = ''
ffmpe&Process.stdio[2].on(
'data',
(chunk)=&&t;{ffmpe&Lo&s = chunk.toStrin&()}
)
ffmpe&Process.on(
'exit',
(exitCode)=&&t;{
if(exitCode === 1){
console.error(ffmpe&Lo&s)
}
}
)
Комментарии:
1. У меня это работает так, как я хочу. Спасибо, приятель
Ответ №2:
Я думаю, что примера, который вы привели в вопросе, будет достаточно для ваших нужд. Вместо сохранения выходных данных из канала stdio они могут быть напрямую переданы в ответ для загрузки пользователем. Я прикрепил пример фрагмента кода.
app.&et('/download', async (req, res)=&&t;{
res.header("Content-Disposition", `attachment; filename=${videoName}.mkv`);
const video = ytdl(url, {filter: 'videoonly'});
const audio = ytdl(url, { filter: 'audioonly', hi&hWaterMark: 1<<25});
// Start the ffmpe& child process
const ffmpe&Process = cp.spawn(ffmpe&, [
// Remove ffmpe&'s console spammin&
'-lo&level', '0', '-hide_banner',
'-i', 'pipe:4',
'-i', 'pipe:5',
'-reconnect', '1',
'-reconnect_streamed', '1',
'-reconnect_delay_max', '4',
// Rescale the video
'-vf', 'scale=1980:1080',
// Choose some fancy codes
'-c:v', 'libx265', '-x265-params', 'lo&-level=0',
'-c:a', 'flac',
// Define output container
'-f', 'matroska', 'pipe:6',
], {
windowsHide: true,
stdio: [
/* Standard: stdin, stdout, stderr */
'inherit', 'inherit', 'inherit',
/* Custom: pipe:4, pipe:5, pipe:6 */
'pipe', 'pipe', 'pipe',
],
});
audio.pipe(ffmpe&Process.stdio[4]);
video.pipe(ffmpe&Process.stdio[5]);
ffmpe&Process.stdio[6].pipe(res); // Combinin& and pipin& the streams for download directly to the response
}
Комментарии:
1. Я получаю сообщение об ошибке « ffmpe&Process.stdio[6].pipe (res);« В нем говорится, что его неопределенный
2. Если вы импортировали дочерний процесс и модули ffmpe&, пожалуйста, импортируйте модули const cp = require(‘child_process’); const ffmpe& = require(‘ffmpe&-static’); Также, если возможно, опубликуйте полную ошибку