Merge commit '0e702124ee149593168cbbb7b30376249a64ae66'
authorJames Almer <jamrial@gmail.com>
Sun, 12 Nov 2017 02:47:50 +0000 (23:47 -0300)
committerJames Almer <jamrial@gmail.com>
Sun, 12 Nov 2017 02:47:50 +0000 (23:47 -0300)
* commit '0e702124ee149593168cbbb7b30376249a64ae66':
  doc: Provide better examples for hls and segment muxing

Merged-by: James Almer <jamrial@gmail.com>
1  2 
doc/muxers.texi

diff --cc doc/muxers.texi
@@@ -459,206 -156,37 +459,209 @@@ See also the @ref{framehash} muxer
  @section hls
  
  Apple HTTP Live Streaming muxer that segments MPEG-TS according to
 -the HTTP Live Streaming specification.
 +the HTTP Live Streaming (HLS) specification.
  
 -It creates a playlist file and numbered segment files. The output
 -filename specifies the playlist filename; the segment filenames
 -receive the same basename as the playlist, a sequential number and
 -a .ts extension.
 +It creates a playlist file, and one or more segment files. The output filename
 +specifies the playlist filename.
 +
 +By default, the muxer creates a file for each segment produced. These files
 +have the same name as the playlist, followed by a sequential number and a
 +.ts extension.
  
+ Make sure to require a closed GOP when encoding and to set the GOP
+ size to fit your segment time constraint.
 +For example, to convert an input file with @command{ffmpeg}:
  @example
- ffmpeg -i in.nut out.m3u8
 -avconv -i in.mkv -c:v h264 -flags +cgop -g 30 -hls_time 1 out.m3u8
