Eyevinn / mp4ff

Library and tools for parsing and writing MP4 files including video, audio and subtitles. The focus is on fragmented files. Includes mp4ff-info, mp4ff-encrypt, mp4ff-decrypt and other tools.
MIT License
456 stars 83 forks source link

feature request: extend segment example to a vod example #140

Closed fastfading closed 2 years ago

fastfading commented 2 years ago

in a vod system, it normally convert a normal mp4 to hls(ts or m4s) in memory and stream to player can we extend the segment example to support hls m4s ? and make a new example ?

Step:

  1. generate a m3u8 file base on mp4
  2. player read m3u8 and send a xx.m4s request to vod
  3. vod read mp4 and convert the related xx.m4s in memory and send to player.
TobbeEdgeware commented 2 years ago

@fastfading That is an interesting application, but goes way beyond the scope of this library which is the mp4 packaging itself and not streaming protocols like HLS or DASH. It would also involve having an HTTP server to serve the files, so there are a too many aspects which go beyond using this library's API.

If you want to implement it using this library, it's totally feasible. I've done such an implementation as part of closed product code for the company where I'm employed. It is implemented as reading and caching the sample metadata of the moov box from a progressive mp4 file, precalculating byte-ranges and communicating them via HLS playlists and sidx boxes, and finally streaming the media as byte-range requests for both HLS and DASH.

tobbee commented 2 years ago

I close this for now since I have not received any more input and I consider this feature request out of scope.

fastfading commented 2 years ago

@tobbee @TobbeEdgeware thank you I already implement such VOD system base on your segment example. however if the mp4 is not a normal mp4

Brands (major/compatible)   isom/isom,iso2,avc1,mp41
MIME    video/mp4; codecs="avc1.640033,mp4a.40.2"; profiles="isom,iso2,avc1,mp41"
Fragmented  false

if the mp4 is a fmp4 convert by mp4box like this. MP4Box -dash 30000 -profile onDemand mp4box.mp4 -out dash.mpd --dual

Brands (major/compatible)   iso6/iso6,dsms,msix,dash
MIME    video/mp4; codecs="avc1.640033,mp4a.40.2"; profiles="iso6,dsms,msix,dash"
Fragmented  true

can we also segment it ? How? could you give an example like the example/segment ?

tobbee commented 2 years ago

Well, the example/resegmenter is for that case. The example code splits one segment into multiple, but it should be relatively simple to change it to read multiple segments and take samples from them in order to make 3s output segments from 2s input segments.

fastfading commented 2 years ago

thanks , again.
and some user like to download the fmp4 as normal mp4. Is it possible to stream the fmp4 to normal mp4. consider customer use web browser, or some download tools. then may send random range download for part of the normal mp4,

all convert in memory, we don't wish any Intermediate files,
assume we already have the m3u8/mpd file info for that fmp4

for the fmp4 is stored in aws s3 storage, not disk . dowload from s3 is slow compare to disk. can we build the normal mp4 stucture (moov) out earlier, then stream s3 fmp4 to customer as normal mp4

tobbee commented 2 years ago

Fragmented MP4 files to progressive is the most tricky conversion since you need information about every single sample in order to create the moov box for the progressive files. I haven't done it and have no example code in that direction. In general, the focus of the mp4ff library is towards fragmented files.

However, I know about a presentation by Derek Buitenhuis at Vimeo from 2021 who had done an implementation for this use case. You can find it at

https://www.slideshare.net/DerekBuitenhuis/a-progressive-approach-to-the-past-ensuring-backwards-compatability-through-cleverness-and-pain

and

https://www.twitch.tv/videos/986194070

fastfading commented 2 years ago

in example/segment do we need all mp4 data ? or only mp4 header data (moov) ? to build xxxx_init.mp4 and xxx.m3u8 for multiplexed segments this is important for progressive mp4 stored in s3.

fastfading commented 2 years ago
image

it seems , I just need modify this code , to achive my goal. Break read at the mdat header

tobbee commented 2 years ago

Yes, you only need to read the moov box. I'm using this code as it is to read only the ftyp+moov from big progressive mp4 files. The r.Seek will seek to the end, and then the read will return io.EOF.

For S3, it may be better to avoid the small byte-range requests at the start and instead read a bigger chunk like one MB to most likely get both the ftyp and the full moov in one go. You should be able to write your own top-level box loop to achieve that.