mp4ff icon indicating copy to clipboard operation
mp4ff copied to clipboard

combine fragments

Open 3052 opened this issue 1 year ago • 10 comments

if you have a single file with multiple fragments, for example multiple sidx, moof and mdat boxes in one file, is it possible to combine those using this module? for example with FFmpeg, this command retains fragments:

ffmpeg -i in.m4a -frag_size 9999 -c copy out.m4a

but this command combines fragments into one:

ffmpeg -i in.m4a -c copy out.m4a

I dont mind a fragmented file, but from my experiences tools such as FFmpeg and MPC-HC will have to read large parts of those files before they will load. for example, FFmpeg is usually having to read about 95% of the file before it will return a result, instead of just reading the moov box.

3052 avatar Jan 02 '24 05:01 3052

It seems that you want a progressive file instead of a multi-fragment file. There is currently no such example code or tool, since the focus is on generating and changing fragmented files.

If you want to make longer fragments, the examples/resegmenter should be useful.

tobbee avatar Jan 04 '24 14:01 tobbee

OK doing this returns a fragmented file, with a single fragment:

ffmpeg -i in.mp4 -c copy -frag_size 39M -movflags empty_moov frag.mp4

note you need to adjust the fragment size depending on the file. also from this project, you can do:

resegmenter -b 99999999 -i frag.mp4 -o one.mp4

again adjust the size as needed.

3052 avatar Jan 09 '24 00:01 3052

check this out. if I take a "normal" file:

ffmpeg -i in.mp4 -c copy -frag_size 9K frag.mp4

you get the poor result of tools reading nearly the entire file:

> ffmpeg -v verbose -i frag.mp4
[AVIOContext @ 000001997f374c80] Statistics: 38141952 bytes read, 48 seeks

but if you use this undocumented option:

ffmpeg -i in.mp4 -c copy -frag_size 9K -movflags global_sidx frag.mp4

then the amount read drops by 99%:

> ffmpeg -v verbose -i frag.mp4
[AVIOContext @ 000002128d154c80] Statistics: 131076 bytes read, 3 seeks

https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/movenc.c

does this module have a similar option?

3052 avatar Jan 09 '24 23:01 3052

A sidx box describing all the segments and something that is present in DASH OnDemand content. It will give you seeking possibilities on the segment level. It is generated by MP4Box and other packaging tools, and I suppose that is what the ffmpeg option results in as well.

There is no real packaging tool in mp4ff but example code for segmenting and resegmenting. These examples don't include sidx boxes. The sidx box parsing/writing is supported though, so once one knows the sizes and timing of all the segments, one can generate such a box and insert it before the first segment.

tobbee avatar Jan 11 '24 07:01 tobbee

@3052 do you have anything more for this ticket? Otherwise, I suggest to close it for now. If you implement sidx addition to the segmented example, please consider making a PR for it.

tobbee avatar Jan 22 '24 16:01 tobbee

yeah I think global sidx is an important box, that should be included with all fragmented files. I know http://hulu.com does that already, but none of the other providers seem to be doing that. so I think it would be helpful to be able to add global sidx to fragmented files. I am working on this on my own but I need another week or so

3052 avatar Jan 22 '24 16:01 3052

Nice that you're working on it.

An issue with the sidx box is that it needs be inside the file and early. For many cases, this is not optimal since it means that you need to go back and write to the start of the file once you have finished all the segments. I think that is a reason not to make it mandatory.

An external sidx file would solve that, but it is not allowed (except for DASH-TS). Another possibility is to add an mfra box at the end as is done in SmoothStreaming.

Of course, putting metadata at the end means that the reader needs to jump there first which is not ideal. One scheme is good for writer and one for readers in the same way as putting the mdat box at the start or at the end of an unfragmented mp4 file...

tobbee avatar Jan 22 '24 16:01 tobbee

An external sidx file would solve that, but it is not allowed (except for DASH-TS). Another possibility is to add an mfra box at the end as is done in SmoothStreaming.

I addressed this already, but not explicitly. from here:

https://github.com/Eyevinn/mp4ff/issues/311#issuecomment-1883969501

this output file:

ffmpeg -i in.mp4 -c copy -frag_size 9K frag.mp4

has mfra, but still is slow to read with FFmpeg and MPC-HC:

> ffmpeg -v verbose -i frag.mp4
[AVIOContext @ 000001997f374c80] Statistics: 38141952 bytes read, 48 seeks

while the global sidx fixes the issue. from my experiments the only resolutions to this were:

  • increase the fragment sizes, in turn decreasing the number of fragments
  • eliminate the fragments, converting the file to progressive
  • add global sidx box

3052 avatar Jan 22 '24 22:01 3052

@3052 I added a method UpdateSidx to mp4.File that can be used to insert a top-level sidx box in a fragmented file. It should work for both single- and multi-track files so I think it should solve your issue. What do you think?

tobbee avatar Feb 13 '24 14:02 tobbee

This seems to be finally solved by #325, so this issue will be closed.

tobbee avatar Apr 19 '24 11:04 tobbee

OK once merged I will close or you can do it

3052 avatar Apr 19 '24 13:04 3052

Merged into master, and will be part of v0.44.0

tobbee avatar Apr 19 '24 13:04 tobbee