How to output fragmented mp4 with ffmpeg?

74,500

Solution 1

This should do the trick:

ffmpeg -re -i infile.ext -g 52 \
-c:a aac -b:a 64k -c:v libx264 -b:v 448k \
-f mp4 -movflags frag_keyframe+empty_moov \
output.mp4
  • frag_keyframe causes fragmented output,
  • empty_moov will cause output to be 100% fragmented; without this the first fragment will be muxed as a short movie (using moov) followed by the rest of the media in fragments,
  • -re is useful when live streaming (use input media frame rate), do not use it if you are creating a file,
  • -g 52 forces (at least) every 52nd frame to be a keyframe

To calculate a healthy keyframe interval please see the paragraphs about fragment sizes in the docs of my streaming server. - You can also consider using WebM which is a free alternative to H.264 (and has better support on some platforms than fragmented mp4).

Important note: FFMpeg's muxer will set the Duration in both tkhd and mdhd atoms to 0xffffffff for each track. This causes problems in some players (for example Quicktime will not play such files). You should find a tool and change it to zero (0x00000000).

Solution 2

UPDATE: Considering a fragmented MP4 as ISMV (Smooth Streaming) file. The new version FFMPEG 0.10, since January, 27, 2012 is able to mux to this format.

$ ffmpeg -h muxer=ismv
ismv muxer AVOptions:
-movflags          <flags> E.... MOV muxer flags
   rtphint                 E.... Add RTP hint tracks
   empty_moov              E.... Make the initial moov atom empty (not supported by QuickTime)
   frag_keyframe           E.... Fragment at video keyframes
   separate_moof           E.... Write separate moof/mdat atoms for each track
   frag_custom             E.... Flush fragments on caller requests
   isml                    E.... Create a live smooth streaming feed (for pushing to a publishing point)
-moov_size         <int>   E.... maximum moov size so it can be placed at the begin
-rtpflags          <flags> E.... RTP muxer flags
   latm                    E.... Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC
   rfc2190                 E.... Use RFC 2190 packetization instead of RFC 4629 for H.263
   skip_rtcp               E.... Don't send RTCP sender reports
-skip_iods         <int>   E.... Skip writing iods atom.
-iods_audio_profile <int>  E.... iods audio profile atom.
-iods_video_profile <int>  E.... iods video profile atom.
-frag_duration     <int>   E.... Maximum fragment duration
-min_frag_duration <int>   E.... Minimum fragment duration
-frag_size         <int>   E.... Maximum fragment size
-ism_lookahead     <int>   E.... Number of lookahead entries for ISM files

Solution 3

ffmpeg -h (but not the man page) has the following:

mp4 muxer AVOptions:  
-movflags          <flags> E.... MOV muxer flags
   rtphint                 E.... Add RTP hint tracks
-moov_size         <int>   E.... maximum moov size so it can be placed at the
                                 beginning
-frag_size         <int>   E.... maximum fragment size
-frag_duration     <int>   E.... maximum fragment duration
-rtpflags          <flags> E.... RTP muxer flags
   latm                    E.... Use MP4A-LATM packetization instead of
                                 MPEG4-GENERIC for AAC
-skip_iods          <int>   E.... Skip writing iods atom.
-iods_audio_profile <int>   E.... iods audio profile atom.
-iods_video_profile <int>   E.... iods video profile atom.

I wouldn't know how to identify a fragmented mp4 if I saw one, but it looks like ffmpeg does have some (poorly documented) support for them.

Solution 4

Perhaps this will help. In the example below, ffmpeg takes a COPY of an RTMP feed and then using ffmpeg, it creates a HTTP output in fMP4 that can be accepted by IIS or Azure entry points.

Note: the original encoder is set to keyframe interval of 2 seconds.

ffmpeg -i rtmp://ip of server:1935/name/streamkey -vcodec copy -acodec copy -nal-hrd cbr -movflags isml+frag_keyframe+separate_moof -f ismv http://url of entry point/entry-point.isml/Streams(feed1)
Share:
74,500
S B
Author by

