- Tue 23 November 2021
- misc
Important: On the off chance that you know my parents or sister,
please don't mention this to them until after the holidays as it's
meant to be a surprise! I'm pretty sure they don't read my blog... They know, and are enjoying the movies.
Several years ago I dropped by my parents' house while they were not home and helped myself to a box of old home movies, on the theory that it would be a nice thing for them and my sister if I were able to get them scanned and converted to more modern media.
Unfortunately, it turned out that there are essentially no service bureaus that are set up to do what I want with them. It's almost like the wedding photography business - everyone wants to control the creative product in the name of adding value while I wanted unretouched archival quality captures to post-process as I wished. Kim and I were lucky to be able to find a wedding photographer who felt the same way that we did, but he was definitely a unicorn and among commercial transfer services there were no unicorns to be had.
My desires were:
- No post-processing
- Don't want a DVD, a hard drive full of files is A-OK
- Professional mezzanine files are fine - I've got it from here
- Trust me, I know what I'm doing and am not going to ask for my money back because I am incompetent to handle the work product
- I won't blame you for the under-or-over-exposure of the source material
- Highest scan resolution possible
Shouldn't be hard right? It took a friend with access to a university archival media lab (to whom I am eternally grateful) to actually help me out on this.
And so I ended up with a hard drive full of Apple ProRes (yuv422p10le) encoded 1920x1080 enormous .mov files. My task was to convert these to something maximally compatible that would work on iPads, Rokus, etc since I wish to share with family friends who are in the various movies.
It's funny how many constraints one little requirement can bring in!
- A lot of players get cranky in some way if they see a stream that they don't recognize, so I had to strip out the ProRes timecode stream.
- Likewise, some players (notoriously older Rokus though there may be others) really want the h.264 video stream to come with an accompanying AAC soundtrack and will go sideways in unpredictable ways if one is not provided, so I had to add a silent soundtrack to my silent films.
- The metadata in the ProRes files claimed 24 FPS which was incorrect. No big deal there; I had said that a directory full of tiff images was fine if that was the most convenient way to deliver them. Actual frame rate for silent Super 8 is usually 18 FPS, which is what it was in this case.
- Preserving an 18 FPS frame rate was a non-starter because most dedicated playback devices only support 24, 30, and 60 FPS.
- Much like 3:2 pulldown for converting cinema to NTSC tv, we had to convert the 18 FPS to 24 FPS, which in practice means that every third frame gets duplicated or perhaps blended with the next frame (I believe ffmpeg does the former). Not the best, but not the worst either, and the human eye is fairly forgiving of this sort of thing.
- Target encoding was h.264 High@4.0 (yuv420p) for maximum compatibility
Here in the future we are not that sensitive to size but we are sensitive to perceived quality degradation by poor compression artifacts on film dirt and the like. A quality setting (CRF or Constant Rate Factor) of 18 put us in a good spot of turning a 1.9 gigabyte ProRes file into a 300 megabyte mp4 file - roughly three minutes runtime at 13 Mbit/second.
Doing all this in one shot with a command line tool took some fiddling since ffmpeg is the most fiddly command line tool since openssl or dd(1). But I persevered and here's the command that gets the job done:
ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -r 18 -i sum_71.mov -c:a aac -c:v libx264 -profile:v high -level:v 4.0 -vf format=yuv420p -movflags +faststart -write_tmcd 0 -crf 18 -r 24 -shortest sum_71.mp4
My copy of ffmpeg is version 4.4.1, built on an Intel Mac running Big Sur, using Homebrew.
Here's the information on the files - before:
barenfang:rs-home-movies rs$ ffprobe sum_71.mov
ffprobe version 4.4.1 Copyright (c) 2007-2021 the FFmpeg developers
built with Apple clang version 13.0.0 (clang-1300.0.29.3)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.4.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-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-avresample --enable-videotoolbox
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sum_71.mov':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2021-11-04T00:24:28.000000Z
Duration: 00:02:17.42, start: 0.000000, bitrate: 118435 kb/s
Stream #0:0(eng): Video: prores (Standard) (apcn / 0x6E637061), yuv422p10le(tv, bt709), 1920x1080, 118433 kb/s, SAR 1:1 DAR 16:9, 24 fps, 24 tbr, 24 tbn, 24 tbc (default)
Metadata:
creation_time : 2021-11-04T00:24:28.000000Z
handler_name : VideoHandler
vendor_id : appl
encoder : Apple ProRes 422 (STD)
timecode : 00:00:00:00
Stream #0:1(eng): Data: none (tmcd / 0x64636D74), 0 kb/s (default)
Metadata:
creation_time : 2021-11-04T00:24:28.000000Z
handler_name : TimeCodeHandler
timecode : 00:00:00:00
Unsupported codec with id 0 for input stream 1
barenfang:rs-home-movies rs$
And after:
barenfang:rs-home-movies rs$ ffprobe sum_71.mp4
ffprobe version 4.4.1 Copyright (c) 2007-2021 the FFmpeg developers
built with Apple clang version 13.0.0 (clang-1300.0.29.3)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.4.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-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-avresample --enable-videotoolbox
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sum_71.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:03:03.23, start: 0.000000, bitrate: 13291 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 13284 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 2 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
barenfang:rs-home-movies rs$
barenfang:rs-home-movies rs$
And there you have it; playback has been tested on various hardware including a 2009 MacBook Pro running MacOS 10.9 (the oldest thing I have around), a 2011 MacBook Pro running MacOS 10.13, a 2013 Roku 3, a 2014 iPad Mini 3, and of course all of my newer stuff. Works great.
Hopefully the ffmpeg
command line above is of value to someone.
Deconstructing it and what the various parts actually do is left as an
exercise to the reader.