首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java mp4parser输出为空

Java mp4parser输出为空
EN

Stack Overflow用户
提问于 2021-10-23 01:48:24
回答 1查看 156关注 0票数 0

此用例是一种服务,它手动地将一系列未压缩的.wav媒体段编码成.m4s片段,通过MPEG-破折号进行广播,使用ffmpeg将.wav压缩到.aac,并使用sannies/mp4解析器将aac音频组装成.m4s媒体片段。

我创建这个公共GitHub项目是为了完整地再现这个问题。

例如,下面是定制的ChunkFragmentM4sBuilder.java类。

第一个使用MP4框的示例可以工作,因为我能够生成一个初始化的MP4 +一系列片段M4s文件,然后这些文件可以连接起来形成一个可播放的MPEG4流。

注意:这个用例要求每个媒体段都是从一个单独生成的源段编码,而不是使用像MP4Box这样的工具从一个连续的音频源中流。

通过mp4parser手动构建媒体段的尝试总体上仍然失败,是因为下面使用的ChunkFragmentM4sBuilder.java编写的片段格式错误。但我很难理解它们到底是如何变形的。

比较ChunkFragmentM4sBuilderTest.log.txtMP4BoxTest.log.txt这两个测试日志对我很有帮助。

通过Java mp4parser (畸形)

前一个日志来自ChunkFragmentM4sBuilderTest.java,它导致连接的测试输出test-java-mp4parser.mp4,实际上它是空的:

代码语言:javascript
复制
Files.deleteIfExists(Path.of(m4sFilePath));
AACTrackImpl aacTrack=new AACTrackImpl(new FileDataSourceImpl(aacFilePath));
Movie movie=new Movie();
movie.addTrack(aacTrack);
Container mp4file=new ChunkFragmentM4sBuilder(hz,seconds,seqNum,bufferSize).build(movie);
FileChannel fc=new FileOutputStream(m4sFilePath).getChannel();
mp4file.writeContainer(fc);
fc.close();

级联盒:

代码语言:javascript
复制
FileTypeBox[majorBrand=iso5;minorVersion=512;compatibleBrand=iso6;compatibleBrand=mp41]
MovieBox[MovieHeaderBox[creationTime=Thu Dec 31 16:00:00 PST 1903;modificationTime=Thu Dec 31 16:00:00 PST 1903;timescale=1000;duration=0;rate=1.0;volume=1.0;matrix=Rotate 0°;nextTrackId=2];TrackBox[TrackHeaderBox[creationTime=Thu Dec 31 16:00:00 PST 1903;modificationTime=Thu Dec 31 16:00:00 PST 1903;trackId=1;duration=0;layer=0;alternateGroup=1;volume=1.0;matrix=Rotate 0°;width=0.0;height=0.0];EditBox[EditListBox{entries=[Entry{segmentDuration=0, mediaTime=1024, mediaRate=1.0}]}];MediaBox[MediaHeaderBox[creationTime=Thu Dec 31 16:00:00 PST 1903;modificationTime=Thu Dec 31 16:00:00 PST 1903;timescale=48000;duration=0;language=und];HandlerBox[handlerType=soun;name=SoundHandler];MediaInformationBox[SoundMediaHeaderBox[balance=0.0];DataInformationBox[DataReferenceBox[DataEntryUrlBox[]]];SampleTableBox[SampleDescriptionBox[AudioSampleEntry{bytesPerSample=0, bytesPerFrame=0, bytesPerPacket=0, samplesPerPacket=0, packetSize=0, compressionId=0, soundVersion=0, sampleRate=48000, sampleSize=16, channelCount=2, boxes=[org.mp4parser.boxes.iso14496.part14.ESDescriptorBox@bed094d2]}];TimeToSampleBox[entryCount=0];SampleToChunkBox[entryCount=0];SampleSizeBox[sampleSize=0;sampleCount=0];StaticChunkOffsetBox[entryCount=0]]]]];MovieExtendsBox[org.mp4parser.boxes.iso14496.part12.TrackExtendsBox@11e7301d];UserDataBox[MetaBox[HandlerBox[handlerType=mdir;name=];AppleItemListBox[org.mp4parser.boxes.apple.AppleEncoderBox@691fba4]]]]
SegmentTypeBox[majorBrand=msdh;minorVersion=0;compatibleBrand=msdh;compatibleBrand=msix]
SegmentIndexBox{entries=[Entry{referenceType=0, referencedSize=160944, subsegmentDuration=480000, startsWithSap=1, sapType=0, sapDeltaTime=0}], referenceId=1, timeScale=48000, earliestPresentationTime=0, firstOffset=0, reserved=0}
MovieFragmentBox[MovieFragmentHeaderBox{sequenceNumber=151304042};TrackFragmentBox[TrackFragmentHeaderBox{trackId=1, baseDataOffset=-1, sampleDescriptionIndex=0, defaultSampleDuration=-1, defaultSampleSize=-1, defaultSampleFlags=null, durationIsEmpty=true, defaultBaseIsMoof=true};TrackFragmentBaseMediaDecodeTimeBox{baseMediaDecodeTime=0};TrackRunBox{sampleCount=470, dataOffset=-1, dataOffsetPresent=false, sampleSizePresent=true, sampleDurationPresent=true, sampleFlagsPresentPresent=false, sampleCompositionTimeOffsetPresent=false, firstSampleFlags=null}]]
org.mp4parser.boxes.iso14496.part12.MediaDataBox@3969adb0

