5

此用例是一项服务,它手动将一系列未压缩的 .wav 媒体片段编码为.m4s片段以通过MPEG-DASH进行广播,使用ffmpeg将 .wav 压缩为 .aac 并使用 sannies/mp4parser将 aac 音频组装成. m4s媒体片段。

我创建了这个公共 GitHub 项目来完整地重现这个问题。

例如,这是自定义的CustomFragmentMp4Builder.java类。

至关重要的是,我们能够使用序列号(索引)指定这个单个 .m4s 片段,我们将为每个媒体片段手动递增该序列号。

目标是构建一个包含盒子类型、和的.m4s片段。作为参考,我使用mp4parser来检查通过.m4s生成的片段。该规范在此处以 .yaml 文件的形式提供SegmentTypeBoxSegmentIndexBoxMovieFragmentBoxffmpeg -f hls

我的实现创建了一个没有错误的 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)

预期的框类型SegmentTypeBoxSegmentIndexBoxMovieFragmentBoxdo 出现在输出中:

预期的框类型 SegmentTypeBox、SegmentIndexBox 和 MovieFragmentBox 确实出现在输出中

但是,在文件末尾出现了一个未知类型的框:

似乎有一个未知类型的框,出现在文件的末尾。

4

1 回答 1

3

m4s由于mdat原子大小不正确,您的段无效。

例如在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应该在初始化段中。

于 2021-10-21T20:00:35.593 回答