Save in Quicktime-compatible format (not H264 - MPEG-4 AVC (part 10) )

When I run

VideoIO.save(
    "video.mp4", images, framerate=5;
    encoder_options=(crf=23, preset="medium")
)

it successfully saves an mp4 video, but it saves it with a codec that Quicktime player is unable to open on my Mac. (Quicktime gives the error “The file isn’t compatible with QuickTime Player.”)

Based on this webpage, and inspecting the codec of the video using the VLC media player, it looks like the issue is that Quicktime does not support the the H264 - MPEG-4 AVC (part 10) format that the video is saved in.

Does anyone know how to tell VideoIO to save a video in a more standard codec? (I am not familiar with codecs, but if I’m understanding, the issue is the “AVC” part.)
In case it helps, I think that this page may explain how to use FFMPEG to save a video in a suitable format.

I don’t think that macrumors post is correct: AVC ist just a name for H.264, see Wikipedia.

A common issue with ffmpeg encoded videos is the pixel format: Why won't video from ffmpeg show in QuickTime, iMovie or quick preview? - Ask Different . However, with your settings VideoIO should use yuv420p which should work in QuickTime so it would be good to have more information:

What is your VideoIO version?

Can you show the output running ffprobe video.mp4 in the terminal?

Thanks for the help.
I am using VideoIO v"0.9.6".

Here is the result of ffprobe:

georgematheos@Georges-MacBook-Pro testing-george % ffprobe video.mp4
ffprobe version 5.0 Copyright (c) 2007-2022 the FFmpeg developers
  built with Apple clang version 13.0.0 (clang-1300.0.29.3)
  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/5.0 --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
  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
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:00:04.00, start: 0.000000, bitrate: 1096 kb/s
  Stream #0:0[0x1](und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p(progressive), 640x480, 1094 kb/s, 5 fps, 5 tbr, 10240 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]

For some reason your video is encoded using the less-compatible yuv444p pixel format… What’s the type of images? (what does typeof(images) say?)

You can try the following:

VideoIO.save(
           "video.mp4", images, framerate=5;
           encoder_options=(crf=23, preset="medium"),
           target_pix_fmt=VideoIO.AV_PIX_FMT_YUV420P
       )
1 Like

I think this catches a lot of people out, not just in Julia.

The default also does not play in Firefox, and FF tells you it is a bad encoding (the error message is deliberately wrong and WontFix), so you fiddle with the encoder options instead of target_pix_fmt

Here’s my code to create a Firefox compatible video from still images

    firstimg = RGB{N0f8}.(load(imgnames[1]))
    open_video_out("$(vfname).$(ftype)", firstimg, framerate=24, target_pix_fmt =VideoIO.AV_PIX_FMT_YUV420P) do writer
        @showprogress "Encoding video frames.." for i in eachindex(imgnames)
           img = RGB{N0f8}.(load(imgnames[i]))
           write(writer, img)
        end
    end
2 Likes