Skip to content

Instantly share code, notes, and snippets.

@jclay
Created January 11, 2025 16:29
Show Gist options
  • Save jclay/62196dc7f47ce9cda8ffbbbb3a583466 to your computer and use it in GitHub Desktop.
Save jclay/62196dc7f47ce9cda8ffbbbb3a583466 to your computer and use it in GitHub Desktop.

Analyzing a video from social media

Prerequisites

  • Modern version of Python installed.
  • ffmpeg command line tools installed

Windows with Chocolatey

choco install python ffmpeg

macOS with Homebrew

brew install python ffmpeg

Getting the highest quality video

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

Displaying motion vectors

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment