如何将下载的CMAF(.cmfv/.cmfa)流文件合并转换为MP4?
解决CMAF分片合并与转MP4的问题
你的代码里的关键错误
- 文件打开模式错误:媒体文件属于二进制格式,必须用
rb(读二进制)和wb(写二进制)模式打开,使用文本模式(r/w)会直接损坏二进制数据,这是FFmpeg无法读取合并文件的核心原因。 - 写入逻辑无效:直接将文件对象
portion写入目标文件是错误操作,需要先读取分片文件的二进制内容再写入。 - FFmpeg调用顺序错误:
ffmpeg-python的正确用法是先指定输入文件,再指定输出文件,且输入参数需传入文件路径,而非已打开的文件对象。
修正后的合并+转换代码:
# 合并视频分片(确保按播放顺序遍历,比如按文件名排序) combined_cmfv = "path/to/combined.cmfv" with open(combined_cmfv, "wb") as out_f: for file in sorted(folder): if file.endswith(".cmfv"): with open(file, "rb") as in_f: out_f.write(in_f.read()) # 合并音频分片 combined_cmfa = "path/to/combined.cmfa" with open(combined_cmfa, "wb") as out_f: for file in sorted(folder): if file.endswith(".cmfa"): with open(file, "rb") as in_f: out_f.write(in_f.read()) # 用ffmpeg-python转成带音频的MP4 import ffmpeg output_mp4 = "path/to/final.mp4" # 直接复制编码格式,避免重新编码浪费时间 ffmpeg.input(combined_cmfv).input(combined_cmfa).output(output_mp4, vcodec="copy", acodec="copy").run()
更省心的FFmpeg直接合并法
无需手动拼接分片,用FFmpeg的concat demuxer可直接按顺序合并分片,步骤如下:
- 创建
video_segments.txt,按播放顺序列出所有cmfv分片的路径,格式示例:
file 'path/to/seg_001.cmfv' file 'path/to/seg_002.cmfv' file 'path/to/seg_003.cmfv'
- 同样创建
audio_segments.txt列出所有cmfa分片。 - 执行FFmpeg合并转码命令:
ffmpeg.input("video_segments.txt", format="concat", safe=0).input("audio_segments.txt", format="concat", safe=0).output(output_mp4, vcodec="copy", acodec="copy").run()
注:
safe=0用于允许使用绝对路径,若使用相对路径可省略该参数。
关于CMAF合并的补充说明
CMAF分片基于ISO-BMFF(MP4的底层格式),因此按播放顺序进行二进制拼接分片是完全合法的,FFmpeg能够识别这类拼接后的文件。但必须保证分片顺序与流媒体服务器推送的顺序完全一致,否则会出现视频跳帧、卡顿甚至无法播放的问题。
内容的提问来源于stack exchange,提问作者Logan Price
相关产品推荐
相关产品推荐

