Java mp4parser 创建单个 .m4s 片段——无效的 moov 框
Java mp4parser to create a single .m4s fragment— invalid moov box
此用例是一项服务,可将一系列未压缩的 .wav 媒体片段手动编码为 .m4s 片段,以便通过 MPEG-DASH, using ffmpeg 将 .wav 压缩为.aac
sannies/mp4parser 到 assemble aac 音频到 .m4s 媒体片段。
我创建了 this public GitHub project 来完整重现该问题。
例如,这里是自定义 CustomFragmentMp4Builder.java class.
至关重要的是,我们能够为这个单个 .m4s 片段指定一个序列号(索引),我们将为每个媒体片段手动递增该序列号。
objective 是构建一个 .m4s 片段,包含框类型 SegmentTypeBox
、SegmentIndexBox
和 MovieFragmentBox
.作为参考,我使用 mp4parser 检查通过 ffmpeg -f hls
生成的 .m4s 片段。此规格可用here as a .yaml file
我的实现创建了一个没有错误的 MP4。但是,当单元测试尝试读取 ChunkMp4Builder 刚刚写入临时文件夹的文件时:
java.lang.RuntimeException: A cast to int has gone wrong. Please contact the mp4parser discussion group (3724673092)
at org.mp4parser.tools.CastUtils.l2i(CastUtils.java:30)
at org.mp4parser.support.AbstractBox.parse(AbstractBox.java:97)
at org.mp4parser.AbstractBoxParser.parseBox(AbstractBoxParser.java:116)
at org.mp4parser.BasicContainer.initContainer(BasicContainer.java:107)
at org.mp4parser.IsoFile.<init>(IsoFile.java:57)
at org.mp4parser.IsoFile.<init>(IsoFile.java:52)
at com.charneykaye.TestBase.getMp4Boxes(TestBase.java:116)
at com.charneykaye.CustomFragmentMp4BuilderTest.run(CustomFragmentMp4BuilderTest.java:78)
预期的框类型 SegmentTypeBox
、SegmentIndexBox
和 MovieFragmentBox
确实出现在输出中:
但是,文件末尾出现了一个未知类型的框:
由于 mdat
原子大小不正确,您的 m4s
片段无效。
例如在test5-128k-151304042.m4s
中,mdat
被标记为长度为16字节,但末尾有数据,文件大小为164884。
然后解析器尝试读取无效的偏移量。 avc5
不是原子,而是字符串“Lavc58.54.100”的一部分。读取为 3724673100 的长度也是无效的,并且大于 32 位整数的最大值,因此转换为 int 无效。
在您的实施中您有:
ParsableBox moov = createMovieFragmentBox(movie);
isoFile.addBox(moov);
List<SampleSizeBox> stszs = Path.getPaths(moov, "trak/mdia/minf/stbl/stsz");
// ...
protected MovieFragmentBox createMovieFragmentBox(Movie movie) {
MovieFragmentBox mfb = new MovieFragmentBox();
// ...
}
这不是 moov
原子,而是 moof
。那里没有 stsz
并且样本大小的总和为 0,因此 mdat
的总计算大小为 16 + 0.
moov
应该在初始化段中。
此用例是一项服务,可将一系列未压缩的 .wav 媒体片段手动编码为 .m4s 片段,以便通过 MPEG-DASH, using ffmpeg 将 .wav 压缩为.aac sannies/mp4parser 到 assemble aac 音频到 .m4s 媒体片段。
我创建了 this public GitHub project 来完整重现该问题。
例如,这里是自定义 CustomFragmentMp4Builder.java class.
至关重要的是,我们能够为这个单个 .m4s 片段指定一个序列号(索引),我们将为每个媒体片段手动递增该序列号。
objective 是构建一个 .m4s 片段,包含框类型 SegmentTypeBox
、SegmentIndexBox
和 MovieFragmentBox
.作为参考,我使用 mp4parser 检查通过 ffmpeg -f hls
生成的 .m4s 片段。此规格可用here as a .yaml file
我的实现创建了一个没有错误的 MP4。但是,当单元测试尝试读取 ChunkMp4Builder 刚刚写入临时文件夹的文件时:
java.lang.RuntimeException: A cast to int has gone wrong. Please contact the mp4parser discussion group (3724673092)
at org.mp4parser.tools.CastUtils.l2i(CastUtils.java:30)
at org.mp4parser.support.AbstractBox.parse(AbstractBox.java:97)
at org.mp4parser.AbstractBoxParser.parseBox(AbstractBoxParser.java:116)
at org.mp4parser.BasicContainer.initContainer(BasicContainer.java:107)
at org.mp4parser.IsoFile.<init>(IsoFile.java:57)
at org.mp4parser.IsoFile.<init>(IsoFile.java:52)
at com.charneykaye.TestBase.getMp4Boxes(TestBase.java:116)
at com.charneykaye.CustomFragmentMp4BuilderTest.run(CustomFragmentMp4BuilderTest.java:78)
预期的框类型 SegmentTypeBox
、SegmentIndexBox
和 MovieFragmentBox
确实出现在输出中:
但是,文件末尾出现了一个未知类型的框:
由于 mdat
原子大小不正确,您的 m4s
片段无效。
例如在test5-128k-151304042.m4s
中,mdat
被标记为长度为16字节,但末尾有数据,文件大小为164884。
然后解析器尝试读取无效的偏移量。 avc5
不是原子,而是字符串“Lavc58.54.100”的一部分。读取为 3724673100 的长度也是无效的,并且大于 32 位整数的最大值,因此转换为 int 无效。
在您的实施中您有:
ParsableBox moov = createMovieFragmentBox(movie);
isoFile.addBox(moov);
List<SampleSizeBox> stszs = Path.getPaths(moov, "trak/mdia/minf/stbl/stsz");
// ...
protected MovieFragmentBox createMovieFragmentBox(Movie movie) {
MovieFragmentBox mfb = new MovieFragmentBox();
// ...
}
这不是 moov
原子,而是 moof
。那里没有 stsz
并且样本大小的总和为 0,因此 mdat
的总计算大小为 16 + 0.
moov
应该在初始化段中。