A buffer comes from browser to node.js read by FileReader.
// videoArrayBuffer is a buffer coming from browser
let readableVideoBuffer = new stream.PassThrough();
readableVideoBuffer.write(videoArrayBuffer);
readableVideoBuffer.end()
ffmpeg()
.input(readableVideoBuffer)
.inputFormat("mp4")
.outputOptions([
"-pix_fmt yuv420p",
"-movflags frag_keyframe+empty_moov",
"-movflags +faststart"
])
// .videoCodec("libx264")
.toFormat("mp4")
.save("test.mp4")
(note: if the problem only happens with some inputs, include a link to such an input file)
expecting a properly saved video
ffmpeg stderr:
ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers
built with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.3_1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9715001400] stream 0, offset 0x4f: partial file
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9715001400] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 1280x720, 10843 kb/s): unspecified pixel format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'pipe:0':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp41isom
creation_time : 2019-07-10T15:03:19.000000Z
Duration: 00:00:02.13, start: 0.033333, bitrate: N/A
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 1280x720, 10843 kb/s, 30 fps, 30 tbr, 30k tbn, 60k tbc (default)
Metadata:
creation_time : 2019-07-10T15:03:19.000000Z
handler_name : VideoHandler
encoder : AVC Coding
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9715001400] stream 0, offset 0x4f: partial file
pipe:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Conversion failed!
I have similar issues when using streams as inputs and / or outputs.
For example this works as you'd expect it to:
new ffmpeg(path.resolve("./debug-input.mp4"))
.toFormat("mp4")
.save(path.resolve("./debug.mp4"))
While this doesn't:
const input = fs.createReadStream(path.resolve("./debug-input.mp4"))
const output = fs.createWriteStream(path.resolve("./debug.mp4"))
new ffmpeg(input)
.toFormat("mp4")
.pipe(output)
Using a stream as input yields ffmpeg exited with code 1: pipe:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF - I've tried other types of NodeJS readable / writable streams with the same results exactly.
Similarly, using an output stream also yields an error:
const output = fs.createWriteStream(path.resolve("./debug.mp4"))
new ffmpeg(path.resolve("./debug-input.mp4"))
.toFormat("mp4")
.pipe(output)
ffmpeg exited with code 1: Conversion failed! (I'm guessing it can't write to the output stream)
I'm running ffmpeg 4.2.1 on MacOS and fluent-ffmpeg 2.1.2
You have to specify the input format, ffmpeg usually uses the file extension to automatically find the format
@njoyard I don't think it's the issue. I did try specifying the input format:
const input = fs.createReadStream(path.resolve("./debug-input.mp4"))
new FFMPEG(input)
.inputFormat("mp4")
.toFormat("mp4")
.save(path.resolve("./debug.mp4"))
For the same Invalid data found when processing input
Also, this wouldn't explain why the output stream is also failing as I do specify a foFormat.
@Coriou did you end up solving this? I'm getting the same problem.
Nope, haven't looked back at it. I was thinking about what would be the best way to reproduce this directly with the ffmpeg binary (not using this node wrapper) but then got caught up in other things and never looked back at this issue since
I am also experiencing this very error with a readable stream coming from node-ftp. Filestreams work fine though.
@adrian-kriegel Could you show me a piece of code using filestreams that works for you please ?
@Coriou I just tested it using a filestream as an output aswell as using one as the input. Using a filestream for the output does in fact not work for me. This works though:
ffmpeg(fs.createReadStream('video.mp4')).inputFormat('mp4').[other commands]
It seems to be the same code you posted. I am guessing that out mp4 files differ in some way.
It has been some time since I opened this issue, but I think I solved my issue by the following:
const inputForFFMPEG = new stream.PassThrough()ffmpeg(inputForFFMPEG).save('./directoryName/file.mp4').on('end', async () => {
try {
// Here I uploaded file to google cloud storage
} catch (e) {
// Here and below is an obsessive error checking
console.log(e);
throw e
}
}).on('error', (err) => {
console.log(err)
})
} catch (e) {
console.log(e)
throw e
}
Note: You can use google cloud to upload files through automatically generated upload link straight to storage and feed ffmpeg with that files URL.
Hope any of this helps to someone in the future. Good luck and happy coding. 馃帀
@Coriou you'll need to add both
.outputOptions('-movflags frag_keyframe+empty_moov')
and
.toFormat("mp4")
in case you're using output streams
I don't exactly know the reason behind it. But it is something like mp4 needs to write header in the beginning after completing whole encoding.
Thanks @utkarsh914, didn't work though. This code returns the exact same error:
import fs from "fs"
import path from "path"
import ffmpeg from "fluent-ffmpeg"
const input = fs.createReadStream(path.resolve("./test-input.mp4"))
const output = fs.createWriteStream(path.resolve("./test-output.mp4"))
new ffmpeg(input)
.inputFormat("mp4")
.outputOptions("-movflags frag_keyframe+empty_moov")
.toFormat("mp4")
.save(output)
Outputs
Error: ffmpeg exited with code 1: pipe:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Conversion failed!
Even though I'd love for this issue to be resolved or - at least - understand what is wrong, it's a non-blocking issue for me as I just use Ffmpeg directly without any problems whatsoever.
Here the input file's probe:
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
built with Apple clang version 11.0.3 (clang-1103.0.32.59)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.2.2_5 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags=-fno-stack-check --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test-input.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:04:05.03, start: 0.000000, bitrate: 2259 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 2127 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
Metadata:
handler_name : ISO Media file produced by Google Inc.
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
handler_name : SoundHandler
I know this is a bit late but, for future reference and for @Coriou
This is a limitation of FFmpeg, specifically the MOV/MP4 muxer (switch to Matroska or WebM if you require streaming inputs), it requires output and input to be seekable.
There's the output-only workaround described @utkarsh914, which uses the empty_moov flag. From the FFmpeg Docs:
[writes] an initial moov atom directly at the start of the file, without describing any samples in it.
This works for outputs, but for inputs, there's no workaround I know about.
Thanks @FedericoCarboni, glad to know what the issue is !
i used this option and fixed
thanks @FedericoCarboni
.addOutputOption('-movflags','frag_keyframe+empty_moov')
Most helpful comment
I know this is a bit late but, for future reference and for @Coriou
This is a limitation of FFmpeg, specifically the MOV/MP4 muxer (switch to Matroska or WebM if you require streaming inputs), it requires output and input to be seekable.
There's the output-only workaround described @utkarsh914, which uses the
empty_moovflag. From the FFmpeg Docs:This works for outputs, but for inputs, there's no workaround I know about.