aiogram/telegram - получить от пользователя видео и превратить его в кружок
Коллеги, доброго дня!
Пожалуйста, подскажите, как решить такую задачу на aiogram 3.x для Telegram. Пользователь отправляет в телегу короткий видеофайл, на бэке происходит его преобразование в кружок (если вертикальное видео, режет его в квадратное).
Делал двумя способами, ни один не работает:
import io
import logging
import asyncio
import tempfile
from colorama import init, Fore
import numpy as np
from moviepy import vfx, VideoFileClip
import os
from moviepy import VideoFileClip, CompositeVideoClip, vfx
from moviepy.video.fx.Crop import Crop
from aiogram import Bot, Dispatcher, Router, types, F
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram.filters.command import Command
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')
init()
BOT_TOKEN = 'TOKEN'
bot = Bot(token=BOT_TOKEN,
default=DefaultBotProperties(
parse_mode=ParseMode.HTML,
))
dp = Dispatcher()
router = Router()
@router.message(Command('start'))
async def start_command(message: types.Message) -> types.Message:
await message.answer(f'{message.from_user.id=}\n'
f'{message.chat.id=}\n'
f'{message.from_user.username=}')
def create_circle_video(input_file):
# Использование временного файла
with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as temp_input_file:
input_file.seek(0) # Убедитесь, что указатель в начале файла
temp_input_file.write(input_file.read())
temp_input_file_path = temp_input_file.name
# Создаем клип
clip = VideoFileClip(temp_input_file_path)
# Обрезка видео в круг
circle_clip = vfx.mask_circle(clip, radius=min(clip.size) // 2)
# Сохраняем результирующее видео в временный файл
with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as temp_output_file:
circle_clip.write_videofile(temp_output_file.name, codec='libx264', audio_codec='aac')
temp_output_file_path = temp_output_file.name
return temp_output_file_path
@router.message(F.video)
async def convert_video(message: types.Message) -> types.Message:
video_file = await bot.get_file(message.video.file_id)
file_path = video_file.file_path
# Скачивание файла
video_data = await bot.download_file(file_path)
# Генерация выходного видео
output_video_path = create_circle_video(video_data)
# Отправка готового видео
with open(output_video_path, 'rb') as video:
await message.answer_video(video)
# Удаляем временный файл после отправки
os.remove(output_video_path)
async def bot_start() -> None:
dp.include_routers(router)
try:
await dp.start_polling(bot, skip_updates=True)
finally:
await bot.session.close()
if __name__ == '__main__':
asyncio.run(bot_start())
Способ выдаёт ошибку:
AttributeError: module 'moviepy.video.fx' has no attribute 'mask_circle'
Другой способ:
import logging
import asyncio
from colorama import init, Fore
from aiogram import Bot, Dispatcher, Router, types, F
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram.filters.command import Command
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')
init()
BOT_TOKEN = 'TOKEN'
bot = Bot(token=BOT_TOKEN,
default=DefaultBotProperties(
parse_mode=ParseMode.HTML,
))
dp = Dispatcher()
router = Router()
@router.message(F.video)
async def convert_video(message: types.Message) -> types.Message:
video_note = message.video.file_id
await message.answer_video_note(video_note=video_note)
async def bot_start() -> None:
dp.include_routers(router)
try:
await dp.start_polling(bot, skip_updates=True)
finally:
await bot.session.close()
if __name__ == '__main__':
asyncio.run(bot_start())
В этом случае он просто возвращает то же самое видео в виде ответа. А ожидаю я от него посланного видео, конвертированного в кружок. Подскажите, пожалуйста, как решить задачку?