The simplest pipeline in ffmpeg
is single-stream streamcopy, that is copying one input elementary stream’s packets without decoding, filtering, or encoding them. As an example, consider an input file called INPUT.mkv with 3 elementary streams, from which we take the second and write it to file OUTPUT.mp4. A schematic representation of such a pipeline looks like this:
┌──────────┬─────────────────────┐ │ demuxer │ │ unused ╞══════════╡ elementary stream 0 ├────────╳ │ │ │ │INPUT.mkv ├─────────────────────┤ ┌──────────────────────┬───────────┐ │ │ │ packets │ │ muxer │ │ │ elementary stream 1 ├─────────⮞│ elementary stream 0 ╞═══════════╡ │ │ │ │ │OUTPUT.mp4 │ │ ├─────────────────────┤ └──────────────────────┴───────────┘ │ │ │ unused │ │ elementary stream 2 ├────────╳ │ │ │ └──────────┴─────────────────────┘
The above pipeline can be constructed with the following commandline:
ffmpeg -i INPUT.mkv -map 0:1 -c copy OUTPUT.mp4
In this commandline
- there is a single input INPUT.mkv;
- there are no input options for this input;
- there is a single output OUTPUT.mp4;
- there are two output options for this output:
-map 0:1
selects the input stream to be used - from input with index 0 (i.e. the first one) the stream with index 1 (i.e. the second one);-c copy
selects thecopy
encoder, i.e. streamcopy with no decoding or encoding.
Streamcopy is useful for changing the elementary stream count, container format, or modifying container-level metadata. Since there is no decoding or encoding, it is very fast and there is no quality loss. However, it might not work in some cases because of a variety of factors (e.g. certain information required by the target container is not available in the source). Applying filters is obviously also impossible, since filters work on decoded frames.
More complex streamcopy scenarios can be constructed - e.g. combining streams from two input files into a single output:
┌──────────┬────────────────────┐ ┌────────────────────┬───────────┐ │ demuxer 0│ │ packets │ │ muxer │ ╞══════════╡elementary stream 0 ├────────⮞│elementary stream 0 ╞═══════════╡ │INPUT0.mkv│ │ │ │OUTPUT.mp4 │ └──────────┴────────────────────┘ ├────────────────────┤ │ ┌──────────┬────────────────────┐ │ │ │ │ demuxer 1│ │ packets │elementary stream 1 │ │ ╞══════════╡elementary stream 0 ├────────⮞│ │ │ │INPUT1.aac│ │ └────────────────────┴───────────┘ └──────────┴────────────────────┘
that can be built by the commandline
ffmpeg -i INPUT0.mkv -i INPUT1.aac -map 0:0 -map 1:0 -c copy OUTPUT.mp4
The output -map option is used twice here, creating two streams in the output file - one fed by the first input and one by the second. The single instance of the -c option selects streamcopy for both of those streams. You could also use multiple instances of this option together with Stream specifiers to apply different values to each stream, as will be demonstrated in following sections.
A converse scenario is splitting multiple streams from a single input into multiple outputs:
┌──────────┬─────────────────────┐ ┌───────────────────┬───────────┐ │ demuxer │ │ packets │ │ muxer 0 │ ╞══════════╡ elementary stream 0 ├─────────⮞│elementary stream 0╞═══════════╡ │ │ │ │ │OUTPUT0.mp4│ │INPUT.mkv ├─────────────────────┤ └───────────────────┴───────────┘ │ │ │ packets ┌───────────────────┬───────────┐ │ │ elementary stream 1 ├─────────⮞│ │ muxer 1 │ │ │ │ │elementary stream 0╞═══════════╡ └──────────┴─────────────────────┘ │ │OUTPUT1.mp4│ └───────────────────┴───────────┘
built with
ffmpeg -i INPUT.mkv -map 0:0 -c copy OUTPUT0.mp4 -map 0:1 -c copy OUTPUT1.mp4
Note how a separate instance of the -c option is needed for every output file even though their values are the same. This is because non-global options (which is most of them) only apply in the context of the file before which they are placed.
These examples can of course be further generalized into arbitrary remappings of any number of inputs into any number of outputs.
标签:ffmpeg,stream,mkv,mp4,Streamcopy,output,elementary,input From: https://www.cnblogs.com/sathcal/p/18537703