How to generate a video for Threads with ffmpeg
Today I wanted to generate a small teaser of an AI generated song I produced for a D&D campaign in order to share it on Threads. Sounds like an easy task but I had to overcome some limitation:
while from its mobile app you can send voice notes, Threads doesn’t allow for standard audio files like an mp3, so I had to generate a video.
I quickly hacked together this command that given the audio file an image, it uses them to produce a video with the image in loop.
ffmpeg -loop 1 -i sollevamento_nanico.webp -i sollevamento_nanico-teaser.mp3 -shortest sollevamento_nanico-teaser.mp4
The generated file had this spec:
Output #0, mp4, to 'sollevamento_nanico-teaser.mp4':
Metadata:
encoder : Lavf60.16.100
Stream #0:0: Video: mpeg4 (mp4v / 0x7634706D), yuv420p(tv, bt470bg/unknown/unknown, progressive), 1024x1024, q=2-31, 200 kb/s, 25 fps, 12800 tbn
Metadata:
encoder : Lavc60.31.102 mpeg4
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
Unlucky for me Threads can’t reproduce it, so I digged a bit into the API documentation and I gathered more information:
Video Specifications
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, 25 Mbps maximum.
Audio Bitrate: 128 kbps.
Duration: 300 seconds (5 minutes) maximum, minimum longer than 0 seconds.
File Size: 1 GB maximum.
Bingo! My file had two issues:
- wrong video codec
- moov atom not at the beginning of the file
Fixing it is a straightforward task in ffmpeg:
ffmpeg -loop 1 -i sollevamento_nanico.webp -i sollevamento_nanico-teaser.mp3 -shortest -c:v libopenh264 -movflags faststart sollevamento_nanico-teaser.mp4
Notice that I used libopenh264
instead of libx264
since the latter is not available on Fedora due to patent issues; nothing prevents you from installing it, but for a 10 second video it doesn’t make any difference.
This was a very quick and dirty solution, I hope it will be useful to someone.
Comments are open if you need some help or want to discuss.