如何使用FFmpeg复制流并保留格式与元数据?添加指定数据流
解决FFmpeg复制数据流时丢失格式与元数据的问题
我懂你遇到的麻烦——明明用了-c copy来复制流,结果Input.mp4里的数据流2加到Final.mov后,格式和元数据都没保留下来。这其实是因为FFmpeg默认处理非视频/音频流(比如自定义数据流、元数据流)的时候,不会自动完整传递所有元数据,再加上MP4转MOV容器时,数据流的封装规则有差异,得加些额外参数来搞定。
第一步:先搞清楚数据流2的详细信息
在修改命令之前,先确认Input.mp4里流2的具体类型和元数据,用这个命令:
ffmpeg -i Input.mp4 -v trace 2>&1 | grep -A 20 "Stream #1:2"
或者用更简洁的ffprobe:
ffprobe -i Input.mp4 -show_streams -select_streams 2
这能帮你看到流的编码格式、元数据标签、流类型(比如是GPMF运动数据、自定义数据流还是其他),后续参数要根据这个来调整。
第二步:修改FFmpeg命令,保留数据流的格式与元数据
根据流的类型,调整原命令,核心是显式指定复制流的元数据,以及确保容器能识别该流:
通用版命令(适用于大多数数据流)
ffmpeg -y -i Output.mp4 -i Input.mp4 -c copy \ -map 0:0 -map 0:1 -map 1:2 \ -map_metadata 1:2 \ Final.mov
-map_metadata 1:2:这个参数是关键,它会把Input.mp4(第二个输入,索引1)里的流2的元数据,复制到输出文件对应的流中,避免元数据丢失。
如果是自定义/特殊数据流(比如GPMF)
如果你的流2是像运动相机的GPMF这类特殊数据流,MOV容器需要明确的流标签才能识别,要加-tag:d:2参数:
ffmpeg -y -i Output.mp4 -i Input.mp4 -c copy \ -map 0:0 -map 0:1 -map 1:2 \ -map_metadata 1:2 \ -tag:d:2 gpmf \ Final.mov
这里的gpmf是流的标签,要根据你第一步查到的流标签来替换(比如如果是其他类型,可能是text、subrip等)。
如果流2是字幕流
如果数据流2其实是字幕流,把参数改成针对字幕的:
ffmpeg -y -i Output.mp4 -i Input.mp4 -c:v copy -c:a copy -c:s copy \ -map 0:0 -map 0:1 -map 1:2 \ -map_metadata 1:s:2 \ Final.mov
第三步:验证结果
命令执行完后,用ffprobe检查Final.mov里的流2:
ffprobe -i Final.mov -show_streams -select_streams 2
对比Input.mp4里的流信息,确认编码格式、元数据都保留下来了。
补充说明
- MOV和MP4虽然同属QuickTime家族,但对非音视频流的封装规则有细微差别,
-c copy只是复制编码数据,元数据需要显式指定传递。 - 如果你的数据流有非常特殊的自定义元数据,可能需要用
-metadata:s:d:2 key=value手动补充,比如:-metadata:s:d:2 title="Original Motion Data" -metadata:s:d:2 author="Camera"
内容的提问来源于stack exchange,提问作者dzeek
相关产品推荐
相关产品推荐