++ffmpeg -i in.mkv -c:v h264 -flags +cgop -g 30 -hls_time 1 out.m3u8
  @end example
 +This example will produce the playlist, @file{out.m3u8}, and segment files:
 +@file{out0.ts}, @file{out1.ts}, @file{out2.ts}, etc.
 +
 +See also the @ref{segment} muxer, which provides a more generic and
 +flexible implementation of a segmenter, and can be used to perform HLS
 +segmentation.
 +
 +@subsection Options
 +
 +This muxer supports the following options:
  
  @table @option
 -@item -hls_time @var{seconds}
 -Set the segment length in seconds.
 -@item -hls_list_size @var{size}
 -Set the maximum number of playlist entries.
 -@item -hls_wrap @var{wrap}
 -Set the number after which index wraps.
 -@item -start_number @var{number}
 -Start the sequence from @var{number}.
 -@item -hls_base_url @var{baseurl}
 +@item hls_init_time @var{seconds}
 +Set the initial target segment length in seconds. Default value is @var{0}.
 +Segment will be cut on the next key frame after this time has passed on the first m3u8 list.
 +After the initial playlist is filled @command{ffmpeg} will cut segments
 +at duration equal to @code{hls_time}
 +
 +@item hls_time @var{seconds}
 +Set the target segment length in seconds. Default value is 2.
 +Segment will be cut on the next key frame after this time has passed.
 +
 +@item hls_list_size @var{size}
 +Set the maximum number of playlist entries. If set to 0 the list file
 +will contain all the segments. Default value is 5.
 +
 +@item hls_ts_options @var{options_list}
 +Set output format options using a :-separated list of key=value
 +parameters. Values containing @code{:} special characters must be
 +escaped.
 +
 +@item hls_wrap @var{wrap}
 +This is a deprecated option, you can use @code{hls_list_size}
 +and @code{hls_flags delete_segments} instead it
 +
 +This option is useful to avoid to fill the disk with many segment
 +files, and limits the maximum number of segment files written to disk
 +to @var{wrap}.
 +
 +
 +@item hls_start_number_source
 +Start the playlist sequence number (@code{#EXT-X-MEDIA-SEQUENCE}) according to the specified source.
 +Unless @code{hls_flags single_file} is set, it also specifies source of starting sequence numbers of
 +segment and subtitle filenames. In any case, if @code{hls_flags append_list}
 +is set and read playlist sequence number is greater than the specified start sequence number,
 +then that value will be used as start value.
 +
 +It accepts the following values:
 +
 +@table @option
 +
 +@item generic (default)
 +Set the starting sequence numbers according to @var{start_number} option value.
 +
 +@item epoch
 +The start number will be the seconds since epoch (1970-01-01 00:00:00)
 +
 +@item datetime
 +The start number will be based on the current date/time as YYYYmmddHHMMSS. e.g. 20161231235759.
 +
 +@end table
 +
 +@item start_number @var{number}
 +Start the playlist sequence number (@code{#EXT-X-MEDIA-SEQUENCE}) from the specified @var{number}
 +when @var{hls_start_number_source} value is @var{generic}. (This is the default case.)
 +Unless @code{hls_flags single_file} is set, it also specifies starting sequence numbers of segment and subtitle filenames.
 +Default value is 0.
 +
 +@item hls_allow_cache @var{allowcache}
 +Explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments.
 +
 +@item hls_base_url @var{baseurl}
  Append @var{baseurl} to every entry in the playlist.
  Useful to generate playlists with absolute paths.
 -@item -hls_allow_cache @var{allowcache}
 -Explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments
 -@item -hls_version @var{version}
 -Set the protocol version. Enables or disables version-specific features
 -such as the integer (version 2) or decimal EXTINF values (version 3).
 +
 +Note that the playlist sequence number must be unique for each segment
 +and it is not to be confused with the segment filename sequence number
 +which can be cyclic, for example if the @option{wrap} option is
 +specified.
 +
 +@item hls_segment_filename @var{filename}
 +Set the segment filename. Unless @code{hls_flags single_file} is set,
 +@var{filename} is used as a string format with the segment number:
 +@example
 +ffmpeg -i in.nut -hls_segment_filename 'file%03d.ts' out.m3u8
 +@end example
 +This example will produce the playlist, @file{out.m3u8}, and segment files:
 +@file{file000.ts}, @file{file001.ts}, @file{file002.ts}, etc.
 +
 +@var{filename} may contain full path or relative path specification,
 +but only the file name part without any path info will be contained in the m3u8 segment list.
 +Should a relative path be specified, the path of the created segment
 +files will be relative to the current working directory.
 +When use_localtime_mkdir is set, the whole expanded value of @var{filename} will be written into the m3u8 segment list.
 +
 +
 +@item use_localtime
 +Use strftime() on @var{filename} to expand the segment filename with localtime.
 +The segment number is also available in this mode, but to use it, you need to specify second_level_segment_index
 +hls_flag and %%d will be the specifier.
 +@example
 +ffmpeg -i in.nut -use_localtime 1 -hls_segment_filename 'file-%Y%m%d-%s.ts' out.m3u8
 +@end example
 +This example will produce the playlist, @file{out.m3u8}, and segment files:
 +@file{file-20160215-1455569023.ts}, @file{file-20160215-1455569024.ts}, etc.
 +Note: On some systems/environments, the @code{%s} specifier is not available. See
 +  @code{strftime()} documentation.
 +@example
 +ffmpeg -i in.nut -use_localtime 1 -hls_flags second_level_segment_index -hls_segment_filename 'file-%Y%m%d-%%04d.ts' out.m3u8
 +@end example
 +This example will produce the playlist, @file{out.m3u8}, and segment files:
 +@file{file-20160215-0001.ts}, @file{file-20160215-0002.ts}, etc.
 +
 +@item use_localtime_mkdir
 +Used together with -use_localtime, it will create all subdirectories which
 +is expanded in @var{filename}.
 +@example
 +ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d-%s.ts' out.m3u8
 +@end example
 +This example will create a directory 201560215 (if it does not exist), and then
 +produce the playlist, @file{out.m3u8}, and segment files:
 +@file{20160215/file-20160215-1455569023.ts}, @file{20160215/file-20160215-1455569024.ts}, etc.
 +
 +@example
 +ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y/%m/%d/file-%Y%m%d-%s.ts' out.m3u8
 +@end example
 +This example will create a directory hierarchy 2016/02/15 (if any of them do not exist), and then
 +produce the playlist, @file{out.m3u8}, and segment files:
 +@file{2016/02/15/file-20160215-1455569023.ts}, @file{2016/02/15/file-20160215-1455569024.ts}, etc.
 +
 +
 +@item hls_key_info_file @var{key_info_file}
 +Use the information in @var{key_info_file} for segment encryption. The first
 +line of @var{key_info_file} specifies the key URI written to the playlist. The
 +key URL is used to access the encryption key during playback. The second line
 +specifies the path to the key file used to obtain the key during the encryption
 +process. The key file is read as a single packed array of 16 octets in binary
 +format. The optional third line specifies the initialization vector (IV) as a
 +hexadecimal string to be used instead of the segment sequence number (default)
 +for encryption. Changes to @var{key_info_file} will result in segment
 +encryption with the new key/IV and an entry in the playlist for the new key
 +URI/IV if @code{hls_flags periodic_rekey} is enabled.
 +
 +Key info file format:
 +@example
 +@var{key URI}
 +@var{key file path}
 +@var{IV} (optional)
 +@end example
 +
 +Example key URIs:
 +@example
 +http://server/file.key
 +/path/to/file.key
 +file.key
 +@end example
 +
 +Example key file paths:
 +@example
 +file.key
 +/path/to/file.key
 +@end example
 +
 +Example IV:
 +@example
 +0123456789ABCDEF0123456789ABCDEF
 +@end example
 +
 +Key info file example:
 +@example
 +http://server/file.key
 +/path/to/file.key
 +0123456789ABCDEF0123456789ABCDEF
 +@end example
 +
 +Example shell script:
 +@example
 +#!/bin/sh
 +BASE_URL=$@{1:-'.'@}
 +openssl rand 16 > file.key
 +echo $BASE_URL/file.key > file.keyinfo
 +echo file.key >> file.keyinfo
 +echo $(openssl rand -hex 16) >> file.keyinfo
 +ffmpeg -f lavfi -re -i testsrc -c:v h264 -hls_flags delete_segments \
 +  -hls_key_info_file file.keyinfo out.m3u8
 +@end example
 +
  @item -hls_enc @var{enc}
  Enable (1) or disable (0) the AES128 encryption.
  When enabled every segment generated is encrypted and the encryption key
@@@ -1468,589 -610,29 +1471,592 @@@ reference stream. The default value is 
  @item segment_format @var{format}
  Override the inner container format, by default it is guessed by the filename
  extension.
 -@item segment_time @var{t}
 -Set segment duration to @var{t} seconds.
 +
 +@item segment_format_options @var{options_list}
 +Set output format options using a :-separated list of key=value
 +parameters. Values containing the @code{:} special character must be
 +escaped.
 +
  @item segment_list @var{name}
 -Generate also a listfile named @var{name}.
 -@item segment_list_type @var{type}
 -Select the listing format.
 -@table @option
 -@item @var{flat} use a simple flat list of entries.
 -@item @var{hls} use a m3u8-like structure.
 +Generate also a listfile named @var{name}. If not specified no
 +listfile is generated.
 +
 +@item segment_list_flags @var{flags}
 +Set flags affecting the segment list generation.
 +
 +It currently supports the following flags:
 +@table @samp
 +@item cache
 +Allow caching (only affects M3U8 list files).
 +
 +@item live
 +Allow live-friendly file generation.
  @end table
 +
  @item segment_list_size @var{size}
 -Overwrite the listfile once it reaches @var{size} entries.
 +Update the list file so that it contains at most @var{size}
 +segments. If 0 the list file will contain all the segments. Default
 +value is 0.
 +
  @item segment_list_entry_prefix @var{prefix}
  Prepend @var{prefix} to each entry. Useful to generate absolute paths.
 +By default no prefix is applied.
 +
 +@item segment_list_type @var{type}
 +Select the listing format.
 +
 +The following values are recognized:
 +@table @samp
 +@item flat
 +Generate a flat list for the created segments, one segment per line.
 +
 +@item csv, ext
 +Generate a list for the created segments, one segment per line,
 +each line matching the format (comma-separated values):
 +@example
 +@var{segment_filename},@var{segment_start_time},@var{segment_end_time}
 +@end example
 +
 +@var{segment_filename} is the name of the output file generated by the
 +muxer according to the provided pattern. CSV escaping (according to
 +RFC4180) is applied if required.
 +
 +@var{segment_start_time} and @var{segment_end_time} specify
 +the segment start and end time expressed in seconds.
 +
 +A list file with the suffix @code{".csv"} or @code{".ext"} will
 +auto-select this format.
 +
 +@samp{ext} is deprecated in favor or @samp{csv}.
 +
 +@item ffconcat
 +Generate an ffconcat file for the created segments. The resulting file
 +can be read using the FFmpeg @ref{concat} demuxer.
 +
 +A list file with the suffix @code{".ffcat"} or @code{".ffconcat"} will
 +auto-select this format.
 +
 +@item m3u8
 +Generate an extended M3U8 file, version 3, compliant with
 +@url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}.
 +
 +A list file with the suffix @code{".m3u8"} will auto-select this format.
 +@end table
 +
 +If not specified the type is guessed from the list file name suffix.
 +
 +@item segment_time @var{time}
 +Set segment duration to @var{time}, the value must be a duration
 +specification. Default value is "2". See also the
 +@option{segment_times} option.
 +
 +Note that splitting may not be accurate, unless you force the
 +reference stream key-frames at the given time. See the introductory
 +notice and the examples below.
 +
 +@item segment_atclocktime @var{1|0}
 +If set to "1" split at regular clock time intervals starting from 00:00
 +o'clock. The @var{time} value specified in @option{segment_time} is
 +used for setting the length of the splitting interval.
 +
 +For example with @option{segment_time} set to "900" this makes it possible
 +to create files at 12:00 o'clock, 12:15, 12:30, etc.
 +
 +Default value is "0".
 +
 +@item segment_clocktime_offset @var{duration}
 +Delay the segment splitting times with the specified duration when using
 +@option{segment_atclocktime}.
 +
 +For example with @option{segment_time} set to "900" and
 +@option{segment_clocktime_offset} set to "300" this makes it possible to
 +create files at 12:05, 12:20, 12:35, etc.
 +
 +Default value is "0".
 +
 +@item segment_clocktime_wrap_duration @var{duration}
 +Force the segmenter to only start a new segment if a packet reaches the muxer
 +within the specified duration after the segmenting clock time. This way you
 +can make the segmenter more resilient to backward local time jumps, such as
 +leap seconds or transition to standard time from daylight savings time.
 +
 +Default is the maximum possible duration which means starting a new segment
 +regardless of the elapsed time since the last clock time.
 +
 +@item segment_time_delta @var{delta}
 +Specify the accuracy time when selecting the start time for a
 +segment, expressed as a duration specification. Default value is "0".
 +
 +When delta is specified a key-frame will start a new segment if its
 +PTS satisfies the relation:
 +@example
 +PTS >= start_time - time_delta
 +@end example
 +
 +This option is useful when splitting video content, which is always
 +split at GOP boundaries, in case a key frame is found just before the
 +specified split time.
 +
 +In particular may be used in combination with the @file{ffmpeg} option
 +@var{force_key_frames}. The key frame times specified by
 +@var{force_key_frames} may not be set accurately because of rounding
 +issues, with the consequence that a key frame time may result set just
 +before the specified time. For constant frame rate videos a value of
 +1/(2*@var{frame_rate}) should address the worst case mismatch between
 +the specified time and the time set by @var{force_key_frames}.
 +
 +@item segment_times @var{times}
 +Specify a list of split points. @var{times} contains a list of comma
 +separated duration specifications, in increasing order. See also
 +the @option{segment_time} option.
 +
 +@item segment_frames @var{frames}
 +Specify a list of split video frame numbers. @var{frames} contains a
 +list of comma separated integer numbers, in increasing order.
 +
 +This option specifies to start a new segment whenever a reference
 +stream key frame is found and the sequential number (starting from 0)
 +of the frame is greater or equal to the next value in the list.
 +
  @item segment_wrap @var{limit}
  Wrap around segment index once it reaches @var{limit}.
 +
 +@item segment_start_number @var{number}
 +Set the sequence number of the first segment. Defaults to @code{0}.
 +
 +@item strftime @var{1|0}
 +Use the @code{strftime} function to define the name of the new
 +segments to write. If this is selected, the output segment name must
 +contain a @code{strftime} function template. Default value is
 +@code{0}.
 +
 +@item break_non_keyframes @var{1|0}
 +If enabled, allow segments to start on frames other than keyframes. This
 +improves behavior on some players when the time between keyframes is
 +inconsistent, but may make things worse on others, and can cause some oddities
 +during seeking. Defaults to @code{0}.
 +
 +@item reset_timestamps @var{1|0}
 +Reset timestamps at the beginning of each segment, so that each segment
 +will start with near-zero timestamps. It is meant to ease the playback
 +of the generated segments. May not work with some combinations of
 +muxers/codecs. It is set to @code{0} by default.
 +
 +@item initial_offset @var{offset}
 +Specify timestamp offset to apply to the output packet timestamps. The
 +argument must be a time duration specification, and defaults to 0.
 +
 +@item write_empty_segments @var{1|0}
 +If enabled, write an empty segment if there are no packets during the period a
 +segment would usually span. Otherwise, the segment will be filled with the next
 +packet written. Defaults to @code{0}.
  @end table
  
- ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.list out%03d.nut
+ Make sure to require a closed GOP when encoding and to set the GOP
+ size to fit your segment time constraint.
 +@subsection Examples
 +
 +@itemize
 +@item
 +Remux the content of file @file{in.mkv} to a list of segments
 +@file{out-000.nut}, @file{out-001.nut}, etc., and write the list of
 +generated segments to @file{out.list}:
 +@example
++ffmpeg -i in.mkv -codec hevc -flags +cgop -g 60 -map 0 -f segment -segment_list out.list out%03d.nut
 +@end example
 +
 +@item
 +Segment input and set output format options for the output segments:
 +@example
 +ffmpeg -i in.mkv -f segment -segment_time 10 -segment_format_options movflags=+faststart out%03d.mp4
 +@end example
 +
 +@item
 +Segment the input file according to the split points specified by the
 +@var{segment_times} option:
 +@example
 +ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.csv -segment_times 1,2,3,5,8,13,21 out%03d.nut
 +@end example
 +
 +@item
 +Use the @command{ffmpeg} @option{force_key_frames}
 +option to force key frames in the input at the specified location, together
 +with the segment option @option{segment_time_delta} to account for
 +possible roundings operated when setting key frame times.
 +@example
 +ffmpeg -i in.mkv -force_key_frames 1,2,3,5,8,13,21 -codec:v mpeg4 -codec:a pcm_s16le -map 0 \
 +-f segment -segment_list out.csv -segment_times 1,2,3,5,8,13,21 -segment_time_delta 0.05 out%03d.nut
 +@end example
 +In order to force key frames on the input file, transcoding is
 +required.
 +
 +@item
 +Segment the input file by splitting the input file according to the
 +frame numbers sequence specified with the @option{segment_frames} option:
 +@example
 +ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.csv -segment_frames 100,200,300,500,800 out%03d.nut
 +@end example
 +
 +@item
 +Convert the @file{in.mkv} to TS segments using the @code{libx264}
 +and @code{aac} encoders:
 +@example
 +ffmpeg -i in.mkv -map 0 -codec:v libx264 -codec:a aac -f ssegment -segment_list out.list out%03d.ts
 +@end example
 +
 +@item
 +Segment the input file, and create an M3U8 live playlist (can be used
 +as live HLS source):
 +@example
 +ffmpeg -re -i in.mkv -codec copy -map 0 -f segment -segment_list playlist.m3u8 \
 +-segment_list_flags +live -segment_time 10 out%03d.mkv
 +@end example
 +@end itemize
 +
 +@section smoothstreaming
 +
 +Smooth Streaming muxer generates a set of files (Manifest, chunks) suitable for serving with conventional web server.
 +
 +@table @option
 +@item window_size
 +Specify the number of fragments kept in the manifest. Default 0 (keep all).
 +
 +@item extra_window_size
 +Specify the number of fragments kept outside of the manifest before removing from disk. Default 5.
 +
 +@item lookahead_count
 +Specify the number of lookahead fragments. Default 2.
 +
 +@item min_frag_duration
 +Specify the minimum fragment duration (in microseconds). Default 5000000.
 +
 +@item remove_at_exit
 +Specify whether to remove all fragments when finished. Default 0 (do not remove).
 +
 +@end table
 +
 +@anchor{fifo}
 +@section fifo
 +
 +The fifo pseudo-muxer allows the separation of encoding and muxing by using
 +first-in-first-out queue and running the actual muxer in a separate thread. This
 +is especially useful in combination with the @ref{tee} muxer and can be used to
 +send data to several destinations with different reliability/writing speed/latency.
 +
 +API users should be aware that callback functions (interrupt_callback,
 +io_open and io_close) used within its AVFormatContext must be thread-safe.
 +
 +The behavior of the fifo muxer if the queue fills up or if the output fails is
 +selectable,
 +
 +@itemize @bullet
 +
 +@item
 +output can be transparently restarted with configurable delay between retries
 +based on real time or time of the processed stream.
 +
 +@item
 +encoding can be blocked during temporary failure, or continue transparently
 +dropping packets in case fifo queue fills up.
 +
 +@end itemize
 +
 +@table @option
 +
 +@item fifo_format
 +Specify the format name. Useful if it cannot be guessed from the
 +output name suffix.
 +
 +@item queue_size
 +Specify size of the queue (number of packets). Default value is 60.
 +
 +@item format_opts
 +Specify format options for the underlying muxer. Muxer options can be specified
 +as a list of @var{key}=@var{value} pairs separated by ':'.
 +
 +@item drop_pkts_on_overflow @var{bool}
 +If set to 1 (true), in case the fifo queue fills up, packets will be dropped
 +rather than blocking the encoder. This makes it possible to continue streaming without
 +delaying the input, at the cost of omitting part of the stream. By default
 +this option is set to 0 (false), so in such cases the encoder will be blocked
 +until the muxer processes some of the packets and none of them is lost.
 +
 +@item attempt_recovery @var{bool}
 +If failure occurs, attempt to recover the output. This is especially useful
 +when used with network output, since it makes it possible to restart streaming transparently.
 +By default this option is set to 0 (false).
 +
 +@item max_recovery_attempts
 +Sets maximum number of successive unsuccessful recovery attempts after which
 +the output fails permanently. By default this option is set to 0 (unlimited).
 +
 +@item recovery_wait_time @var{duration}
 +Waiting time before the next recovery attempt after previous unsuccessful
 +recovery attempt. Default value is 5 seconds.
 +
 +@item recovery_wait_streamtime @var{bool}
 +If set to 0 (false), the real time is used when waiting for the recovery
 +attempt (i.e. the recovery will be attempted after at least
 +recovery_wait_time seconds).
 +If set to 1 (true), the time of the processed stream is taken into account
 +instead (i.e. the recovery will be attempted after at least @var{recovery_wait_time}
 +seconds of the stream is omitted).
 +By default, this option is set to 0 (false).
 +
 +@item recover_any_error @var{bool}
 +If set to 1 (true), recovery will be attempted regardless of type of the error
 +causing the failure. By default this option is set to 0 (false) and in case of
 +certain (usually permanent) errors the recovery is not attempted even when
 +@var{attempt_recovery} is set to 1.
 +
 +@item restart_with_keyframe @var{bool}
 +Specify whether to wait for the keyframe after recovering from
 +queue overflow or failure. This option is set to 0 (false) by default.
 +
 +@end table
 +
 +@subsection Examples
 +
 +@itemize
 +
 +@item
 +Stream something to rtmp server, continue processing the stream at real-time
 +rate even in case of temporary failure (network outage) and attempt to recover
 +streaming every second indefinitely.
 +@example
 +ffmpeg -re -i ... -c:v libx264 -c:a aac -f fifo -fifo_format flv -map 0:v -map 0:a
 +  -drop_pkts_on_overflow 1 -attempt_recovery 1 -recovery_wait_time 1 rtmp://example.com/live/stream_name
 +@end example
 +
 +@end itemize
 +
 +@anchor{tee}
 +@section tee
 +
 +The tee muxer can be used to write the same data to several files or any
 +other kind of muxer. It can be used, for example, to both stream a video to
 +the network and save it to disk at the same time.
 +
 +It is different from specifying several outputs to the @command{ffmpeg}
 +command-line tool because the audio and video data will be encoded only once
 +with the tee muxer; encoding can be a very expensive process. It is not
 +useful when using the libavformat API directly because it is then possible
 +to feed the same packets to several muxers directly.
 +
 +@table @option
 +
 +@item use_fifo @var{bool}
 +If set to 1, slave outputs will be processed in separate thread using @ref{fifo}
 +muxer. This allows to compensate for different speed/latency/reliability of
 +outputs and setup transparent recovery. By default this feature is turned off.
 +
 +@item fifo_options
 +Options to pass to fifo pseudo-muxer instances. See @ref{fifo}.
 +
 +@end table
 +
 +The slave outputs are specified in the file name given to the muxer,
 +separated by '|'. If any of the slave name contains the '|' separator,
 +leading or trailing spaces or any special character, it must be
 +escaped (see @ref{quoting_and_escaping,,the "Quoting and escaping"
 +section in the ffmpeg-utils(1) manual,ffmpeg-utils}).
 +
 +Muxer options can be specified for each slave by prepending them as a list of
 +@var{key}=@var{value} pairs separated by ':', between square brackets. If
 +the options values contain a special character or the ':' separator, they
 +must be escaped; note that this is a second level escaping.
 +
 +The following special options are also recognized:
 +@table @option
 +@item f
 +Specify the format name. Useful if it cannot be guessed from the
 +output name suffix.
 +
 +@item bsfs[/@var{spec}]
 +Specify a list of bitstream filters to apply to the specified
 +output.
 +
 +@item use_fifo @var{bool}
 +This allows to override tee muxer use_fifo option for individual slave muxer.
 +
 +@item fifo_options
 +This allows to override tee muxer fifo_options for individual slave muxer.
 +See @ref{fifo}.
 +
 +It is possible to specify to which streams a given bitstream filter
 +applies, by appending a stream specifier to the option separated by
 +@code{/}. @var{spec} must be a stream specifier (see @ref{Format
 +stream specifiers}).  If the stream specifier is not specified, the
 +bitstream filters will be applied to all streams in the output.
 +
 +Several bitstream filters can be specified, separated by ",".
 +
 +@item select
 +Select the streams that should be mapped to the slave output,
 +specified by a stream specifier. If not specified, this defaults to
 +all the input streams. You may use multiple stream specifiers
 +separated by commas (@code{,}) e.g.: @code{a:0,v}
 +
 +@item onfail
 +Specify behaviour on output failure. This can be set to either @code{abort} (which is
 +default) or @code{ignore}. @code{abort} will cause whole process to fail in case of failure
 +on this slave output. @code{ignore} will ignore failure on this output, so other outputs
 +will continue without being affected.
 +@end table
 +
 +@subsection Examples
 +
 +@itemize
 +@item
 +Encode something and both archive it in a WebM file and stream it
 +as MPEG-TS over UDP (the streams need to be explicitly mapped):
 +@example
 +ffmpeg -i ... -c:v libx264 -c:a mp2 -f tee -map 0:v -map 0:a
 +  "archive-20121107.mkv|[f=mpegts]udp://10.0.1.255:1234/"
 +@end example
 +
 +@item
 +As above, but continue streaming even if output to local file fails
 +(for example local drive fills up):
 +@example
 +ffmpeg -i ... -c:v libx264 -c:a mp2 -f tee -map 0:v -map 0:a
 +  "[onfail=ignore]archive-20121107.mkv|[f=mpegts]udp://10.0.1.255:1234/"
 +@end example
 +
 +@item
 +Use @command{ffmpeg} to encode the input, and send the output
 +to three different destinations. The @code{dump_extra} bitstream
 +filter is used to add extradata information to all the output video
 +keyframes packets, as requested by the MPEG-TS format. The select
 +option is applied to @file{out.aac} in order to make it contain only
 +audio packets.
 +@example
 +ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac
 +       -f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
 +@end example
 +
 +@item
 +As below, but select only stream @code{a:1} for the audio output. Note
 +that a second level escaping must be performed, as ":" is a special
 +character used to separate options.
 +@example
 +ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac
 +       -f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=\'a:1\']out.aac"
 +@end example
 +@end itemize
 +
 +Note: some codecs may need different options depending on the output format;
 +the auto-detection of this can not work with the tee muxer. The main example
 +is the @option{global_header} flag.
 +
 +@section webm_dash_manifest
 +
 +WebM DASH Manifest muxer.
 +
 +This muxer implements the WebM DASH Manifest specification to generate the DASH
 +manifest XML. It also supports manifest generation for DASH live streams.
 +
 +For more information see:
 +
 +@itemize @bullet
 +@item
 +WebM DASH Specification: @url{https://sites.google.com/a/webmproject.org/wiki/adaptive-streaming/webm-dash-specification}
 +@item
 +ISO DASH Specification: @url{http://standards.iso.org/ittf/PubliclyAvailableStandards/c065274_ISO_IEC_23009-1_2014.zip}
 +@end itemize
 +
 +@subsection Options
 +
 +This muxer supports the following options:
 +
 +@table @option
 +@item adaptation_sets
 +This option has the following syntax: "id=x,streams=a,b,c id=y,streams=d,e" where x and y are the
 +unique identifiers of the adaptation sets and a,b,c,d and e are the indices of the corresponding
 +audio and video streams. Any number of adaptation sets can be added using this option.
 +
 +@item live
 +Set this to 1 to create a live stream DASH Manifest. Default: 0.
 +
 +@item chunk_start_index
 +Start index of the first chunk. This will go in the @samp{startNumber} attribute
 +of the @samp{SegmentTemplate} element in the manifest. Default: 0.
 +
 +@item chunk_duration_ms
 +Duration of each chunk in milliseconds. This will go in the @samp{duration}
 +attribute of the @samp{SegmentTemplate} element in the manifest. Default: 1000.
 +
 +@item utc_timing_url
 +URL of the page that will return the UTC timestamp in ISO format. This will go
 +in the @samp{value} attribute of the @samp{UTCTiming} element in the manifest.
 +Default: None.
 +
 +@item time_shift_buffer_depth
 +Smallest time (in seconds) shifting buffer for which any Representation is
 +guaranteed to be available. This will go in the @samp{timeShiftBufferDepth}
 +attribute of the @samp{MPD} element. Default: 60.
 +
 +@item minimum_update_period
 +Minimum update period (in seconds) of the manifest. This will go in the
 +@samp{minimumUpdatePeriod} attribute of the @samp{MPD} element. Default: 0.
 +
 +@end table
 +
 +@subsection Example
 +@example
 +ffmpeg -f webm_dash_manifest -i video1.webm \
 +       -f webm_dash_manifest -i video2.webm \
 +       -f webm_dash_manifest -i audio1.webm \
 +       -f webm_dash_manifest -i audio2.webm \
 +       -map 0 -map 1 -map 2 -map 3 \
 +       -c copy \
 +       -f webm_dash_manifest \
 +       -adaptation_sets "id=0,streams=0,1 id=1,streams=2,3" \
 +       manifest.xml
 +@end example
 +
 +@section webm_chunk
 +
 +WebM Live Chunk Muxer.
 +
 +This muxer writes out WebM headers and chunks as separate files which can be
 +consumed by clients that support WebM Live streams via DASH.
 +
 +@subsection Options
 +
 +This muxer supports the following options:
 +
 +@table @option
 +@item chunk_start_index
 +Index of the first chunk (defaults to 0).
 +
 +@item header
 +Filename of the header where the initialization data will be written.
 +
 +@item audio_chunk_duration
 +Duration of each audio chunk in milliseconds (defaults to 5000).
 +@end table
 +
 +@subsection Example
  @example
 -avconv -i in.mkv -c hevc -flags +cgop -g 60 -map 0 -f segment -list out.list out%03d.nut
 +ffmpeg -f v4l2 -i /dev/video0 \
 +       -f alsa -i hw:0 \
 +       -map 0:0 \
 +       -c:v libvpx-vp9 \
 +       -s 640x360 -keyint_min 30 -g 30 \
 +       -f webm_chunk \
 +       -header webm_live_video_360.hdr \
 +       -chunk_start_index 1 \
 +       webm_live_video_360_%d.chk \
 +       -map 1:0 \
 +       -c:a libvorbis \
 +       -b:a 128k \
 +       -f webm_chunk \
 +       -header webm_live_audio_128.hdr \
 +       -chunk_start_index 1 \
 +       -audio_chunk_duration 1000 \
 +       webm_live_audio_128_%d.chk
  @end example
  
  @c man end MUXERS