修改MP4的tkhd/stsd盒后FFprobe不识别新分辨率求助
问题根源与解决思路
为什么Exiftool生效但FFprobe不识别?
两者读取视频宽高的逻辑完全不同:
- Exiftool仅读取MP4容器的顶层元数据结构(tkhd、stsd盒),所以修改这些容器头后,它直接返回新的宽高值
- FFprobe会深度解析H.264编码流内部的序列参数集(SPS),这是视频编码阶段写入的核心配置,其中存储了编码层面的真实宽高(对应
coded_width/height)。它优先采用SPS中的数据,完全不受容器头修改的影响。你提到的ff_h264_decode_seq_parameter_set就是FFmpeg负责解析SPS的核心函数。
解决方法
要让FFprobe识别新的宽高参数,必须同时修改两个部分:
- 保留你已完成的MP4容器元数据修改(tkhd、stsd盒)
- 修改H.264流中的SPS数据,将其中的宽高字段更新为目标值(300x400)
注意事项
- SPS是二进制格式的NALU单元,需要解析其结构找到宽高对应字段修改,修改后需重新计算校验值,否则可能导致视频无法正常播放
- 若不想手动解析SPS,可借助FFmpeg工具同步修改容器头与SPS,这种操作仅修改元数据,不会改变视频像素数据(符合你“不缩放”的需求)
修改容器头的Python代码示例
import struct def modify_tkhd_box(file_path, new_width, new_height): # 定位tkhd盒位置(实际需根据MP4结构完善定位逻辑) with open(file_path, 'r+b') as f: # 示例:假设已找到tkhd盒中宽高的偏移位置 f.seek(0x100) # 替换为实际width偏移 f.write(struct.pack('>I', new_width)) f.seek(0x104) # 替换为实际height偏移 f.write(struct.pack('>I', new_height)) def modify_stsd_box(file_path, new_width, new_height): # 定位stsd盒中视频轨道参数位置(实际需根据MP4结构完善定位逻辑) with open(file_path, 'r+b') as f: # 示例:假设已找到stsd盒中宽高的偏移位置 f.seek(0x200) # 替换为实际width偏移 f.write(struct.pack('>H', new_width)) f.seek(0x202) # 替换为实际height偏移 f.write(struct.pack('>H', new_height)) modify_tkhd_box("test.mp4", 300, 400) modify_stsd_box("test.mp4", 300, 400)
内容的提问来源于stack exchange,提问作者James W.
相关产品推荐
相关产品推荐

