0

I'm trying to decode a video from raw bytes using ffmpeg -i pipe: -f rawvideo -pix_fmt bgr24 -an -sn pipe:, while the command exits with code 0, the stdout is empty and stderr contains the following message:

ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.2_4 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --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-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --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
  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
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fa862816a00] stream 0, offset 0x2c: partial file
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'pipe:':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.29.100
  Duration: 00:00:06.28, start: 0.000000, bitrate: N/A
    Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv), 1080x1920, 50546 kb/s, 29 fps, 29 tbr, 14848 tbn, 14848 tbc (default)
    Metadata:
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> rawvideo (native))
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fa862816a00] stream 0, offset 0x2c: partial file
pipe:: Invalid data found when processing input
Output #0, rawvideo, to 'pipe:':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.45.100
    Stream #0:0(und): Video: rawvideo (BGR[24] / 0x18524742), bgr24, 1080x1920, q=2-31, 1443225 kb/s, 29 fps, 29 tbn, 29 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.91.100 rawvideo
frame=    0 fps=0.0 q=0.0 Lsize=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)

Any hint would be appreciated, as I don't have much experience with FFMPEG.

I can probe the same video without problem with ffprobe -show_format -show_streams -of json pipe:

4
  • As it says, "stream 0, offset 0x2c: partial file". Generally, you can't pipe in a MP4/MOV. MPEGTS is the typical container for piping.
    – Gyan
    Jul 8 at 13:24
  • Thanks for the quick reply. Does that mean, that if I have an MP4 file, I would first have to convert it to a different format that can be piped? Or is there any other alternative? Jul 8 at 13:31
  • No, you will have to remux it to a workable container like MPEG TS.
    – Gyan
    Jul 8 at 17:14
  • Actually, I found a solution that works when you can control the files (see answer). Jul 9 at 7:33
0

The goal of the above question is potentially impossible, because:

You generally cannot pipe mov (or mp4) files unless you used -movflags +faststart when encoding or if run tools/qt-faststart on the input file before piping it. - Carl Eugen

This is, because they store crucial information needed to decode towards the end of the file by default, requiring a full load before being fully processable. However, they are able to store it towards the beginning, too. In that case, piping works.

Since I control the files I am working with, I could simply rewrite the files so that this information is stored towards their beginning and now the command from the question works. I used ffmpeg to do that: ffmpeg -i <ORIGINAL_FILENAME> -c copy -map 0 -movflags +faststart <NEW_FILENAME>.

I've written a small python script to do that for me:

from pathlib import Path
from subprocess import DEVNULL, PIPE, Popen

def convert_video_to_faststart(path: Path):
    tmp_path = str(path).replace(path.name, f"tmp_{path.name}")
    args = ["ffmpeg", "-i", str(path), "-c", "copy", "-map", "0", "-movflags", "+faststart",
            tmp_path]

    process = Popen(args, stdin=DEVNULL, stdout=PIPE, stderr=PIPE)
    _, _ = process.communicate()
    if process.returncode != 0:
        raise RuntimeError(f"ffmpeg error\n\n{err.decode('utf-8')}")
    path.unlink()
    Path(tmp_path).rename(path)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.