gpac / mp4box.js

JavaScript version of GPAC's MP4Box tool
https://gpac.github.io/mp4box.js/
BSD 3-Clause "New" or "Revised" License
1.89k stars 318 forks source link

if the chunkSize config is set to a small value, then for some mp4 video, fragmentation takes a lot of time. #391

Closed ashuvssut closed 2 months ago

ashuvssut commented 4 months ago

When using a download chunk size ranging between 1 MB to 3 MB, as demonstrated in the attached video below, I've noticed a significant delay in the completion of mp4box fragmentation for many MP4 videos with durations less than 1.5 minutes. Please refer to the linked video for illustration. Increasing the chunk size appears to mitigate this delay in fragmentation initiation.

Interestingly, for videos with durations exceeding 1.5 minutes, a chunk size of 1 MB performs adequately. However, I'm puzzled as to why videos with durations less than 1.5 minutes necessitate a larger chunk size to mitigate this delay.

I mention the 1.5-minute threshold because, irrespective of their size, videos consistently experience prolonged start-up times. (1.5 minutes serves as an average approx duration).

output_compressed.webm

In the demo video provided above:

  1. Initially, a 3-minute duration video was used, where setting the chunkSize to 1MB resulted in expected behaviour: i.e video started without any delay.

  2. However, when a video with a duration of less than 1 minute was used, setting the chunkSize to 1MB resulted in significant start-up delay. Increasing the chunkSize to 4MB improved the video start time.

    • This same behaviour was also tested with a less than 1-minute 4K MP4 video of 180MB in size.
    • It's notable that a very large chunkSize is required to initiate the video slightly earlier. Setting chunkSize to 1MB results in considerable delay in video start-up.

EDIT: i did a few more tests on 2 more files

The 1.25GB mp4 file is of 15mins: https://drive.google.com/file/d/1GI2pFTCpTcyu-hQt89AQpe-pDBiA6uPL/view?usp=drive_link The 130MB 3gp file is of 30secs: https://drive.google.com/file/d/1bLyuIn3AjxcQ5_EYppTCej7ASt0QMlzp/view?usp=drive_link

Regarding the 2nd point mentioned above, it's not limited to files of duration 1-min 4K video . A more accurate description would be: "mp4box struggles with fragmentation particularly when dealing with files that have a disproportionately large size relative to their short video duration."

Steps to set up the mp4box player playground locally shown in the video

clone this repo

yarn install
yarn dev # starts demo-player app
yarn serve # starts the media sever
yarn dev:player # (Optional) re-build mp4box-player lib by watching for changes
PopeyeSailorMike commented 3 months ago

Hi. I just had a look at this and it got me wondering why your building an mp4 blox player and not simply customizing video.js

ashuvssut commented 3 months ago

I have mentioned all the reasoning here: https://github.com/stacknide/mp4box-apps#why-do-streaming-using-mp4box-player

but in short, mp4box helps me play "RAW video byte ranges" directly.

As of 2024, if you want to play "video byte ranges", the closest thing you would use is "Streaming Protocols like DASH or HLS". But those Streaming Protocols need "PROCESSED video byte ranges" (Processing is done on server side like segmentation and transcoding/remuxing to mp4/webm)

mp4box does those byte ranges processing part on the client side on the fly. For me, it fits my use case because I don't have a capable server that can do such video processing


Little more on why not video.js:

Using videojs, you have 2 options to play your video:-


not simply customizing video.js

Customizing video.js is out of question because what I need is, "processing raw video byte ranges for streaming on client side". Video.js cant do that client side processing part. mp4box can

PopeyeSailorMike commented 3 months ago

Thanks for the detailed breakdown. Check this out. This uses Mp4Box to append fragmented mp4: https://github.com/chriswiggins/videojs-fmp4/blob/master/src/plugin.js

PopeyeSailorMike commented 3 months ago

Managed to update the repo above. It's working and it appears it will be possible to achieve the same results as your mp4box player by using this plugin which preceded vhs(videojs-http-streaming utilizing MSE under the hood for DASH and HLS): https://github.com/videojs/videojs-contrib-media-sources/blob/master/index.html

ashuvssut commented 3 months ago

Were you able to do seek Operation too on that flv video?

PopeyeSailorMike commented 3 months ago

I've built it but the sample FLV is only 6 seconds long. It should work just fine with longer videos.

PopeyeSailorMike commented 3 months ago

So, I tried longer videos and it appears that flv.js doesn't seek as of right now and sourceBuffer requires the exact codecs for raw byte ranges to work with MSE. Video.js is great because it allows you to specify the techOrder and toggle them on/off as needed. That's why I suggested it but Mp4box appears to have a consistent method for handling raw video byte ranges.

ashuvssut commented 2 months ago

We observed that having a smaller value in the Segment Size field in the playground UI (i.e a smaller nb_samples value) helped fixed the issue with those high resolution mp4 file.

So in the linked PR above, we made corrections to calculate nb_samples and chunkSize precisely based on a constant named SEGMENT_DURATION_SECS

PopeyeSailorMike commented 2 months ago

Cool!