Конвертируйте файл из mkv в mp4, не сохраняя его на стороне сервера, используя fluent-ffmpeg в nodejs - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь создать приложение для узла, которое получает файл mkv, преобразует его в mp4, жестко записывает субтитры и отправляет его обратно, чтобы пользователь мог загрузить его. В командной строке это прекрасно работает

ffmpeg -i input.mkv -threads 1 -vf subtitles=input.mkv -acodec copy output.mp4

Затем я попытался преобразовать это в маршрут узла, используя fluent-ffmpeg

var ffmpeg = require('fluent-ffmpeg');

routes.post('/process', (req, res) => {
    //file sent
    const file = req.files.file
    const path = __dirname + '/public/data/'

    //saves file in server
    file.mv(path + file.name, err => {
        if (err) return res.sendStatus(500).send(err)
        console.log('upload successful')
    })

    //convert the file to mp4 with the hardburned subtitle
    ffmpeg(path + file.name).toFormat('mp4')
    .addOutputOption(["-threads 1"])
    .addOutputOption(["-acodec copy"])
    .addOutputOption(['-vf subtitles=' + path + file.name])
    .on('end', () => {
        console.log('done')
        res.sendStatus(200)
    })
    .on('error', console.log)
    .saveToFile(path + 'output.mp4') //saves file in server
})

Это HTML Я тестирую

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Index</title>
</head>
<body>
    <form method='post' action="/process" enctype="multipart/form-data">
        <input type='file' id='uploader' name='file'>
        <input type='submit' value='send'>
    </form>
</body>
</html>

К сожалению, это не сработало, и код вернул следующее сообщение об ошибке

Error: ffmpeg exited with code 1: Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
Conversion failed!

    at ChildProcess.<anonymous> (C:\Users\fsvic\Desktop\ffmpeg_teste_node\node_modules\fluent-ffmpeg\lib\processor.js:182:22)
    at ChildProcess.emit (events.js:182:13)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:240:12) '' 'ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers\n  built with gcc 9.1.1 (GCC) 20190807\n  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt\n  libavutil      56. 31.100 / 56. 31.100\n  libavcodec     58. 54.100 / 58. 54.100\n  libavformat    58. 29.100 / 58. 29.100\n  libavdevice    58.  8.100 / 58.  8.100\n  libavfilter     7. 57.100 /  7. 57.100\n  libswscale      5.  5.100 /  5.  5.100\n  libswresample   3.  5.100 /  3.  5.100\n  libpostproc    55.  5.100 / 55.  5.100\nInput #0, matroska,webm, from \'C:\\Users\\fsvic\\Desktop\\ffmpeg_teste_node/public/data/star_trails.mkv\':\n  Metadata:\n    COMPATIBLE_BRANDS: mp42mp41\n    MAJOR_BRAND     : mp42\n    MINOR_VERSION   : 0\n    ENCODER         : Lavf57.66.105\n  Duration: 00:00:21.25, start: 0.000000, bitrate: 1893 kb/s\n    Stream #0:0(eng): Video: h264 (High), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)\n    Metadata:\n      HANDLER_NAME    : ?Mainconcept Video Media Handler\n      ENCODER         : Lavc57.83.101 libx264\n      DURATION        : 00:00:21.163000000\n    Stream #0:1(eng): Audio: vorbis, 48000 Hz, stereo, fltp (default)\n    Metadata:\n      HANDLER_NAME    : #Mainconcept MP4 Sound Media Handler\n      ENCODER         : Lavc57.83.101 libvorbis\n      DURATION        : 00:00:21.251000000\nStream mapping:\n  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))\n  Stream #0:1 -> #0:1 (copy)\nPress [q] to stop, [?] for help\n[subtitles @ 000001cc091dbb80] Unable to parse option value "UsersfsvicDesktopffmpeg_teste_node/public/data/star_trails.mkv" as image size\n    Last message repeated 1 times\n[subtitles @ 000001cc091dbb80] Error setting option original_size to value UsersfsvicDesktopffmpeg_teste_node/public/data/star_trails.mkv.\n[Parsed_subtitles_0 @ 000001cc0910a8c0] Error applying options to the filter.\n[AVFilterGraph @ 000001cc0912ba80] Error initializing filter \'subtitles\' with args \'C:UsersfsvicDesktopffmpeg_teste_node/public/data/star_trails.mkv\'\nError reinitializing filters!\nFailed to inject frame into filter network: Invalid argument\nError while processing the decoded data for stream #0:0\nConversion failed!\n'

Кроме того, Я не могу ничего сохранить в на стороне сервера из-за ограничений памяти, поэтому мне нужен способ использовать команды FFmpeg без реального файла в папке. Я обнаружил, что функция pipe могла бы сделать эту работу, но я понятия не имею, как я могу реализовать ее в текущем коде.

...