- Modern version of Python installed.
ffmpegcommand 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