在Telegram机器人开发中,发送视频消息是高频需求,但很多开发者发现:直接调用sendVideo接口时,用户看到的视频预览往往只是默认的第一帧,既不美观也不够直观。想要让视频拥有定制化的封面(缩略图),需要理解Telegram Bot API对缩略图参数的底层要求,并正确上传文件。本文将基于最新Bot API文档,从零开始演示如何发送带自定义缩略图的视频文件,并提供可直接落地的Python代码示例。
一、理解sendVideo的基本参数与缩略图机制
Telegram Bot API的sendVideo方法用于发送视频文件,核心参数包括:
- chat_id:目标聊天ID,可以是用户ID、群组ID或频道ID。
- video:视频文件,支持以
file_id、HTTP URL或multipart/form-data上传的新文件。 - thumbnail(或旧版
thumb):可选,用于设置视频封面的图片文件。同样支持file_id、URL或新上传的图片。 - caption:视频附带的说明文字。
- supports_streaming:是否启用流式播放。
值得注意的是:Telegram要求缩略图必须是JPEG格式(实际也支持PNG,但官方文档建议使用JPEG),且文件大小不超过200KB,尺寸建议为320x320像素或更小。如果缩略图不符合规范,API会返回错误。
二、发送视频的三种方式与缩略图搭配
方式1:使用file_id发送已上传的视频
如果你的机器人之前已经上传过该视频并获得file_id,可以复用该ID,同时传入一个已存在的file_id作为缩略图。这种方式最快,但要求缩略图也已在Telegram服务器上。
import requests
TOKEN = "YOUR_BOT_TOKEN"
url = f"https://api.telegram.org/bot/sendVideo"
payload = {
"chat_id": "@mychannel",
"video": "BAAC...(视频file_id)",
"thumbnail": "AAMC...(缩略图file_id)",
"caption": "带封面的测试视频"
}
r = requests.post(url, json=payload)
print(r.json())方式2:通过HTTP URL发送视频和缩略图
如果视频和缩略图都托管在外部服务器上,可以直接将URL传给API。Telegram会同时下载两者。注意,URL必须HTTPS,且Telegram服务器能访问。
payload = {
"chat_id": "@mychannel",
"video": "https://example.com/video.mp4",
"thumbnail": "https://example.com/thumb.jpg",
"caption": "网络视频带封面"
}
r = requests.post(url, json=payload)方式3:本地文件直接上传(multipart/form-data)
最灵活的方式是通过multipart/form-data同时上传视频和缩略图。Python的requests库天然支持文档要求,但缩略图字段必须显式指定为文件,且字段名应为thumbnail(新版API)或thumb(旧版兼容)。
import requests
TOKEN = "YOUR_BOT_TOKEN"
url = f"https://api.telegram.org/bot/sendVideo"
files = {
"video": open("movie.mp4", "rb"),
"thumbnail": open("cover.jpg", "rb")
}
data = {
"chat_id": "@mychannel",
"caption": "本地视频带自定义封面"
}
r = requests.post(url, data=data, files=files)
print(r.json())注意:在multipart上传时,缩略图字段不能使用files字典以外的其他方式传递。部分开发者误将缩略图放在data中作为base64字符串,这会导致API报错。
三、关键注意事项与常见错误排查
- 缩略图格式与大小:Telegram服务器会拒绝超过200KB的缩略图,建议压缩到90KB以内,并使用JPEG格式。PNG也可以,但JPEG兼容性最好。
- 视频与缩略图必须不同文件:你不能将同一个文件同时作为视频和缩略图。
- 异步发送与超时:如果视频文件较大,网络请求可能需要较长时间,务必在代码中设置合理的超时(例如30秒以上)。
- 错误代码400:如果日志显示“Bad Request: wrong file identifier”或“image process failed”,请检查缩略图是否有效,或是否超过大小限制。
- 使用BotFather设置默认缩略图?:BotFather没有提供全局缩略图配置,每个视频消息都要单独指定。
四、进阶:如何自动生成视频缩略图
如果你没有现成的封面图,可以用ffmpeg从视频中提取某一帧作为缩略图。以下命令提取视频第5秒的画面,并压缩为320x320的JPEG:
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 -vf "scale=320:320:force_original_aspect_ratio=decrease,pad=320:320:(ow-iw)/2:(oh-ih)/2" -q:v 2 thumb.jpg在Python中,你可以调用subprocess执行上述命令,然后立即将生成的thumb.jpg作为缩略图上传。
五、完整示例:从本地文件到带封面视频推送
下面是一个完整的Python函数,封装了本地视频上传并附带缩略图的过程,同时包含异常处理和日志。
import requests
import logging
import os
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
TOKEN = "YOUR_BOT_TOKEN"
def send_video_with_thumbnail(chat_id, video_path, thumb_path, caption=""):
"""发送视频并设置缩略图"""
url = f"https://api.telegram.org/bot/sendVideo"
# 检查文件是否存在
if not os.path.isfile(video_path) or not os.path.isfile(thumb_path):
logger.error("文件不存在")
return None
# 准备multipart数据
with open(video_path, "rb") as vf, open(thumb_path, "rb") as tf:
files = {
"video": vf,
"thumbnail": tf
}
data = {"chat_id": chat_id, "caption": caption}
try:
r = requests.post(url, files=files, data=data, timeout=60)
r.raise_for_status()
result = r.json()
if result["ok"]:
logger.info("视频发送成功,ID: %s", result["result"]["message_id"])
return result["result"]
else:
logger.error("API返回错误: %s", result["description"])
except requests.exceptions.RequestException as e:
logger.error("请求异常: %s", e)
return None
# 使用示例
if __name__ == "__main__":
send_video_with_thumbnail("@mychannel", "demo.mp4", "cover.jpg", "看这个精彩瞬间!")六、总结与最佳实践
通过本文你应该掌握了Telegram机器人发送视频并设置缩略图的三种方法。在实际开发中,推荐使用本地文件上传方式以保证灵活性,但要确保缩略图尺寸和体积符合要求。如果视频内容本身有很好的首帧,也可以不设置缩略图,Telegram会自动截取。若需要批量发送,建议预先将视频上传到Telegram获取file_id,后续仅需传输ID,可大幅减少流量消耗。