I’m trying to use ffmpeg to take an input mp3 audio file (which contains an audio source and video source) from stdin, make modifications, and then send the mp3 to stdout. However, upon inspection of the audio after saving the stream from stdout, the file stream is missing the video source even though ffmpeg output states it is a part of the output sent to stdout.
For example, here’s the command I’m running with modifications removed (I’m using node fluent ffmpeg but here’s the converted command)
ffmpeg -i pipe:0 -f mp3 -map 0 pipe:1
I added the -map 0 to ensure all Sources are passed to the output.
After running, I receive the following output:
ffmpeg version 4.3.4-0+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 10 (Debian 10.2.1-6)
configuration: --prefix=/usr --extra-version=0+deb11u1 --toolchain=hardened --libdir=/usr/lib/aarch64-linux-gnu --incdir=/usr/include/aarch64-linux-gnu --arch=arm64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mp3, from 'pipe:0':
Metadata:
#REMOVED METADATA TO SHORTEN
Duration: N/A, start: 0.000000, bitrate: 320 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
Stream #0:1: Video: png, rgb24(pc), 1500x1500 [SAR 11811:11811 DAR 1:1], 90k tbr, 90k tbn, 90k tbc (attached pic)
Metadata:
title : cover
comment : Cover (front)
Stream mapping:
Stream #0:0 -> #0:0 (mp3 (mp3float) -> mp3 (libmp3lame))
Stream #0:1 -> #0:1 (png (native) -> png (native))
[mp3 @ 0xaaaae0fbb180] Frame rate very high for a muxer not efficiently supporting it.
Please consider specifying a lower framerate, a different muxer or -vsync 2
Output #0, mp3, to 'pipe:1':
Metadata:
# REMOVED METADATA TO SHORTEN
Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, fltp
Metadata:
encoder : Lavc58.91.100 libmp3lame
Stream #0:1: Video: png, rgb24(progressive), 1500x1500 [SAR 11811:11811 DAR 1:1], q=2-31, 200 kb/s, 90k fps, 90k tbn, 90k tbc (attached pic)
Metadata:
title : cover
comment : Cover (front)
encoder : Lavc58.91.100 png
frame= 1 fps=0.0 q=0.0 size= 1kB time=00:00:31.32 bitrate= 0.1kbits/s speed=62.6x
frame= 1 fps=1.0 q=0.0 size= 1kB time=00:01:08.31 bitrate= 0.1kbits/s speed=68.3x
frame= 1 fps=0.7 q=0.0 size= 1kB time=00:01:46.21 bitrate= 0.0kbits/s speed=70.8x
frame= 1 fps=0.5 q=0.0 size= 1kB time=00:02:24.19 bitrate= 0.0kbits/s speed=72.1x
frame= 1 fps=0.4 q=0.0 size= 1kB time=00:03:04.11 bitrate= 0.0kbits/s speed=73.6x
frame= 1 fps=0.3 q=-0.0 Lsize= 5618kB time=00:03:35.09 bitrate= 213.9kbits/s speed=72.8x
video:2256kB audio:3361kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.009597%
Everything looks good so far! As you can see, the output correctly maps Stream #0:0 (audio) and Stream #0:1 (album art) to Output #0. which is my stdout, yea?
So my output stream pipe:1 should contain both the audio and video streams, correct? However, when I pipe that stream to an output file and run ffprobe, I see the following:
ffprobe version 5.0.1 Copyright (c) 2007-2022 the FFmpeg developers
built with Apple clang version 13.1.6 (clang-1316.0.21.2.5)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/5.0.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-neon
libavutil 57. 17.100 / 57. 17.100
libavcodec 59. 18.100 / 59. 18.100
libavformat 59. 16.100 / 59. 16.100
libavdevice 59. 4.100 / 59. 4.100
libavfilter 8. 24.100 / 8. 24.100
libswscale 6. 4.100 / 6. 4.100
libswresample 4. 3.100 / 4. 3.100
libpostproc 56. 3.100 / 56. 3.100
[mp3 @ 0x11d604890] Format mp3 detected only with low score of 1, misdetection possible!
[mp3float @ 0x11d604c50] Header missing
Last message repeated 286 times
[mp3 @ 0x11d604890] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from '/Users/jordan/Downloads/ODESZA-Wide.mp3':
Duration: 00:04:32.88, start: 0.000000, bitrate: 320 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
The output claims that there’s a low score for mp3 detection, missing a header, and also Stream #0:1 (the album art) is completely missing from Input #0 even though it was a part of the Output #0 which should be sent to the stdout.
Do I have a fundamental misunderstanding of how piping streams work? When piping to an output file, can it only write a single stream like Stream #0:0 or should it being writing the entire Stream #0:0 AND Stream #0:1 since that is composition of the mp3 file?
If I run the same command, but write directly to file instead of stdout, like this:
ffmpeg -i pipe:0 -f mp3 -map 0 out.mp3
it contains both streams, so clearly this has to do with how piping streams work, right?
Thank you!