☰
aiogram 的 VideoQuality 类型详解:视频质量对象的结构、字段与应用实战
2026/10/13 6:42:37 网站建设 项目流程
  • 后端
  • 即时通讯
  • API设计

【免费下载链接】aiogram

aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio

项目地址:https://gitcode.com/gh_mirrors/ai/aiogram
点击查看免费下载

导读

本文围绕 aiogram 框架中的VideoQuality类型展开,完整讲解该对象的全部字段定义、与Video/Message对象的嵌套关系、实例化与取值方式,并结合仓库源码与测试用例,展示如何在异步 Bot 中读取视频多质量版本并使用file_id完成下载。读完本文,你将掌握VideoQuality的底层数据结构、字段语义(含大文件file_size的整数精度陷阱)以及它在真实消息处理场景中的完整调用链。


一、VideoQuality 是什么

VideoQuality是 aiogram 中用于表示“特定质量视频文件”的 Telegram 对象类型,对应 Telegram Bot API 中的VideoQuality对象(源码定义于 aiogram/types/video_quality.py)。

它的核心职责是:当一条视频消息存在多个清晰度版本时,为每一个版本单独建模——每个版本都是一个独立的文件,拥有自己的file_id、尺寸、编码格式与体积信息。

该类型在 aiogram 的 API 文档中通过 docs/api/types/video_quality.rst 以automodule指令自动生成,并在aiogram.types命名空间下以VideoQuality名称公开导出(见 aiogram/types/init.py 与第 898 行的导入语句)。

从继承结构看,VideoQuality继承自TelegramObject(见 aiogram/types/base.py),因此它天然具备 aiogram 所有 Telegram 对象的基础能力:

  • Pydantic 数据校验:字段类型不符时会在实例化阶段直接报错;
  • frozen=True不可变模型:对象创建后字段不可被修改;
  • 冗余字段容忍:extra="allow"允许 Telegram 未来新增字段而不破坏兼容性;
  • 对象与 Bot 上下文绑定:可通过BotContextController关联当前 Bot 实例,便于后续直接调用下载等操作。

二、字段结构与语义详解

VideoQuality共定义了 5 个字段,其中 4 个为必填字段,1 个为可选字段:

字段名类型是否必填含义
file_idstr必填该质量版本文件的标识符,可用于下载或复用该文件
file_unique_idstr必填文件的唯一标识,同一文件在不同 Bot 间保持恒定,但不能用于下载或复用
widthint必填视频宽度(像素)
heightint必填视频高度(像素)
codecstr必填视频编码格式,例如'h264'、'h265'或'av01'
file_sizeint \| None可选,默认None文件大小(字节)

2.1 file_id 与 file_unique_id 的区别

这是最容易混淆的一组字段:

  • file_id:每次通过 Bot API 获取到的文件标识符,可用于getFile查询、download下载,以及在sendVideo等方法中直接复用该文件。它仅在当前 Bot 的范围内有效。
  • file_unique_id:文件的全局唯一标识,跨 Bot、跨时间是恒定的,适合作为数据库中的主键或去重依据,但不能用来下载或重新发送文件。

2.2 codec 字段

codec描述该质量版本视频使用的编码标准。Telegram 官方文档中给出了'h264'、'h265'、'av01'等示例,实际取值取决于发送方上传的编码格式。你的业务代码可以根据codec判断是否支持直接转发,或在多端播放前做转码决策。

2.3 file_size 的大整数精度陷阱

file_size是可选字段(默认None),其文档注释(见源码第 25-26 行)特别强调了一个容易踩坑的点:

文件大小可能超过 2^31,部分编程语言在解释该值时会遇到困难或出现静默缺陷;但该值最多只有 52 个有效位,因此有符号 64 位整数或双精度浮点数类型都能安全存储它。

在 Python 中int是任意精度整数,天然不受此限制;但如果你的项目需要将file_size传入其他语言栈(如通过 JSON 交给前端、Go、Java 等),应使用 64 位有符号整数或 double 类型承载,避免溢出。


三、VideoQuality 在对象树中的位置

VideoQuality并不是独立出现的类型,它嵌套在Video对象中,而Video又挂在Message对象上。完整层级关系如下:

Message └── video: Video | None └── qualities: list[VideoQuality] | None └── VideoQuality { file_id, file_unique_id, width, height, codec, file_size }

对应源码位置:

  • Message.video字段定义在 aiogram/types/message.py;
  • Video.qualities字段定义在 aiogram/types/video.py,类型为list[VideoQuality] | None,表示“视频可用的质量版本列表”,可选;
  • Video还包含file_id、file_unique_id、width、height、duration、thumbnail、cover、start_timestamp、file_name、mime_type、file_size等字段。

这意味着:一条视频消息(Message.video)本身代表“默认/原始版本”,而qualities列表则提供了用户可以选择的其他清晰度。二者都各自持有独立的file_id,下载时互不干扰。


四、实战:从消息中读取质量版本

下面展示如何在 aiogram 的消息处理器中,从一条视频消息中枚举并读取所有可用质量版本:

from aiogram import Router, types router = Router() @router.message(lambda message: message.video is not None) async def handle_video(message: types.Message) -> None: video = message.video # 默认/原始版本的基本信息 await message.answer( f"原始版本:{video.width}x{video.height}," f"{video.duration} 秒,codec 见文件详情" ) # 枚举所有可用质量版本 if video.qualities: lines = ["可用质量版本:"] for q in video.qualities: size_mb = None if q.file_size is not None: size_mb = round(q.file_size / (1024 * 1024), 2) lines.append( f"- {q.width}x{q.height} | codec: {q.codec} | " f"file_id: {q.file_id[:12]}... " f"({'大小 ' + str(size_mb) + ' MB' if size_mb is not None else '大小未知'})" ) await message.answer("\n".join(lines)) else: await message.answer("该视频未提供其他质量版本。")

