ffmpeg - 从现有的非分段、分段 MP4 文件创建 Init 文件
问题描述
我正在对较长的视频文件执行分块编码,其中我将原始文件拆分为单独编码的单独序列。这些序列是不同长度的文件,具体取决于场景剪辑出现的位置——它们的长度可能在 2 到 5 秒之间。它们都以 I 帧开头并且是独立的。
我的编码序列都是 MP4,例如:
test_0000.mp4
test_0001.mp4
test_0002.mp4
test_0003.mp4
test_0004.mp4
它们都有共同的属性:
$ mp4info test_0000.mp4
File:
major brand: isom
minor version: 200
compatible brand: isom
compatible brand: iso2
compatible brand: mp41
fast start: no
Movie:
duration: 2016 ms
time scale: 1000
fragments: no
...
现在,为了用 DASH 播放器播放这些,我必须创建一个初始化段和单独的分段 MP4。
mp4fragment
我可以生成在每个独立 MP4 文件上运行的分段MP4:
$ mp4info test_0000.m4s
File:
major brand: isom
minor version: 200
compatible brand: isom
compatible brand: iso2
compatible brand: mp41
compatible brand: iso5
fast start: yes
Movie:
duration: 2016 ms
time scale: 1000
fragments: yes
...
但显然,这些现在不符合规范,并且都包含一个moov
原子:
我需要的是只有一个moof
和mdat
框的单个媒体段,然后需要一个只有一个moov
框的初始化段。
如何从现有的已编码段生成它?
我知道这看起来像是一个 XY 问题。原则上,我可以在编码后直接对原始文件进行分段,并同时运行这些编码,例如使用 ffmpeg 的dash
muxer 或 MP4Box,但是:
- 关于最小和最大持续时间,几乎无法控制生成的段大小
- 这种方法不并行
我还检查了 Bento4;它似乎不提供此功能。FFmpeg 也没有。MP4Box 的行为类似。他们都假设你有一个长文件开始。
我看到我可以从这些“假片段”中拼接出ftyp
和moov
框,以创建一个初始化段。但我最终会得到包含多个 moof
和mdat
框的片段,这不符合规范——它只允许一个片段和媒体数据框:
4. 媒体细分
[…] 一个可选的片段类型框 (styp),后跟一个电影片段框 (moof),然后是一个或多个媒体数据框 (mdat)。
我想我可以忍受这个styp
不在场。
解决方案
我认为最简单的方法是使用MP4Box,有关详细信息,请参阅将碎片 MP4 拆分为多个 MP4 文件。
推荐阅读
- inno-setup - 调试重生的 Inno Setup 安装程序
- ruby-on-rails - 助手中的文本不会翻译
- android - 我的 Flutter App 在我的 Android Kitkat 4.4.4 平板电脑上不断崩溃
- sql - 列的 Oracle 更新查询数据屏蔽
- java - Pi 3 上的 OpenJFX 16ea 为 libprism_es2_monocle.so 引发 UnsatisfiedLinkError:libGLESv2.so
- r - data.table 过滤器不适用于 with()?
- c++ - 如何找到大数的斐波那契和?
- php - 在 PHP 同一页面上传递表单值
- laravel - 显示 Laravel 验证错误?
- ios - CocoaPods 找不到 pod "React/Core" 的兼容版本?