Search code examples
ffmpegpipemozjpeg

How to extract sequence of lossless images with FFMPEG and pipe them to mozjpeg's cjpeg?


I know it can be down with imagemagick but mozjpeg produces much smaller images which is desirable.

I want all frames of a video be extracted and converted to JPEG by mozjpeg.

What I have tried:

$ ind = 1
$ ffmpeg -hide_banner -ss 00:00:10 -i IN.webm -t 00:00:02 -r 24 -c:v bmp -f image2pipe pipe:1 | \
    cjpeg - workDir/$((ind++)).jpeg

Error message:

av_interleaved_write_frame(): Broken pipe time=00:00:00.00 bitrate=N/A speed=   0x    

Error writing trailer of pipe:1: Broken pipe

frame=    1 fps=0.0 q=-0.0 Lsize=    6075kB time=00:00:00.04 bitrate=1194394.4kbits/s speed=0.0765x    

video:6075kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

Conversion failed!


Solution

  • cjpeg accepts stdin pipe input but does not seem to accept more than one input at a time.

    Output images and then loop with cjpeg:

    ffmpeg -ss 00:00:10 -i IN.webm -t 00:00:02 %04d.bmp
    for f in *.bmp; do cjpeg -quality 75 -outfile "workDir/${f%.bmp}.jpg" "$f"; done
    

    No need for -r 24: using that can result in dropped or duplicated frames if you force an arbitrary frame rate that doesn't match the input. Omit -r and ffmpeg will output all frames.