使用Telethon上传视频遇问题:黑缩略图、元数据错误及流播放故障
Telethon上传Telegram视频的问题与解决方法
问题概述
使用Telethon库向Telegram上传视频时遇到以下问题:
- 视频常显示黑缩略图
- 视频无法流播放或出现流播放故障
- 显示错误的视频元数据(时长、宽高)
- 偶尔视频时长显示为00:00,或文件大小小于预期
已尝试用hachoir库提取元数据,但未彻底解决。同一视频通过Telegram应用手动上传正常,机器人上传则出现问题。
代码示例
import os from telethon import TelegramClient from hachoir.metadata import extractMetadata from hachoir.parser import createParser from telethon.tl.types import DocumentAttributeVideo api_id = 'YOUR_API_ID' api_hash = 'YOUR_API_HASH' bot_token = 'YOUR_BOT_TOKEN' chat_id = 'CHAT_ID' video_path = "videos/sample_video.mp4" client = TelegramClient('bot', api_id, api_hash).start(bot_token=bot_token) async def upload_video(): metadata = extractMetadata(createParser(video_path)) duration = metadata.get('duration').seconds if metadata.has('duration') else 0 width = metadata.get('width') if metadata.has('width') else 640 height = metadata.get('height') if metadata.has('height') else 360 await client.send_file( chat_id, video_path, attributes=[ DocumentAttributeVideo( duration=duration, w=width, h=height, supports_streaming=True ) ] ) with client: client.loop.run_until_complete(upload_video())
环境
Telethon==1.34.0 cryptg==0.4.0 tqdm==4.66.2 hachoir==3.3.0
复现步骤
- 使用Telethon通过hachoir解析器提取的元数据(时长、宽高)上传视频
- 观察到上传的视频可能显示黑缩略图、时长错误(如00:00)、无法正常流播放
- 通过Telegram应用手动上传同一视频,查看正确表现
预期与实际行为
预期行为
- 视频上传后显示正确缩略图,可正常流播放,元数据(时长、宽高)准确
实际行为
- 视频频繁显示错误元数据(如00:00时长、不正确的宽高)
- 视频显示黑缩略图或无法流播放
- 偶尔通过机器人上传的视频文件大小小于预期
解决方案
1. 替换元数据提取工具,提高准确性
hachoir对部分视频格式的解析存在局限性,改用ffmpeg提取更可靠的元数据:
import subprocess def get_video_metadata(video_path): # 调用ffmpeg提取视频时长、宽高 result = subprocess.run( [ 'ffmpeg', '-i', video_path, '-v', 'quiet', '-show_entries', 'stream=duration,width,height', '-of', 'csv=p=0' ], capture_output=True, text=True ) if result.returncode != 0: return 0, 640, 360 data = result.stdout.strip().split(',') duration = int(float(data[0])) if len(data)>=1 else 0 width = int(data[1]) if len(data)>=2 else 640 height = int(data[2]) if len(data)>=3 else 360 return duration, width, height
替换原代码中hachoir的提取逻辑,ffmpeg能兼容更多视频编码和容器格式,元数据识别更精准。
2. 手动生成缩略图,解决黑图问题
Telethon默认生成的缩略图可能失效,手动提取视频帧作为自定义缩略图:
import tempfile import os def generate_thumbnail(video_path): # 创建临时文件存储缩略图 temp_file = tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) temp_path = temp_file.name temp_file.close() # 提取视频第1秒的帧作为缩略图 subprocess.run( ['ffmpeg', '-i', video_path, '-ss', '00:00:01.0', '-vframes', '1', '-q:v', '2', temp_path], capture_output=True ) return temp_path # 修改upload_video函数,添加缩略图参数 async def upload_video(): check_file_integrity(video_path) duration, width, height = get_video_metadata(video_path) thumb_path = generate_thumbnail(video_path) await client.send_file( chat_id, video_path, thumb=thumb_path, attributes=[ DocumentAttributeVideo( duration=duration, w=width, h=height, supports_streaming=True ) ] ) os.unlink(thumb_path) # 上传后清理临时文件
3. 添加文件完整性校验,避免上传损坏文件
文件大小异常可能源于文件损坏或读取失败,上传前校验文件:
def check_file_integrity(video_path): if not os.path.exists(video_path): raise FileNotFoundError("视频文件不存在") file_size = os.path.getsize(video_path) if file_size == 0: raise ValueError("视频文件为空") return file_size
在upload_video函数开头调用此方法,提前拦截无效文件。
4. 调整Telethon上传参数,确保视频类型识别正确
添加force_document=False强制按视频类型上传,避免Telegram误判为文档:
await client.send_file( chat_id, video_path, thumb=thumb_path, force_document=False, # 明确指定为视频而非文档 attributes=[ DocumentAttributeVideo( duration=duration, w=width, h=height, supports_streaming=True ) ] )
注意事项
- 确保运行环境安装了ffmpeg:Linux执行
apt install ffmpeg,macOS执行brew install ffmpeg - 优先使用H.264编码的视频,这是Telegram支持最完善的编码格式
- 升级Telethon到最新版本,修复已知上传bug:
pip install --upgrade telethon
内容的提问来源于stack exchange,提问作者Unique Shadows
相关产品推荐
相关产品推荐

