0

This use case is a service that manually encodes a series of uncompressed .wav media segments into .m4s fragments for broadcast via MPEG-DASH, using ffmpeg to compress the .wav to .aac and sannies/mp4parser to assemble the aac audio into a .m4s media fragment.

I created this public GitHub project to reproduce the issue in its entirety.

For example, here's the custom ChunkFragmentM4sBuilder.java class.


This log is from ChunkFragmentM4sBuilderTest.java which results in the concatenated test output test-java-mp4parser.mp4 appears to be ok:

Concatenated init .mp4 and fragment .m4s are OK

However, when I play the shipped playlist and segments using VLC, I see these failures in the logs:

mp4: Fragment sequence discontinuity detected 163497124 != 0

This error happens when VLC plays the following DASH playlist:

And here is the latest implementation of my custom fragment builder class and additional notes:

Files.deleteIfExists(Path.of(m4sFilePath));
AACTrackImpl aacTrack=new AACTrackImpl(new FileDataSourceImpl(aacFilePath));
Movie movie=new Movie();
movie.addTrack(aacTrack);
Container mp4file=new ChunkFragmentM4sBuilder(seqNum).build(movie);
FileChannel fc=new FileOutputStream(m4sFilePath).getChannel();
mp4file.writeContainer(fc);
fc.close();
Charney Kaye
  • 3,667
  • 6
  • 41
  • 54
  • Feedback is appreciated if you believe this is a poor question. – Charney Kaye Oct 23 '21 at 08:07
  • After some diggings with your `test-java-mp4parser.mp4` using my tag-parser.java, I noticed that the file has 2 duplicates `ftyp` tag. The specification says this tag must be one and only one. First one specified `iso6` and `mp41` and the other one has `mp42, iso6, avc1` and `isom` for it's compatible brands. Using `ffmpeg` to rearrange the tags did solve the problem: `ffmpeg -i test-java-mp4parser.mp4 -acodec copy -vcodec copy output.mp4`. – Darkman Oct 23 '21 at 12:48
  • @Darkman That's because the file is a concatenation of the segments used as a test. The problem is with the segments which should not have a `ftyp` and a `moov` at all, but just a `styp`. VLC is already able to play the DASH manifest by ignoring the extra atoms, just by providing the right segment list. – aergistal Oct 23 '21 at 13:18
  • @aergistal That's right. If done correctly those `m4s`s can be concat easily with its init file. Looking at the first `test5-128k-163497124.m4s`, it has `ftyp` tag which it shouldn't and I dont check the other two. I'm sure they have one too. Note: some `MPEG-DASH`s do **NOT** have an init file. – Darkman Oct 23 '21 at 13:30
  • Oh one more thing, the problem here is that MPEG-DASH does not always come with an init file so the tool must know how to mux/demux them and not just concatenation. – Darkman Oct 23 '21 at 13:40
  • And one last thing. Those `m4s`s are **NOT** `m4s` format but `mp4`. They should have `mp4` suffix instead. And because they're `mp4`s, you'll need to mux them and not to concat them. – Darkman Oct 23 '21 at 13:56
  • 1
    @Darkman No you don't, they're just self-initialized segments. – aergistal Oct 23 '21 at 16:05
  • I am going to modify my code in order to output segments without the initializer. I've been using MP4Box to generate the initial segment, so I will likely add another class to this repository in order to write the init segment. – Charney Kaye Oct 24 '21 at 00:21

1 Answers1

0

The VLC message is just an info entry and not an error. It's expected since the starting sequence number corresponds to the live-edge.

You cannot playback that manifest once the live-edge went past the time of the last segment of those 3 provided. You would need to continue generating new segments corrresponding to the current time.

You can test this easily by making the manifest static, adding a segment list and modifiying the start number.


Your segments look self-initialized but are not declared as such which will lead to problems. It also wastes bandwidth as you already provide an initialization segment.

As a reminder you should have:

  • an init segment with ftyp and moov
  • a series of media segments with styp (optional), moof, mdat
aergistal
  • 29,947
  • 5
  • 70
  • 92
  • Not to brush off your point @aergistal I believe in your expertise! Just that as mentioned, I've played back both types of segments using the identical playlist file. One works with no errors in the logs, and one fails to play yet shows errors. This leads me to believe that there is *some* difference in the files. Does my logic make sense? – Charney Kaye Oct 23 '21 at 20:25
  • It would help to post the complete VLC debug log and version. It played on my end with the segments you provided renamed to the current time, despite repeating `moov` atoms and inconsistent base decode times etc – aergistal Oct 23 '21 at 21:58
  • Apologies that my lab notes project is an analog I'm maintaining in parallel with the private codebase I am actually working on. However, I've discovered that you are correct here. I added a static playlist file https://github.com/charneykaye/encode-fmp4-demo/blob/main/notes/via-java-mp4parser-v2/test5-static.mpd by which I can use VLC to play these three segments. Thanks for the guidance here. I will pursue cleaning up my init + segment containers, working through this for now... – Charney Kaye Oct 24 '21 at 00:19
  • 1
    Finally [my third draft](https://github.com/charneykaye/encode-fmp4-demo/blob/main/src/main/java/com/charneykaye/ChunkFragmentM4sBuilderV3.java) constructed this [viable .m4s fragment](https://github.com/charneykaye/encode-fmp4-demo/blob/main/notes/via-java-mp4parser-v3/test5-128k-151304042.m4s) – Charney Kaye Oct 24 '21 at 04:18
  • 1
    @CharneyKaye One more thing you can fix is the `tfdt` base media decode time which is set to 0 for your segments instead of the sum of all previous samples since the first segment (number 0). – aergistal Oct 24 '21 at 08:07
  • 1
    @CharneyKaye Once done make it available on a test server and test it using the [DASH-IF reference player](https://reference.dashif.org/dash.js/v4.1.0/samples/dash-if-reference-player/index.html). – aergistal Oct 24 '21 at 08:11