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.
Want this for yourself?
To run this, you'll need a modern Ruby installed and ffprobe installed (on a Mac with homebrew, brew install ffprobe
should do).