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())

В этом случае он просто возвращает то же самое видео в виде ответа. А ожидаю я от него посланного видео, конвертированного в кружок. Подскажите, пожалуйста, как решить задачку?


Ответы (0 шт):