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).