Кружок из любого видео — и без «подпишитесь на 4 канала»

—

от автора

После Качалки и «Чисто» — мелочь попроще: отправить в Telegram кружок не с камеры, а из готового видео. Ботов для этого полно, и почти все устроены одинаково: прежде чем что-то сделать, просят подписаться на четыре канала, потом показывают рекламу, а кружок отдают с водяным знаком.

Задача на вечер, но раз уж все делают её с подписками — сделал без. Бот @chisto_krugi_bot: присылаешь видео — получаешь кружок. Ни подписок, ни рекламы, ни регистрации. Код открыт.

Рассказывать тут особо не о чем, поэтому коротко: что умеет и на что я всё-таки наступил.

Что умеет

  • Режет квадрат по центру и сжимает под Telegram: до 640×640, H.264, около 1,5 Мбит/с.

  • Видео длиннее минуты предлагает разрезать на кружки по минуте (до десяти) или взять одну минуту.

  • Нужен не тот кусок — подписываешь видео временем, например 1:20, кружок начнётся оттуда.

  • Принимает обычное видео, файл и гифку.

  • Пока работает, показывает прогресс прямо в сообщении, а в конце его убирает — в чате остаётся только кружок.

Вертикальный ролик 1080×1920 на 38 секунд превращается в кружок на 1,6 МБ за 3,7 секунды на одном ядре сервера. Запись экрана 2560×1600 на 22 секунды — за 4,5 секунды, весит потом 0,6 МБ.

Весь бот — два файла на Python без зависимостей, только стандартная библиотека и FFmpeg.

Грабли №1: присланный файл может оказаться не видео

Файл присылает незнакомый человек, а FFmpeg умеет открывать не только видео. Например, плейлисты HLS: текстовый файл со ссылками на куски видео. Если переименовать такой плейлист в .mp4 и вписать в него путь к чужому файлу на сервере, FFmpeg честно пойдёт его читать и может вклеить в «кружок».

Поэтому и ffprobe, и ffmpeg запускаются с белым списком:

-protocol_whitelist file-format_whitelist mov,mp4,matroska,webm,avi,gif,mpegts,flv,3gp,ogg

Читать можно только с диска и только обычные видеоконтейнеры. Плейлист-ловушка теперь заканчивается сообщением «Не получилось открыть файл как видео» — это проверяет отдельный тест.

Грабли №2: прогресс, который застревает на 17%

Прогресс FFmpeg отдаёт сам, если запустить его с -progress pipe:1: каждые полсекунды он пишет out_time_us=…. Я делил это время на 60 секунд — длину кружка. А видео было на 10 секунд, и полоска честно доползала до 17% и пропадала вместе с готовым кружком. Теперь делю на настоящую длину куска.

Вторая мелочь там же: ошибки FFmpeg я сначала читал из трубы. На битом видео он пишет ошибку на каждый кадр, труба переполняется — и FFmpeg замирает, ожидая, пока её прочитают. Теперь ошибки идут во временный файл, а на случай, если FFmpeg всё равно зависнет, есть таймер, который его останавливает.

Грабли №3: Telegram отдаёт ботам только 20 МБ

Чтобы сделать кружок, бот должен сначала скачать видео. Обычный Bot API отдаёт ботам файлы только до 20 МБ — а минута с телефона в 1080p весит 30–60 МБ. Обойти это можно только своим сервером Bot API (telegram-bot-api --local), тогда лимит — 2 ГБ, а файл бот берёт прямо с диска. Для Качалки такой сервер у меня уже есть, и бот это умеет. Пока работает обычный режим: видео больше 20 МБ бот просит обрезать в галерее — для кружка всё равно нужна минута.

Грабли №4: у человека закрыты видеосообщения

В настройках приватности Telegram можно запретить присылать себе голосовые и видеосообщения — и ботам тоже. Тогда на sendVideoNote Telegram отвечает ошибкой, и человек остаётся ни с чем. В этом случае бот присылает то же видео обычным файлом и подсказывает, где открыть видеосообщения.

Чтобы сервер не заметил бота

Бот живёт на том же сервере, что и Качалка. Чтобы обработка видео не отнимала у неё ресурсы, у бота свой пользователь и потолок: полтора ядра из трёх, гигабайт памяти, приоритет ниже. Разом обрабатываются два видео, у одного человека в очереди — до трёх, на человека — до 40 кружков в час.

Видео бот не хранит: сделал кружок — удалил и исходник, и результат.

Чтобы не проверять руками

44 теста. 13 — про обработку: обрезка по центру (красный и синий края должны пропасть, остаться только зелёная середина), повёрнутое видео, 60 fps, WEBM и гифка, разрезка, битые файлы, плейлист-ловушка, зависший FFmpeg. Остальные 31 — бот целиком на поддельном Telegram: от «прислал видео» до «пришёл кружок», в обычном режиме и со своим сервером Bot API. GitHub прогоняет их после каждого изменения.


Бот — @chisto_krugi_bot, исходники — github.com/kozliq/krugi. Поднять своего — python3 krugi.py и токен от BotFather.

Ещё у меня есть Качалка — сохраняет видео без водяных знаков, и «Чисто» — убирает рекламу на телефоне и компьютере. Тоже бесплатно, тоже без регистрации.

Будет ещё.

ссылка на оригинал статьи https://habr.com/ru/articles/1099112/