DEV Community

liveavabot
liveavabot

Posted on

How to make a Telegram video avatar that actually uploads

If you've ever tried to set a video as your Telegram profile picture and watched nothing happen, you're not alone. Telegram has a narrow, undocumented media spec.

The spec

  • Dimensions: exactly 800x800 pixels
  • Codec: H.264 only
  • Duration: at most 10.0 seconds
  • File size: at most 2 MB
  • Audio: no audio track
  • Pixel format: yuv420p
  • Container: MP4 with faststart

Any violation = silent rejection.

The iPhone problem

iPhone records in HEVC by default. HEVC is unusable as a Telegram avatar.

The ffmpeg command

ffmpeg -i input.mov \
  -t 10 \
  -vf "crop=min(iw\,ih):min(iw\,ih),scale=800:800,fps=30" \
  -c:v libx264 \
  -preset medium \
  -pix_fmt yuv420p \
  -b:v 900k \
  -an \
  -movflags +faststart \
  output.mp4
Enter fullscreen mode Exit fullscreen mode

Wrapping it in a bot

from aiogram import Router, F
from aiogram.types import Message, FSInputFile
import asyncio, tempfile
from pathlib import Path

router = Router()

@router.message(F.video | F.animation | F.document)
async def handle_video(message: Message):
    file = message.video or message.animation or message.document
    with tempfile.TemporaryDirectory() as td:
        inp = Path(td) / "in.bin"
        out = Path(td) / "out.mp4"
        await message.bot.download(file, destination=inp)
        # ffmpeg subprocess here
        await message.answer_video(FSInputFile(out))
Enter fullscreen mode Exit fullscreen mode

Try it

Skip writing ffmpeg yourself: https://t.me/LiveAvaBot?start=devto_article_20260418

Top comments (0)