A script to validate videos for the Instagram API
If you are publishing videos via the Instagram API (as I do for my feed2gram gem and for Beckygram), one of the first things you notice is that it is a lot less forgiving than their app is.
From their docs that spell this out:
The following are the specifications for Reels:
- Container: MOV or MP4 (MPEG-4 Part 14), no edit lists, moov atom at the front of the file.
- Audio codec: AAC, 48khz sample rate maximum, 1 or 2 channels (mono or stereo).
- Video codec: HEVC or H264, progressive scan, closed GOP, 4:2:0 chroma subsampling.
- Frame rate: 23-60 FPS.
- Picture size:
- Maximum columns (horizontal pixels): 1920
- Required aspect ratio is between 0.01:1 and 10:1 but we recommend 9:16 to avoid cropping or blank space.
- Video bitrate: VBR, 25Mbps maximum
- Audio bitrate: 128kbps
- Duration: 15 mins maximum, 3 seconds minimum
- File size: 300MB maximum
If you get this wrong, you'll receive a mostly-unhelpful-but-better-than-nothing-error message that looks like this:
{
"message": "The video file you selected is in a format that we don't support.",
"type": "OAuthException",
"code": 352,
"error_subcode": 2207026,
"is_transient": false,
"error_user_title": "Unsupported format",
"error_user_msg": "The video format is not supported. Please check spec for supported CodedException format",
"fbtrace_id": "AvU9fEFKlA8Z7RLRlZ1j9w_"
}
I was sick of hobbling together the same half dozen ffprobe
commands and then eyeballing the results (which are typically inscrutable if you don't know what you're looking for), so I wrote a script to test this for me.
For example, a recent clip failed to syndicate to Instagram and I wondered why that was, so I ran this little script, which I put on my PATH
and named validate_video_for_instagram
. It output:
Validating video: /Users/justin/Documents/podcast/clips/v30-the-startup-shell-game.mp4
✅ container
✅ audio_codec
✅ max_audio_sample_rate
✅ video_codecs
✅ color_space
✅ min_frame_rate
✅ max_frame_rate
❌ max_horizontal_pixels - Maximum columns (horizontal pixels): 1920 required; got: 2160
✅ min_aspect_ratio
✅ max_aspect_ratio
✅ max_video_bitrate_mbps
❌ max_audio_bitrate_kbps - Audio bitrate: 128kbps maximum required; got: 256.073
✅ min_duration_seconds
✅ max_duration_seconds
✅ max_size_megabytes
❌ Video had 2 error(s) preventing API upload to Instagram.
Docs: https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-user/media
Is it surprising that the Instagram API won't accept 4K video? Yes. Especially since the videos weighs in at less than 100MB.
To run this, you'll need a modern Ruby installed and ffprobe installed (on a Mac with homebrew, brew install ffprobe
should do).
Spoiler alert: there's more to this…