簡體   English   中英

Java mp4parser 輸出為空

[英]Java mp4parser output is empty

此用例是一項服務,它手動將一系列未壓縮的 .wav 媒體片段編碼為 .m4s 片段以通過 MPEG-DASH 進行廣播,使用 ffmpeg 將 .wav 壓縮為 .aac 並使用 sannies/mp4parser 將 aac 音頻組合成 .m4s 片段。 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實際上是空的: Java mp4parser 方法的連接輸出為空

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();

串聯框:

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 方法輸出的塊中存在缺陷。

MP4Box 方法的連接輸出沒問題

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

串聯框:

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

test-java-mp4parser.mp4不為空但無效,因為:

  • sidx條目引用的大小錯誤
  • tfhd0覆蓋默認樣本描述索引 ( 1 )
  • trun沒有指定數據偏移量
  • mdat AAC 數據以 8 個零字節開頭,這會導致解碼失敗

如果這些是固定的,文件將使用 FFmpeg 播放。

列出的m4s段也格式不正確,似乎與連接結果不對應。 例如,序列號用作樣本描述索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM