Is it possible to create a new mp4 file from one stream byte stream block?

If I have a remote mp4 file on a server that supports byte ranges, is it possible to get one byte range and create a new / standalone mp4 from this range data?

If I try to write the data range of the returned byte directly to the mp4 file using fs.createWriteStream(remoteFilename) , it will not receive the metadata of the video (duration, size, etc.) that needs to be played.

When I get a range of bytes that starts at 0 and ends at XX, mp4 output is played, but will have metadata for the duration of the entire video length and freeze the screen when the range of bytes is done for the rest of the duration time.

How else can I take a range of bytes and create a standalone .mp4 file from this stream object?

The thing is to avoid downloading the entire 10 minute file before I can make a 5 second clip using ffmpeg. If I can calculate and load a range of bytes, there must be a way to write it to a standalone mp4 file.

Thanks in advance for any help you can provide.

+6
source share
1 answer

MP4 files are structured using drawers. Two main ones: moov and mdat (the general case without fragmentation of MP4):

  • moov box: contains other fields :) - each of them contains information about the encoded data present in the mdat field (moov = metadata about the MP4 file). Typical metadata are duration, frame rate, codec information, link to video / audio frames ...
  • mdat box: contains the actual encoded data for the file. It can come from various codecs and includes audio and video data (or only one of them if this happens). For H264 blocks, NALs are contained in the mdat field.

The moov box (should be) at the beginning of the file for web delivery of MP4 files, so if you write a request for a range of bytes from 0 to XX, you will most likely receive the entire moov block + a certain amount of mdat data. Therefore, the file can be played back to a certain point. If you have a byte ranging from YY to XX odds, you won’t get a decent moov box, but many mdat that cannot be used as such unless they are repackaged in the MP4 file with the corresponding moov box referencing the β€œcut” mdat information.

You can recreate a valid MP4 file from a byte range block, but this requires advanced knowledge of the MP4 file format structure (you also need to remove the moov box to make it acceptable). The MP4 file format is based on the ISO format of the base media file - this was indicated as ISO / IEC 14496-12 (MPEG-4 part 12).

I know 2 libraries that could help do what you want: one in PHP and one in Java . I do not know if such a lib exists for node.js (I assume it can be ported). Even if you do not use them, the 2 libraries above contain valuable information about the subject.

To answer your question, you can solve the problem from a different angle. Knowing which part of the file you want in milliseconds, you can run the ffmpeg command to splic a full-sized MP4 file on the smaller side, and then do what you need with this new smaller MP4 file (so you do not need to load unnecessary data on client).

The ffmpeg command for this (in this case is cut after 1 minute from the beginning of the file):

 ffmpeg -i input.mp4 -ss 00:00:00.000 -t 00:01:00.000 -c:a copy -c:v copy output.mp4 

See this post for more information on the above command line.

This is pretty fast, as the MP4 file structure is simply reorganized without re-transcoding.

EDIT:. Or can I use ffmpeg in the remote file and create a new clip locally?

 ffmpeg -ss 00:01:00.000 -i "http://myfile.mp4" -t 00:02:00.000 -c:a copy -c:v copy output.mp4 

Assuming you have ffmpeg on your client (application / network), if you run the above command, ffmpeg will select mp4 at the input URL, then find 1 min and cut 2 minutes from there and write the generated content for output. mp4 locally (without full file download).

ffmpeg needs to be created with support for the HTTP input protocol (which you will find in most binaries). You can read here for more information on where to place the -ss option (pros / cons).

+6
source

All Articles