要点说明:

  1. 使用message.video是否为None来筛选视频消息;
  2. video.qualities为None时表示没有附加质量版本,需判空后再遍历;
  3. 每个q都是独立的VideoQuality实例,可直接读取字段,也可在需要时复用其file_id发送该版本。

五、实战:按质量下载视频文件

Telegram 官方限制 Bot 当前可下载的文件最大为 20 MB(见 aiogram/types/file.py 与 aiogram/methods/get_file.py 的注释)。下载VideoQuality对应的文件,与下载其他文件完全一致——通过Bot.download()方法即可完成。

Bot.download()的底层逻辑位于 aiogram/client/bot.py,其工作流程为:

  1. 从传入对象读取file_id(VideoQuality满足 Downloadable 协议,只要求具有file_id属性);
  2. 调用bot.get_file(file_id)获取文件的file_path(对应 GetFile 方法);
  3. 调用download_file()以流式分块方式(默认chunk_size=65536,即 64 KB)写入目标。

示例:下载指定质量版本到本地文件或内存流

import io async def download_quality(video: types.Video, target_width: int = 1920) -> None: if not video.qualities: return # 按宽度挑选目标质量版本 quality = next( (q for q in video.qualities if q.width == target_width), video.qualities[0], ) # 方式一:下载到本地文件 await bot.download(quality, destination=f"video_{quality.width}x{quality.height}.mp4") # 方式二:下载到内存(BytesIO),便于进一步处理 buffer = io.BytesIO() await bot.download(quality, destination=buffer) buffer.seek(0)

bot.download()支持str或任意具备file_id属性的对象作为输入,因此可以直接把VideoQuality实例传进去。需要自定义超时或分块大小时,可传入timeout(默认 30 秒)与chunk_size(默认 64 KB)参数。


六、源码级验证:构造与测试用例

aiogram 仓库为VideoQuality提供了完整的单元测试,位于 tests/test_api/test_types/test_video_quality.py,覆盖了三个典型场景,可以直接作为使用参考:

1. 基础实例化(测试第 6-24 行):不带file_size构造对象,断言所有必填字段取值正确,且file_size默认为None:

VideoQuality( file_id="abc123", file_unique_id="unique123", width=1920, height=1080, codec="h264", ) # -> file_size is None

2. 带 file_size 实例化(测试第 26-36 行):显式传入file_size=1048576,验证可选字段正常保存。

3. 嵌套在 Video 中(测试第 38-62 行):构造包含两个VideoQuality元素的Video.qualities列表,验证长度、索引访问与各字段取值:

video = Video( file_id="video123", file_unique_id="unique_video123", width=1920, height=1080, duration=120, qualities=[ VideoQuality(file_id="abc123", file_unique_id="unique123", width=1920, height=1080, codec="h264"), VideoQuality(file_id="q2", file_unique_id="uq2", width=1280, height=720, codec="h264", file_size=524288), ], ) assert len(video.qualities) == 2 assert video.qualities[0].width == 1920 assert video.qualities[1].file_size == 524288

这些测试同时印证了:VideoQuality是普通 Pydantic 模型对象,支持关键字参数直接构造,可独立使用也可嵌套在Video中。

另外,从 CHANGES.rst 与 CHANGES.rst 的变更记录可以确认,VideoQuality类型及Video.qualities字段是作为新特性引入的:Video新增qualities字段(类型为list[VideoQuality]),同时新增了描述可用视频质量选项的VideoQuality类型。


七、常见问题与注意事项

  1. qualities可能为None:并非所有视频消息都会附带多质量版本,访问前务必判空,避免AttributeError。
  2. file_size可能为None:Telegram 不保证始终返回文件大小,展示体积信息时需做可选处理。
  3. 不要用file_unique_id下载:它只能作为去重与主键用途,下载必须使用file_id。
  4. 下载大小限制:Bot 可下载文件上限为 20 MB(当前官方限制),超大视频请使用file_size提前判断后再决定是否下载。
  5. file_id有有效期与作用域:getFile返回的下载链接保证至少 1 小时有效;file_id仅在当前 Bot 范围内可用,跨 Bot 复用需先获取对应 Bot 自己的file_id。

八、小结

VideoQuality虽然只是一个承载 6 个字段的轻量对象,但在视频类 Bot 业务中承担着“多清晰度版本枚举与分发”的关键职责。结合本文内容,你可以:

  • 通过message.video.qualities枚举所有质量版本;
  • 依据width、height、codec、file_size做出智能选择(如自动挑选最小版本转发、限制带宽场景);
  • 利用file_id配合Bot.download()完成任意质量版本的流式下载。

深入源码进一步学习时,推荐按如下路径阅读:

  • 类型定义:aiogram/types/video_quality.py
  • 嵌套载体:aiogram/types/video.py
  • 消息挂载点:aiogram/types/message.py
  • 下载实现:aiogram/client/bot.py
  • 单元测试:tests/test_api/test_types/test_video_quality.py
  • 变更记录:CHANGES.rst
  • 后端
  • 即时通讯
  • API设计

【免费下载链接】aiogram

aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio

项目地址:https://gitcode.com/gh_mirrors/ai/aiogram
点击查看免费下载

相关推荐

上一篇:AntiDupl 图片去重:10分钟完成一次内容级查重,释放几十GB磁盘空间
下一篇:Visual C++ 运行库安装失败怎么排查?3 条命令完成定位与修复

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询