- Modern version of Python installed.
ffmpeg
command line tools installed
Windows with Chocolatey
choco install python ffmpeg
macOS with Homebrew
brew install python ffmpeg
I use yt-dlp
for getting videos. Install it via pip:
pip install yt-dlp
List all formats for a given video with -F
yt-dlp -F "https://youtu.be/oYawawiaroI?si=4VvFOeKWmuI4WQ0V"
Output looks like this
[info] Available formats for oYawawiaroI:
ID EXT RESOLUTION FPS CH │ FILESIZE TBR PROTO │ VCODEC VBR ACODEC ABR ASR MORE INFO
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
sb3 mhtml 48x27 3 │ mhtml │ images storyboard
sb2 mhtml 80x45 1 │ mhtml │ images storyboard
sb1 mhtml 160x90 1 │ mhtml │ images storyboard
sb0 mhtml 320x180 1 │ mhtml │ images storyboard
233 mp4 audio only │ m3u8 │ audio only unknown [en] Default
234 mp4 audio only │ m3u8 │ audio only unknown [en] Default
140 m4a audio only 2 │ 530.36KiB 130k https │ audio only mp4a.40.2 130k 44k [en] medium, m4a_dash
251 webm audio only 2 │ 496.78KiB 122k https │ audio only opus 122k 48k [en] medium, webm_dash
269 mp4 256x144 30 │ ~324.40KiB 78k m3u8 │ avc1.4D400C 78k video only
160 mp4 256x144 30 │ 69.52KiB 17k https │ avc1.4d400c 17k video only 144p, mp4_dash
230 mp4 640x360 30 │ ~927.77KiB 224k m3u8 │ avc1.4D401E 224k video only
134 mp4 640x360 30 │ 203.85KiB 50k https │ avc1.4d401e 50k video only 360p, mp4_dash
18 mp4 640x360 30 2 │ 589.82KiB 144k https │ avc1.42001E mp4a.40.2 44k [en] 360p
605 mp4 640x360 30 │ ~740.07KiB 178k m3u8 │ vp09.00.21.08 178k video only
243 webm 640x360 30 │ 117.11KiB 29k https │ vp9 29k video only 360p, webm_dash
136 mp4 1280x720 30 │ 416.80KiB 102k https │ avc1.64001f 102k video only 720p, mp4_dash
311 mp4 1280x720 60 │ ~ 1.73MiB 428k m3u8 │ avc1.640020 428k video only
298 mp4 1280x720 60 │ 718.53KiB 176k https │ avc1.640020 176k video only 720p60, mp4_dash
312 mp4 1920x1080 60 │ ~ 2.60MiB 643k m3u8 │ avc1.64002A 643k video only
299 mp4 1920x1080 60 │ 1.25MiB 315k https │ avc1.64002a 315k video only 1080p60, mp4_dash
Here you'll want to aim to pick the video format that is most likely to be the original upload.
Everything else will be re-encoded which is lossy. YouTube only downscales, so this tells us the original resolution was 1080p.
Make sure to only pick from codecs that start with avc1
. This is equivalent to H264. It's extremely unlikely anyone uploads
video in vp9 so these have all been re-encoded by YouTube.
From here we have two choices, 312
and 299
. 312
has ~2x higher bitrate (VBR) at 643k
so that's the best pick.
Now let's download that exact video stream:
yt-dlp -f 312 "https://youtu.be/oYawawiaroI?si=4VvFOeKWmuI4WQ0V" -o output.mp4
You can ask ChatGPT to create ffmpeg commands to crop video, display frame counts and many other things. It's a good way to get a starting point for a command.
Here is the ffmpeg wiki with some examples of showing motion vectors https://trac.ffmpeg.org/wiki/Debug/MacroblocksAndMotionVectors
Preview with ffplay
ffplay -flags2 +export_mvs -vf "codecview=mv=pf+bf+bb" output.mp4
Press space
to pause and step frame by frame by pressing s
Re-encode to produce a new video with the motion vectors overlaid
ffmpeg -flags2 +export_mvs -i output.mp4 -vf "codecview=mv=pf+bf+bb" -c:v libx264 output_mv.mp4
Same thing but slowing the video down by 4x
ffmpeg -flags2 +export_mvs -i output.mp4 -vf "codecview=mv=pf+bf+bb,setpts=4*PTS" -c:v libx264 output_mv.mp4
Showing a frame count
ffmpeg -flags2 +export_mvs -i output.mp4 -vf "codecview=mv=pf+bf+bb,drawtext=text='Frame %{n}':x=(w-tw)/2:y=10:fontsize=24:fontcolor=white:borderw=2,setpts=4*PTS" -c:v libx264 output_mv.mp4