S B

Updated on July 19, 2022

Comments

  • S B
    S B almost 2 years

    ffmpeg -i infile.avi out.mp4 outputs non-fragmented MP4.

    How do I obtain fragmented mp4?

    Update A fragmented mp4 file is internally divided into several back-to-back chunks or MPEG-4 movie fragments. Each chunk has its own moof atom - so there are several moof atoms interleaved in the file instead of a single moov at the end as in the case of an unfragmented mp4. This makes it easier to stream over slow networks where buffering is involved

    There are several tools like mp4box that convert a normal mp4 to a fragmented one. Unfortunately we cannot use something like this

    ffmpeg <options to output mp4> | mp4box
    

    since ffmpeg does not produce seekable output while producing mp4 containers.

  • Brandon Aaskov
    Brandon Aaskov about 10 years
    If you're having issues with the above command, you may need to reinstall ffmpeg. To install via brew with all options: brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-frei0r --with-libass --with-libvo-aacenc --with-libvorbis --with-libvpx --with-opencore-amr --with-openjpeg --with-opus --with-rtmpdump --with-schroedinger --with-speex --with-theora --with-tools
  • Jesse Chisholm
    Jesse Chisholm about 10 years
    re: "I wouldn't know how to identify a fragmented mp4 if I saw one" :) they do look alot alike. :) There is an 'mvex' atom near the front of the 'moov' to let you know it will be fragmented. There will be rather little actual data information in the various track sub-atoms. There will be top level 'moof' 'mdat' pairs which is where the actual data resides. There may be an 'mfra' atom at the end.
  • astralmaster
    astralmaster almost 9 years
    Is it possible to stream the output to HTML5 instead of saving it to a file? With http protocol?
  • vbence
    vbence almost 9 years
    @astralmaster AFAIK FFmpeg has no http server socket output (just client). You have to bounce media off an other piece of software like VLC, or if you want to serve multiple clients, FFserver.
  • astralmaster
    astralmaster almost 9 years
    @vbence Unfrtunately FFServer has only linux builds and I am looking for a windows solution.
  • vbence
    vbence almost 9 years
    @astralmaster You can always use a free VM, like VmWare Player.
  • crs1138
    crs1138 almost 7 years
    @BrandonAaskov: When I've tried reinstalling ffmpeg with the codecs you suggest I get a warning saying: Warning: ffmpeg: this formula has no --with-libvo-aacenc option so it will be ignored!
  • vbence
    vbence almost 7 years
    @BrandonAaskov There are new options sice then. I edited the answer. For more info see: trac.ffmpeg.org/wiki/Encode/AAC
  • Gyan
    Gyan over 6 years
    mp4box -info file will indicate if the MP4 is fragmented.
  • Shevach Riabtsev
    Shevach Riabtsev over 4 years
    It's correct that ffmpeg sets 0xffffff as duration, this means that the duration of is not determined. The MPEG File System spec. (ISO/IEC 14496-12:2015) says: "duration is an integer that indicates the duration of this track (in the timescale indicated in the Movie Header Box). The value of this field is equal to the sum of the durations of all of the track’s edits. If there is no edit list, then the duration is the sum of the sample durations, converted into the timescale in the Movie Header Box. If the duration of this track cannot be determined then duration is set to all 1s."
  • Shevach Riabtsev
    Shevach Riabtsev over 4 years
    By the way in the recent versions of ffmpeg the duration is set to 0 (at least in cases when fragmented mp4 generated). It's a bug of ffmpeg to set duration to "0" instead of 0xffffff. Because 0xffffff should be interpreted as "the duration cannot be determined".
  • Admin
    Admin almost 4 years
    WebM is not an alternative to H.264. WebM is an alternative to mp4 (containers) as VP9 is an alternative to H.264 (codecs)
  • vbence
    vbence almost 4 years
    @cub33 Not quite.
  • yesennes
    yesennes over 3 years
    Might want to add omit_tfhd_offset to the movflags to improve some browser compatibility.