通过MP4Box (确定)

后一个日志来自MP4BoxTest.java,它导致连接测试输出test-mp4box.mp4,这是可以的。

但是请注意,对于最终用例来说,这个方法是不可接受的,因为这个hack方法输出的块中存在缺陷。

代码语言:javascript
复制
MP4Box \
  -profile live \
  -add aacFilePath \
  -dash 10000 \
  -frag 10000 \
  -idx ${NUM} \
  -moof-sn ${NUM} \
  -out test5.mpd \
  -segment-name test5-128k- \
  -segment-ext m4s \
  -single-traf \
  -subsegs-per-sidx 0 \
  -daisy-chain \
  -single-segment \
  /tmp

级联盒:

代码语言:javascript
复制
FileTypeBox[majorBrand=iso5;minorVersion=512;compatibleBrand=iso6;compatibleBrand=mp41]
MovieBox[MovieHeaderBox[creationTime=Thu Dec 31 16:00:00 PST 1903;modificationTime=Thu Dec 31 16:00:00 PST 1903;timescale=1000;duration=0;rate=1.0;volume=1.0;matrix=Rotate 0°;nextTrackId=2];TrackBox[TrackHeaderBox[creationTime=Thu Dec 31 16:00:00 PST 1903;modificationTime=Thu Dec 31 16:00:00 PST 1903;trackId=1;duration=0;layer=0;alternateGroup=1;volume=1.0;matrix=Rotate 0°;width=0.0;height=0.0];EditBox[EditListBox{entries=[Entry{segmentDuration=0, mediaTime=1024, mediaRate=1.0}]}];MediaBox[MediaHeaderBox[creationTime=Thu Dec 31 16:00:00 PST 1903;modificationTime=Thu Dec 31 16:00:00 PST 1903;timescale=48000;duration=0;language=und];HandlerBox[handlerType=soun;name=SoundHandler];MediaInformationBox[SoundMediaHeaderBox[balance=0.0];DataInformationBox[DataReferenceBox[DataEntryUrlBox[]]];SampleTableBox[SampleDescriptionBox[AudioSampleEntry{bytesPerSample=0, bytesPerFrame=0, bytesPerPacket=0, samplesPerPacket=0, packetSize=0, compressionId=0, soundVersion=0, sampleRate=48000, sampleSize=16, channelCount=2, boxes=[org.mp4parser.boxes.iso14496.part14.ESDescriptorBox@bed094d2]}];TimeToSampleBox[entryCount=0];SampleToChunkBox[entryCount=0];SampleSizeBox[sampleSize=0;sampleCount=0];StaticChunkOffsetBox[entryCount=0]]]]];MovieExtendsBox[org.mp4parser.boxes.iso14496.part12.TrackExtendsBox@7ce1e496];UserDataBox[MetaBox[HandlerBox[handlerType=mdir;name=];AppleItemListBox[org.mp4parser.boxes.apple.AppleEncoderBox@51da5351]]]]
SegmentTypeBox[majorBrand=msdh;minorVersion=0;compatibleBrand=msdh;compatibleBrand=msix]
SegmentIndexBox{entries=[Entry{referenceType=0, referencedSize=162267, subsegmentDuration=479232, startsWithSap=1, sapType=1, sapDeltaTime=0}], referenceId=1, timeScale=48000, earliestPresentationTime=0, firstOffset=0, reserved=0}
MovieFragmentBox[MovieFragmentHeaderBox{sequenceNumber=151304042};TrackFragmentBox[TrackFragmentHeaderBox{trackId=1, baseDataOffset=-1, sampleDescriptionIndex=0, defaultSampleDuration=-1, defaultSampleSize=-1, defaultSampleFlags=null, durationIsEmpty=false, defaultBaseIsMoof=true};TrackFragmentBaseMediaDecodeTimeBox{baseMediaDecodeTime=0};TrackRunBox{sampleCount=468, dataOffset=1964, dataOffsetPresent=true, sampleSizePresent=true, sampleDurationPresent=false, sampleFlagsPresentPresent=false, sampleCompositionTimeOffsetPresent=false, firstSampleFlags=null}]]
org.mp4parser.boxes.iso14496.part12.MediaDataBox@640d3ba5
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-23 10:22:03

test-java-mp4parser.mp4不是空的,但无效,因为:

  • 引用的sidx条目大小是错误的
  • tfhd正在用0覆盖默认的示例描述索引(1)。
  • trun没有指定数据偏移量
  • mdat AAC数据以8个零字节开始,这将导致解码失败。

如果这些是固定的,该文件将与FFmpeg一起播放。

列出的m4s段也有格式错误,似乎与连接结果不一致。例如,序列号用作示例描述索引。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69684510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档