If I have a remote mp4 file on a server that supports Byte Ranges, is it possible to retrieve a single byte range and create a new/self-contained mp4 from that range data?
If I try and write a returned byte range data directly to an mp4 file using
MP4 files are structured with boxes. Two main of them being moov and mdat (general case of non-fragmented MP4):
The moov box is (should be) at the beginning of the file for MP4 file web delivery so if you write a byte range request from 0 to XX you will likely get the whole moov box + a certain amount of mdat data. Hence the file can be played up to a certain point. If you byte range from YY to XX chances are you will not get a decent moov box but a lot of mdat which as such cannot be used unless they are repack in a MP4 file with a proper moov box referencing information about the "cut" mdat.
It is possible to recreate a valid MP4 file from a byte range chunk but it requires an advanced knowledge of the MP4 file format structure (you need to retrieve the moov box as well to make it bearable). MP4 file format is based on ISO base media file format - that was specified as ISO/IEC 14496-12 (MPEG-4 Part 12).
I know 2 libs that could help doing what you want: one in PHP and one in Java. I do not know if such a lib exists for node.js (I guess it could be ported). Even if you do not use them the 2 libs above contain valuable information about the subject.
To provide an answer to your question you could tackle the issue with a different angle. Knowing which part of the file you want in milliseconds you could execute an ffmpeg command to splice the full-length MP4 file server-side into a smaller one and then do what you need with this new smaller MP4 file (as so you do not need to download unnecessary data on the client).
ffmpeg command for that is (in this case cut at 1 minute from beginning of 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 info on the above command line
This is done pretty fast as the MP4 file structure is just re-organised with no re-transcoding.
EDIT: Or can I use ffmpeg on a remote file and create the 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 (app/web) if you run the above command ffmpeg will fetch the mp4 to the input URL then seek to 1 min and cut 2 min from there and so write the generated content to output.mp4 locally (without downloading the full file of course).