Node.js объедините аудио- и видеопотоки и передайте их клиенту

#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’); Также, если возможно, опубликуйте полную ошибку