2
votes

I am performing chunked encodes of longer video files, where I've split the original file into individual sequences that I have encoded separately. These sequences are files of different length, depending on where the scene cuts appear—they may be between 2 and 5 seconds long. They all start with an I-frame and are standalone.

My encoded sequences are all MP4s, e.g.:

test_0000.mp4
test_0001.mp4
test_0002.mp4
test_0003.mp4
test_0004.mp4

They all have common properties:

$ mp4info test_0000.mp4

File:
  major brand:      isom
  minor version:    200
  compatible brand: isom
  compatible brand: iso2
  compatible brand: mp41
  fast start:       no

Movie:
  duration:   2016 ms
  time scale: 1000
  fragments:  no

...

Now, in order to play those with a DASH player, I have to create an initialization segment and individual fragmented MP4s.

I could generate the fragmented MP4s via mp4fragment which I run on each standalone MP4 file:

$ mp4info test_0000.m4s
File:
  major brand:      isom
  minor version:    200
  compatible brand: isom
  compatible brand: iso2
  compatible brand: mp41
  compatible brand: iso5
  fast start:       yes

Movie:
  duration:   2016 ms
  time scale: 1000
  fragments:  yes

...

But obviously, these are now not according to spec, and all contain a moov atom:

What I'd need is individual media segments with only one moof and mdat box, which then require an initialization segment with only a moov box.

How can I generate that from the existing, already encoded segments?

I know this appears like an XY problem. In principle, I could already segment my original file directly after encoding, and run those encodes at the same time, e.g. using ffmpeg's dash muxer, or MP4Box, however:

  • There is almost no control over the resulting segment sizes, with respect to minimum and maximum duration
  • This approach does not parallelize

I have also checked Bento4; it does not seem to offer this functionality. Neither does FFmpeg. MP4Box behaves similarly. They all assume you have one long file to start with.


I see I could splice off the ftyp and moov boxes from these “fake fragments” in order to create an initialization segment. But I would end up with segments containing multiple moof and mdat boxes, which is not according to the specification – it only allows one fragment and media data box:

4. Media Segments

[…] one optional Segment Type Box (styp) followed by a single Movie Fragment Box (moof) followed by one or more Media Data Boxes (mdat).

I guess I can live with this the styp not being present.

1
I don’t of of any tool to do this. But you just need to strip the ftyp and moov from every file, and save a copy for the init. I think a tool like dd could do it.szatmary
Thanks – I'm just wondering why nothing is out there yet, as all tools assume you want to go from one big file into equal-sized segments. I was thinking about something like what you suggested, but then I'd still have segments containing multiple moof and mdat boxes (see question update), which I don't think would be valid?slhck
The multiple moof/mdat is very common these days. It was added as part of cmaf to enable low latency live streaming.szatmary
Sounds good, I'll investigate. Thanks for the pointers!slhck

1 Answers

0
votes

I think the simplest way would be using MP4Box, see Split fragmented MP4 into multiple MP4 files for details.