@subhe

Как отправить видео в телеграм бот без загрузки на компьютер и в режиме стриминга?

У меня есть код, который скачивает видео по ссылке и выводит в консоль прогресс загрузки.
Мне нужно отправлять это видео в телеграм бота, но так как файл большой время ожидания очень большое.
Я знаю, что можно загружать видео сразу на сервер тг и показывать пользователю до его полной загрузки через supports_streaming, но мой код почему-то ждет полной загрузки видео на сервер и не дает предпоказ.

Код который скачивает видео на компьютер:
import ssl
import urllib.request
import fake_useragent
from tqdm import tqdm  # импортируем tqdm

stream_url = 'https://cdn-r4-cache.soap4youand.me/adad6ec937715da5d9d34f907c2b873f1ac57303/5548/ad29d13d480c8f2455ef747283e10f52/'
referer = 'https://cdn-r4-cache.soap4youand.me/adad6ec937715da5d9d34f907c2b873f1ac57303/5548/ad29d13d480c8f2455ef747283e10f52/'
user_agent = fake_useragent.UserAgent().random

headers = {'Referer': referer, 'User-Agent': user_agent}

request = urllib.request.Request(stream_url, headers=headers)

context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE

request = urllib.request.Request(stream_url, headers=headers)

with urllib.request.urlopen(request, context=context) as response, open('video.mp4', 'wb') as out_file:
    chunk_size = 1024 * 1024  # размер блока данных, загружаемых за один раз (1 MB)
    total_size = int(response.getheader('Content-Length', 0))  # общий размер файла в байтах
    progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True)  # создаем объект tqdm с общим размером файла

    while True:
        data = response.read(chunk_size)  # читаем данные блоками
        if not data:
            break  # прерываем цикл, если данные закончились
        out_file.write(data)  # записываем блоки данных в файл
        progress_bar.update(len(data))  # обновляем индикатор прогресса

    progress_bar.close()  # закрываем индикатор прогресса после завершения загрузки


Вариант кода, который должен отправлять видео пользователю предпоказом:
import telebot
import ssl
import urllib.request
import fake_useragent

TOKEN = ''
bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def start(message):
    stream_url = 'https://cdn-r4-cache.soap4youand.me/adad6ec937715da5d9d34f907c2b873f1ac57303/5548/ad29d13d480c8f2455ef747283e10f52/'
    referer = 'https://cdn-r4-cache.soap4youand.me/adad6ec937715da5d9d34f907c2b873f1ac57303/5548/ad29d13d480c8f2455ef747283e10f52/'
    user_agent = fake_useragent.UserAgent().random

    headers = {'Referer': referer, 'User-Agent': user_agent}

    context = ssl.create_default_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE

    request = urllib.request.Request(stream_url, headers=headers)

    with urllib.request.urlopen(request, context=context) as response:
        video = response.read()

    bot.send_video(message.chat.id, video=video, supports_streaming=True)

bot.polling()


Как мне реализовать свою задачу и возможно ли это вообще?
  • Вопрос задан
  • 866 просмотров
Пригласить эксперта
Ответы на вопрос 1
@5465
Для отправки видео в телеграм бота без загрузки на компьютер и в режиме стриминга, вы можете использовать модуль requests и метод post из библиотеки python-telegram-bot для отправки видео на сервер телеграма.

Вам необходимо изменить код таким образом, чтобы он читал видео блоками и отправлял их на сервер телеграма. Для этого вам понадобится использовать метод requests.post с параметрами для отправки частей файла.

Пример кода, который может помочь вам реализовать задачу:

import telebot
import requests

TOKEN = 'YOUR_TOKEN'
bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def start(message):
    stream_url = 'https://cdn-r4-cache.soap4youand.me/adad6ec937715da5d9d34f907c2b873f1ac57303/5548/ad29d13d480c8f2455ef747283e10f52/'

    with requests.get(stream_url, stream=True) as r:
        total_size = int(r.headers.get('content-length', 0))
        if total_size == 0:
            bot.send_message(message.chat.id, 'Failed to retrieve video from URL')
            return

        headers = {'Content-Type': 'video/mp4'}
        url = f'https://api.telegram.org/bot{TOKEN}/sendVideo'

        for chunk in r.iter_content(chunk_size=1024*1024):
            if chunk:
                try:
                    response = requests.post(url, data={'chat_id': message.chat.id}, headers=headers, files={'video': chunk}, timeout=30)
                    response.raise_for_status()
                except Exception as e:
                    print(f'Error sending chunk: {e}')
                    bot.send_message(message.chat.id, 'Error sending video chunk')
                    break

bot.polling()


В этом примере мы отправляем видео блоками размером 1 МБ, используя метод requests.post для отправки каждого блока на сервер телеграма. Мы также добавляем параметр timeout, чтобы прервать отправку, если что-то идет не так. Вы можете настроить размер блока (chunk_size) в соответствии с вашими потребностями.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы