You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram机器人无法发送视频:下载成功但发送代码未执行

Telegram YouTube下载机器人发送视频失败排查与修复

问题描述

我基于Pyrogram与Pytube开发了一个Telegram机器人,功能是接收用户发送的YouTube链接,下载对应视频后发送回聊天窗口。目前视频能成功下载,视频时长也可正常获取,但发送视频的代码段始终未执行,且已确认bot token、api_id、api_hash的配置完全正确。

原代码

from pyrogram import Client
from pytube import YouTube
import os
import asyncio

app = Client("qaserd_ll", api_id=..., api_hash='...', bot_token='...')

@app.on_message()
async def send_video(client, message):
    URL = message.text
    yt = YouTube(URL)
    ys = yt.streams.get_highest_resolution()
    video_path = 'video.mp4'
    try:
        ys.download(filename='video.mp4')  # Download the video using the specified filename
        print("Video downloaded successfully")
    except Exception as e:
        print(f"An error occurred while downloading the video: {e}")
        return
    attempts = 0
    while not os.path.exists('video.mp4') and attempts < 10:  # Wait for the video to be downloaded
        await asyncio.sleep(1)
        attempts += 1
    if attempts == 10:
        print("Video download timed out")
        return
    duration = yt.length
    print(duration)
    try:
        await client.send_video(message.chat.id, video_path, duration=duration)
        print("Video sent successfully")
    except Exception as e:
        print(f"An error occurred while sending the video: {e}")

app.run()

问题排查与修复方案

1. 限制消息触发范围

原代码的@app.on_message()未设置过滤条件,会接收所有类型的消息(包括机器人自身发送的消息、命令消息、非文本消息等),可能导致逻辑触发混乱。添加过滤规则,仅处理包含YouTube链接的用户文本消息:

  • 使用filters.regex匹配YouTube链接格式
  • 使用~filters.me排除机器人自身的消息

2. 优化文件等待逻辑

Pytube的download()是同步阻塞方法,下载完成后才会返回,因此后续的while等待循环完全多余,可直接移除,避免不必要的等待或误判。

3. 完善发送视频的异常处理与参数

  • 确保duration参数为整数类型(显式转换更稳妥)
  • 添加视频标题作为发送时的字幕,提升用户体验
  • 增强异常捕获的详细度,便于定位问题

4. 添加本地文件清理

发送完成后删除本地下载的视频文件,避免磁盘空间被占用,使用try...finally确保无论发送成功与否都执行清理。

修改后的代码

from pyrogram import Client, filters
from pytube import YouTube
import os

app = Client("qaserd_ll", api_id=..., api_hash='...', bot_token='...')

# 仅匹配YouTube链接的文本消息,排除机器人自身消息
@app.on_message(filters.regex(r'https?://(www\.)?youtube\.com/watch\?v=|https?://youtu\.be/') & ~filters.me)
async def send_video(client, message):
    URL = message.text
    video_path = 'video.mp4'
    try:
        yt = YouTube(URL)
        ys = yt.streams.get_highest_resolution()
        # 同步下载视频,完成后才会继续执行
        ys.download(filename=video_path)
        print("视频下载成功")

        # 确认文件存在且可访问
        if not os.path.isfile(video_path):
            print("下载的视频文件不存在")
            return

        duration = int(yt.length)
        print(f"视频时长:{duration}秒")

        # 发送视频,添加标题作为字幕
        await client.send_video(
            chat_id=message.chat.id,
            video=video_path,
            duration=duration,
            caption=f"📥 {yt.title}"
        )
        print("视频发送成功")
    except Exception as e:
        print(f"执行出错:{str(e)}")
    finally:
        # 无论成功失败,都清理本地文件
        if os.path.exists(video_path):
            os.remove(video_path)
            print("本地视频文件已清理")

app.run()

内容的提问来源于stack exchange,提问作者Qaserd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:45:23