Automation Pipeline3 min read

My Reels cover was selling a blank intro, not my app

I auto-crossposted my short videos to Instagram Reels, and the cover came out as the solid-color intro screen. The offset parameters were ignored for Reels, so I switched to extracting the cover image myself, hosting it, and passing its URL.

#instagram#reels#thumbnail#ffmpeg#automation
Left: a Reel whose cover is a solid-color intro screen. Right: a Reel whose cover is set to an app-screen frame.
Reels ignored the cover offset, so I had to upload the heaviest PNG frame myself and pass it by URL.

The cover was the intro

The vertical promo videos for my apps get made once and crossposted to several channels. Instagram Reels is one of them. But the published Reels had a cover (thumbnail) that wasn't the app screen. It was the solid-color intro at the very start of the video. The first impression in the feed was a flat block of color with no information on it.

The video itself had the app screens in it. The problem was where the platform took the cover from, and I had never specified that.

Does your auto-publishing pipeline check only the video body, or have you ever confirmed who picks the single cover image that actually shows up in the feed?

I thought an offset would do it

My first idea was to specify the moment to use as the cover. But the cover/thumbnail offset parameters (cover, thumb_offset) were ignored when publishing Reels. Setting them didn't change the result. To change a Reels cover, I had to use the cover_url parameter, which takes an image by URL.

That turned the problem into two: code had to choose which frame to use, and that image had to be uploaded somewhere reachable by URL.

What would you do? Have a person set the cover moment for every video, or let code choose?

The heaviest PNG was the app screen

I let code choose. A function called pick_cover grabs frames at several points in the MP4, saves each as PNG, and picks the one with the largest file size. A solid-color intro compresses to a tiny PNG. An app screen full of text and UI elements comes out much larger. So the rule treats the largest PNG as the app screen. The chosen frame gets converted to JPEG.

Then the JPEG gets uploaded to a file hosting path I already use, and that URL goes into the Reels publish request as cover_url. The publishing module only needed a change to accept the cover_url parameter. The whole diff was two files and 33 added lines.

The upside of this approach is that I don't have to set a new cover moment when the video structure changes. If the intro gets longer or shorter, the rule still gives the same answer.

Self-check

  • Have you looked, at least once per platform, at which frame actually becomes the cover of your auto-published videos?
  • Have you verified from the published result that your cover parameter really applies to that post type (e.g. Reels) and isn't silently ignored?
  • If your videos open on a solid intro or logo screen, have you considered that this first frame may become the default cover?

The honest part

Picking the frame with the largest PNG as the app screen is only a heuristic. I haven't ruled out a noisy transition or a frame with a busy background being picked instead, and I have no record of checking the result on every video. I also don't know yet whether views or engagement changed after the cover switched to the app screen. This fix removed a cover that was a blank block of color. It did not measure what that was worth.

Related