如何用Python通过二进制流获取视频的元数据(播放时长、分辨率等信息)?
网上一些获取媒体元数据的库如 moviepy,mutagen 等都是通过文件路径名作为输入. 把 bytes 存为文件然后再通过 filename 作为输入这样多此一举,还会占用磁盘 IO
如何像 PIL Image.open(io.BytesIO(file.body)) 这样直接读 bytes 数据就能获取元数据信息呢?
如何用Python通过二进制流获取视频的元数据(播放时长、分辨率等信息)?
h264 手动解析 pps 和 sps
用Python获取视频元数据,一个直接的方法是使用ffmpeg-python库,它封装了FFmpeg的功能。如果没装,先pip install ffmpeg-python。下面这个例子从二进制流中读取视频文件并提取关键信息:
import ffmpeg
import io
def get_video_metadata_from_bytes(video_bytes):
"""
从二进制数据中获取视频元数据。
参数:
video_bytes: 视频文件的二进制数据 (bytes)
返回:
包含时长、分辨率等信息的字典
"""
# 将字节数据包装成类文件对象
input_stream = io.BytesIO(video_bytes)
try:
# 使用ffmpeg.probe分析视频流
probe = ffmpeg.probe(
'pipe:0', # 从标准输入读取
format='mp4', # 根据实际情况调整格式
cmd='ffprobe' # 确保ffprobe在系统路径中
)
# 获取视频流信息(通常第一个视频流)
video_stream = next(
(stream for stream in probe['streams'] if stream['codec_type'] == 'video'),
None
)
if video_stream is None:
return {"error": "未找到视频流"}
# 提取关键信息
metadata = {
"duration": float(video_stream.get('duration', 0)), # 时长(秒)
"width": int(video_stream.get('width', 0)), # 宽度
"height": int(video_stream.get('height', 0)), # 高度
"codec": video_stream.get('codec_name', 'unknown'), # 编码格式
"bit_rate": video_stream.get('bit_rate', 'N/A'), # 比特率
"frame_rate": eval(video_stream.get('avg_frame_rate', '0/1')) # 帧率
}
return metadata
except ffmpeg.Error as e:
return {"error": f"FFmpeg错误: {e.stderr.decode()}"}
except Exception as e:
return {"error": f"处理失败: {str(e)}"}
# 使用示例
if __name__ == "__main__":
# 模拟从文件读取二进制数据
with open('example.mp4', 'rb') as f:
video_data = f.read()
# 获取元数据
result = get_video_metadata_from_bytes(video_data)
print("视频元数据:", result)
关键点说明:
- 二进制流处理:通过
io.BytesIO将字节数据转换为类文件对象,FFmpeg可以从标准输入(pipe:0)读取。 - 格式指定:
format参数需要根据实际视频格式调整(如mp4、avi、mov等)。 - 帧率计算:
avg_frame_rate返回字符串格式的分数(如"30/1"),用eval()转换为浮点数。 - 错误处理:FFmpeg可能因格式不支持或损坏文件而失败,需要适当捕获异常。
替代方案:如果不想依赖FFmpeg,可以用moviepy(pip install moviepy),它更简单但功能稍少:
from moviepy.editor import VideoFileClip
import io
def get_metadata_moviepy(video_bytes):
with io.BytesIO(video_bytes) as buffer:
buffer.write(video_bytes)
buffer.seek(0)
with VideoFileClip(buffer) as video:
return {
"duration": video.duration,
"size": video.size, # (width, height)
"fps": video.fps
}
总结:用ffmpeg-python处理二进制流最可靠。
这工作量也太大啦吧, 而且不止是 mp4 媒体文件有可能是 ogg, avi 等多种格式.感觉应该会有现成的轮子啊. 我一直没找到. 看 stackoverflow 也有人在问 https://stackoverflow.com/questions/17340292/python-get-media-file-metadata-from-byte-array
libmediainfo,有包括 Python 在内的多种语言的 API binding
看了下 pymediainfo 这个库,也是只有通过文件名来读取 : (
pymediainfo.MediaInfo.parse(“xxx.mp4”)
这个需求没必要用 python 去实现,直接通过 shell 调用获取到数据就行了,本地的用 ffmpeg,网络的用 ffprobe

