Add comprehensive documentation for the -json_cmd, -json_cmd_print,
and -json_cmd_gen options:
- doc/json_cmd.texi: Full reference covering JSON schema, option
types, value encoding, file-loading syntax, decoder definitions,
and round-trip workflow examples
- doc/ffmpeg.texi: Synopsis entries and option descriptions with
cross-references to the new reference document
- doc/examples/json_cmd_*.json: Eight example files demonstrating
simple transcoding, complex filter graphs, multi-input/output
pipelines, image sequences, and lavfi virtual inputs
Signed-off-by: Tom Vaughan
---
doc/examples/json_cmd_complex.json | 29 +
doc/examples/json_cmd_filter_chain.json | 22 +
doc/examples/json_cmd_filter_graph.json | 22 +
doc/examples/json_cmd_image_sequence.json | 19 +
doc/examples/json_cmd_lavfi_input.json | 28 +
doc/examples/json_cmd_multi_io.json | 34 ++
doc/examples/json_cmd_simple.json | 22 +
doc/examples/json_cmd_trim_copy.json | 23 +
doc/ffmpeg.texi | 78 +++
doc/json_cmd.texi | 617 ++++++++++++++++++++++
10 files changed, 894 insertions(+)
create mode 100644 doc/examples/json_cmd_complex.json
create mode 100644 doc/examples/json_cmd_filter_chain.json
create mode 100644 doc/examples/json_cmd_filter_graph.json
create mode 100644 doc/examples/json_cmd_image_sequence.json
create mode 100644 doc/examples/json_cmd_lavfi_input.json
create mode 100644 doc/examples/json_cmd_multi_io.json
create mode 100644 doc/examples/json_cmd_simple.json
create mode 100644 doc/examples/json_cmd_trim_copy.json
create mode 100644 doc/json_cmd.texi
diff --git a/doc/examples/json_cmd_complex.json
b/doc/examples/json_cmd_complex.json
new file mode 100644
index 0000000000..13a3981880
--- /dev/null
+++ b/doc/examples/json_cmd_complex.json
@@ -0,0 +1,29 @@
+{
+ "global_options": {
+ "y": true,
+ "filter_complex": "[0:v]scale=1280:720[v];[0:a]volume=1.5[a]"
+ },
+ "inputs": [
+ {
+ "url": "input.mp4",
+ "options": {
+ "ss": "00:01:00",
+ "t": "30"
+ }
+ }
+ ],
+ "outputs": [
+ {
+ "url": "output.mp4",
+ "options": {
+ "map": ["[v]", "[a]"],
+ "c:v": "libx264",
+ "preset": "medium",
+ "crf": "23",
+ "c:a": "aac",
+ "b:a": "128k",
+ "movflags": "+faststart"
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_filter_chain.json
b/doc/examples/json_cmd_filter_chain.json
new file mode 100644
index 0000000000..6719da724e
--- /dev/null
+++ b/doc/examples/json_cmd_filter_chain.json
@@ -0,0 +1,22 @@
+{
+ "global_options": {
+ "y": true
+ },
+ "inputs": [
+ {
+ "url": "input.mp4",
+ "options": {}
+ }
+ ],
+ "outputs": [
+ {
+ "url": "output.mp4",
+ "options": {
+ "vf":
"eq=brightness=0.0:contrast=1.075,unsharp=5:5:1.05:5:5:0.0",
+ "pix_fmt": "yuv420p",
+ "c:v": "libx264",
+ "crf": "18"
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_filter_graph.json
b/doc/examples/json_cmd_filter_graph.json
new file mode 100644
index 0000000000..acdac67c56
--- /dev/null
+++ b/doc/examples/json_cmd_filter_graph.json
@@ -0,0 +1,22 @@
+{
+ "global_options": {
+ "y": true
+ },
+ "inputs": [
+ {
+ "url": "input.mp4",
+ "options": {}
+ }
+ ],
+ "outputs": [
+ {
+ "url": "side_by_side.mp4",
+ "options": {
+ "filter_complex": "[0]split[a][b]; [a]crop=iw/2:ih:0:0[left];
[b]crop=iw/2:ih:iw/2:0,eq=brightness=0.1:contrast=1.2[right];
[left][right]hstack=inputs=2[out]",
+ "map": "[out]",
+ "c:v": "libx264",
+ "crf": "20"
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_image_sequence.json
b/doc/examples/json_cmd_image_sequence.json
new file mode 100644
index 0000000000..2f5c974a22
--- /dev/null
+++ b/doc/examples/json_cmd_image_sequence.json
@@ -0,0 +1,19 @@
+{
+ "global_options": {
+ "y": true
+ },
+ "inputs": [
+ {
+ "url": "input.mp4",
+ "options": {}
+ }
+ ],
+ "outputs": [
+ {
+ "url": "frame_%04d.png",
+ "options": {
+ "frames:v": "100"
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_lavfi_input.json
b/doc/examples/json_cmd_lavfi_input.json
new file mode 100644
index 0000000000..bb95c08672
--- /dev/null
+++ b/doc/examples/json_cmd_lavfi_input.json
@@ -0,0 +1,28 @@
+{
+ "global_options": {
+ "y": true
+ },
+ "inputs": [
+ {
+ "url": "anullsrc=channel_layout=stereo:sample_rate=44100",
+ "options": {
+ "f": "lavfi"
+ }
+ },
+ {
+ "url": "input.mp4",
+ "options": {}
+ }
+ ],
+ "outputs": [
+ {
+ "url": "output_with_audio.mp4",
+ "options": {
+ "map": ["1:v", "0:a"],
+ "c:v": "copy",
+ "c:a": "aac",
+ "shortest": true
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_multi_io.json
b/doc/examples/json_cmd_multi_io.json
new file mode 100644
index 0000000000..3a06af4176
--- /dev/null
+++ b/doc/examples/json_cmd_multi_io.json
@@ -0,0 +1,34 @@
+{
+ "global_options": {
+ "y": true
+ },
+ "inputs": [
+ {
+ "url": "video_only.mp4",
+ "options": {}
+ },
+ {
+ "url": "audio_only.wav",
+ "options": {}
+ }
+ ],
+ "outputs": [
+ {
+ "url": "combined.mp4",
+ "options": {
+ "map": ["0:v", "1:a"],
+ "c:v": "copy",
+ "c:a": "aac",
+ "shortest": true
+ }
+ },
+ {
+ "url": "audio_only_output.mp3",
+ "options": {
+ "map": ["1:a"],
+ "c:a": "libmp3lame",
+ "b:a": "320k"
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_simple.json
b/doc/examples/json_cmd_simple.json
new file mode 100644
index 0000000000..28e1560979
--- /dev/null
+++ b/doc/examples/json_cmd_simple.json
@@ -0,0 +1,22 @@
+{
+ "global_options": {
+ "y": true,
+ "loglevel": "info"
+ },
+ "inputs": [
+ {
+ "url": "input.mp4",
+ "options": {}
+ }
+ ],
+ "outputs": [
+ {
+ "url": "output.mp4",
+ "options": {
+ "c:v": "libx264",
+ "c:a": "aac",
+ "b:v": "2M"
+ }
+ }
+ ]
+}
diff --git a/doc/examples/json_cmd_trim_copy.json
b/doc/examples/json_cmd_trim_copy.json
new file mode 100644
index 0000000000..3e2410f3ec
--- /dev/null
+++ b/doc/examples/json_cmd_trim_copy.json
@@ -0,0 +1,23 @@
+{
+ "global_options": {
+ "y": true
+ },
+ "inputs": [
+ {
+ "url": "input.mov",
+ "options": {
+ "ss": "00:01:00",
+ "t": "30"
+ }
+ }
+ ],
+ "outputs": [
+ {
+ "url": "clip.mov",
+ "options": {
+ "codec": "copy",
+ "map": "0:v"
+ }
+ }
+ ]
+}
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 533131adfc..72b334db96 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -14,6 +14,12 @@
ffmpeg [@var{global_options}] @{[@var{input_file_options}] -i
@file{input_url}@} ... @{[@var{output_file_options}] @file{output_url}@} ...
+ffmpeg -json_cmd @file{config.json}
+
+ffmpeg -json_cmd_print @file{config.json}
+
+ffmpeg -json_cmd_gen [@var{global_options}] @{[@var{input_file_options}] -i
@file{input_url}@} ... @{[@var{output_file_options}] @file{output_url}@} ...
+
@chapter Description
@c man begin DESCRIPTION
@@ -778,6 +784,76 @@ stream from @file{B.mp4}.
@table @option
+@item -json_cmd @var{filename} (@emph{global})
+Read all options from a JSON configuration file instead of the command line.
+When this option is used, it must be the only argument (besides the program
name).
+
+The JSON file must contain an object with the following structure:
+
+@example
+@{
+ "global_options": @{
+ "y": true,
+ "loglevel": "info"
+ @},
+ "inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{
+ "ss": "00:01:00",
+ "t": "30"
+ @}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "c:v": "libx264",
+ "c:a": "aac",
+ "map": ["0:v", "0:a"]
+ @}
+ @}
+ ]
+@}
+@end example
+
+Option values may be:
+@itemize
+@item
+A string: added as @code{-option value}.
+@item
+A number: converted to a string and added as @code{-option value}.
+@item
+@code{true}: added as a flag @code{-option}.
+@item
+@code{false}: the option is skipped (no-op).
+@item
+An array of strings/numbers: the option is repeated for each element,
+e.g. @code{"map": ["0:v", "0:a"]} becomes @code{-map 0:v -map 0:a}.
+@end itemize
+
+@item -json_cmd_print @var{filename} (@emph{global})
+Parse a JSON configuration file and print the equivalent shell command line
+to standard output, then exit without executing. This is useful for
+verifying a JSON file, debugging, or generating a command that can be
+pasted into a shell. Arguments containing shell metacharacters are
+automatically single-quoted.
+
+@item -json_cmd_gen (@emph{global})
+Parse the remaining command-line arguments and print an equivalent
+JSON command file to standard output, then exit without executing.
+This is the reverse of @option{-json_cmd}: it converts a regular ffmpeg
+command line into the JSON format that @option{-json_cmd} accepts.
+Unknown options (e.g.@ codec-specific AVOptions not compiled into
+this build) are handled gracefully by assuming they take one argument.
+Repeated options like @option{-map} are emitted as JSON arrays.
+
+Example:
+@example
+ffmpeg -json_cmd_gen -y -i input.mp4 -c:v libx264 -c:a aac output.mkv
+@end example
+
@item -f @var{fmt} (@emph{input/output})
Force input or output file format. The format is normally auto detected for
input
files and guessed from the file extension for output files, so this option is
not
@@ -3270,6 +3346,8 @@ ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext
@end itemize
@c man end EXAMPLES
+@include json_cmd.texi
+
@include config.texi
@ifset config-all
@ifset config-avutil
diff --git a/doc/json_cmd.texi b/doc/json_cmd.texi
new file mode 100644
index 0000000000..fe31b9b4a8
--- /dev/null
+++ b/doc/json_cmd.texi
@@ -0,0 +1,617 @@
+@chapter JSON Command Files
+@c man begin JSON COMMAND FILES
+
+@command{ffmpeg} can read its entire configuration from a JSON file instead
+of the command line. This is useful for:
+
+@itemize @bullet
+@item
+Long or complex commands that are difficult to manage as shell strings.
+@item
+Programmatic generation of ffmpeg commands from other tools.
+@item
+Avoiding shell escaping issues with filter graphs, metadata, and special
characters.
+@item
+Storing reproducible encoding configurations in version control.
+@end itemize
+
+@section Usage
+
+@example
+ffmpeg -json_cmd @var{config.json}
+@end example
+
+When @code{-json_cmd} is used, it must be the @emph{only} argument.
+The JSON file replaces the entire command line.
+
+@section Printing the Equivalent Command Line
+
+@example
+ffmpeg -json_cmd_print @var{config.json}
+@end example
+
+This parses the JSON file, constructs the equivalent command line with
+proper shell escaping, prints it to standard output, and exits without
+executing. This is useful for:
+
+@itemize @bullet
+@item
+Verifying that a JSON file produces the intended command.
+@item
+Generating a pasteable shell command from a JSON configuration.
+@item
+Debugging option ordering or quoting issues.
+@end itemize
+
+Arguments containing shell metacharacters (spaces, quotes, semicolons,
+brackets, pipes, etc.) are automatically single-quoted. Single quotes
+within arguments are escaped as @code{'\\''}.
+
+Example:
+@example
+$ ffmpeg -json_cmd_print config.json
+ffmpeg -y -filter_complex '[0:v]scale=1280:720[v];[0:a]volume=1.5[a]' -i
input.mp4 -map '[v]' -map '[a]' -c:v libx264 output.mp4
+@end example
+
+@section Generating JSON from a Command Line
+
+@example
+ffmpeg -json_cmd_gen [@var{options}] @{-i @var{input}@} ... @var{output} ...
+@end example
+
+This parses the remaining arguments as a normal ffmpeg command line and
+prints the equivalent JSON command file to standard output, then exits
+without executing. It is the reverse of @option{-json_cmd}.
+
+@itemize @bullet
+@item
+Quickly convert an existing command into JSON for reuse or automation.
+@item
+Options not found in this build (e.g.@ codec-specific AVOptions such as
+@option{-preset} when the codec is not compiled in) are handled
+gracefully and assumed to take one argument.
+@item
+Repeated options (e.g.@ @option{-map}) are emitted as JSON arrays.
+@end itemize
+
+Example:
+@example
+$ ffmpeg -json_cmd_gen -y -i in.mp4 -map 0:v -map 0:a -c:v libx264 out.mkv
+@{
+ "global_options": @{
+ "y": true
+ @},
+ "inputs": [
+ @{
+ "url": "in.mp4",
+ "options": @{@}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "out.mkv",
+ "options": @{
+ "map": ["0:v", "0:a"],
+ "c:v": "libx264"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@section JSON Structure
+
+The JSON file must contain a single root object. All fields are optional
+except the root object itself.
+
+@example
+@{
+ "global_options": @{ ... @},
+ "inputs": [ ... ],
+ "outputs": [ ... ],
+ "decoders": [ ... ]
+@}
+@end example
+
+@subsection global_options
+
+An object whose keys are option names (without the leading @code{-}) and
+whose values are the option arguments.
+
+@example
+"global_options": @{
+ "y": true,
+ "loglevel": "info",
+ "filter_complex": "[0:v]scale=1280:720[v];[0:a]volume=1.5[a]"
+@}
+@end example
+
+@subsection inputs
+
+An array of input file objects. Each object must have a @code{"url"} string
+and may have an @code{"options"} object. Options are emitted @emph{before}
+the @code{-i} flag, matching the standard command-line convention.
+
+@example
+"inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{
+ "ss": "00:01:00",
+ "t": "30",
+ "f": "mp4"
+ @}
+ @}
+]
+@end example
+
+@subsection outputs
+
+An array of output file objects. Each object must have a @code{"url"} string
+and may have an @code{"options"} object. Options are emitted before the
+output URL.
+
+@example
+"outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "c:v": "libx264",
+ "c:a": "aac",
+ "b:v": "2M",
+ "map": ["0:v", "0:a"],
+ "movflags": "+faststart"
+ @}
+ @}
+]
+@end example
+
+@subsection decoders
+
+An array of loopback decoder objects (corresponding to the @code{-dec}
+option). Each object must have a @code{"name"} string and may have an
+@code{"options"} object.
+
+@example
+"decoders": [
+ @{
+ "name": "decoder_name",
+ "options": @{ @}
+ @}
+]
+@end example
+
+@section Value Types
+
+JSON values in option objects are converted to command-line arguments
+according to their type.
+
+@table @asis
+@item String
+Added as @code{-option value}. Strings have no length limit, making them
+ideal for long filter graphs.
+@example
+"filter_complex": "[0:v]scale=1280:720,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v]"
+@end example
+
+@item Number
+Converted to a string. Integers are printed without a decimal point.
+@example
+"ar": 48000 @result{} -ar 48000
+"q:v": 2.5 @result{} -q:v 2.5
+@end example
+
+@item @code{true}
+Emits the option as a flag with no argument.
+@example
+"y": true @result{} -y
+"shortest": true @result{} -shortest
+@end example
+
+@item @code{false}
+Skipped (not emitted). To negate a boolean option, use the
+@code{no}-prefixed name with @code{true}:
+@example
+"noautorotate": true @result{} -noautorotate
+"nostdin": true @result{} -nostdin
+@end example
+
+@item Array
+The option is repeated for each element. Use this for any option that
+can appear multiple times: @code{-map}, @code{-attach}, @code{-filter_complex},
+@code{-metadata}, etc.
+@example
+"map": ["0:v", "0:a"]
+ @result{} -map 0:v -map 0:a
+
+"filter_complex": ["[0:v]scale=640:480[v]", "[0:a]volume=2[a]"]
+ @result{} -filter_complex [0:v]scale=640:480[v] -filter_complex
[0:a]volume=2[a]
+
+"metadata": ["title=My Video", "artist=Author"]
+ @result{} -metadata title=My Video -metadata artist=Author
+@end example
+
+@item @code{null}
+Skipped. Useful for conditionally disabling an option in generated JSON.
+@end table
+
+@section Stream Specifiers
+
+Stream specifiers are part of the option key, exactly as on the command line.
+The colon syntax works naturally in JSON keys:
+
+@example
+"c:v": "libx264" @result{} -c:v libx264
+"c:a": "aac" @result{} -c:a aac
+"b:v:0": "5M" @result{} -b:v:0 5M
+"b:a:1": "128k" @result{} -b:a:1 128k
+"filter:v": "scale=640:480" @result{} -filter:v scale=640:480
+"metadata:s:v:0": "title=Video" @result{} -metadata:s:v:0 title=Video
+"disposition:a:0": "default" @result{} -disposition:a:0 default
+@end example
+
+@section File-Loading Syntax
+
+FFmpeg supports loading an option's value from a file using the @code{-/option}
+syntax. In JSON, prefix the key with @code{/}:
+
+@example
+"/filter_complex": "my_filtergraph.txt"
+ @result{} -/filter_complex my_filtergraph.txt
+@end example
+
+This reads the contents of @file{my_filtergraph.txt} and uses it as the
+value for @code{-filter_complex}.
+
+@section AVOptions (Codec/Format/Filter Options)
+
+Options not built into ffmpeg itself (such as codec-specific options) are
+handled through FFmpeg's AVOptions system. They work identically in JSON:
+
+@example
+"preset": "medium" @result{} -preset medium (x264/x265 preset)
+"crf": "23" @result{} -crf 23 (x264/x265 quality)
+"movflags": "+faststart" @result{} -movflags +faststart
+"profile:v": "high" @result{} -profile:v high
+"level": "4.1" @result{} -level 4.1
+@end example
+
+@section Complete Examples
+
+@subsection Simple Transcoding
+
+Equivalent to:
+@code{ffmpeg -y -i input.mp4 -c:v libx264 -c:a aac -b:v 2M output.mp4}
+
+@example
+@{
+ "global_options": @{
+ "y": true
+ @},
+ "inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{@}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "c:v": "libx264",
+ "c:a": "aac",
+ "b:v": "2M"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Trimming with Seek
+
+Equivalent to:
+@code{ffmpeg -y -ss 00:01:00 -t 30 -i input.mp4 -c copy output.mp4}
+
+@example
+@{
+ "global_options": @{ "y": true @},
+ "inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{
+ "ss": "00:01:00",
+ "t": "30"
+ @}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "c": "copy"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Complex Filter Graph
+
+Equivalent to:
+@code{ffmpeg -y -i input.mp4 -filter_complex
"[0:v]scale=1280:720[v];[0:a]volume=1.5[a]" -map "[v]" -map "[a]" -c:v libx264
-preset medium -crf 23 -c:a aac -b:a 128k -movflags +faststart output.mp4}
+
+@example
+@{
+ "global_options": @{
+ "y": true,
+ "filter_complex": "[0:v]scale=1280:720[v];[0:a]volume=1.5[a]"
+ @},
+ "inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{@}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "map": ["[v]", "[a]"],
+ "c:v": "libx264",
+ "preset": "medium",
+ "crf": "23",
+ "c:a": "aac",
+ "b:a": "128k",
+ "movflags": "+faststart"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Multiple Inputs and Outputs
+
+Equivalent to:
+@code{ffmpeg -y -i video.mp4 -i audio.wav -map 0:v -map 1:a -c:v copy -c:a aac
-shortest combined.mp4 -map 1:a -c:a libmp3lame -b:a 320k audio.mp3}
+
+@example
+@{
+ "global_options": @{ "y": true @},
+ "inputs": [
+ @{ "url": "video.mp4", "options": @{@} @},
+ @{ "url": "audio.wav", "options": @{@} @}
+ ],
+ "outputs": [
+ @{
+ "url": "combined.mp4",
+ "options": @{
+ "map": ["0:v", "1:a"],
+ "c:v": "copy",
+ "c:a": "aac",
+ "shortest": true
+ @}
+ @},
+ @{
+ "url": "audio.mp3",
+ "options": @{
+ "map": ["1:a"],
+ "c:a": "libmp3lame",
+ "b:a": "320k"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Two-Pass Encoding
+
+Two-pass encoding requires running ffmpeg twice. Use two separate JSON files:
+
+@b{Pass 1} (@file{pass1.json}):
+@example
+@{
+ "global_options": @{ "y": true @},
+ "inputs": [
+ @{ "url": "input.mp4", "options": @{@} @}
+ ],
+ "outputs": [
+ @{
+ "url": "/dev/null",
+ "options": @{
+ "c:v": "libx264",
+ "b:v": "2M",
+ "pass": "1",
+ "passlogfile": "ffmpeg2pass",
+ "an": true,
+ "f": "null"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@b{Pass 2} (@file{pass2.json}):
+@example
+@{
+ "global_options": @{ "y": true @},
+ "inputs": [
+ @{ "url": "input.mp4", "options": @{@} @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "c:v": "libx264",
+ "b:v": "2M",
+ "pass": "2",
+ "passlogfile": "ffmpeg2pass",
+ "c:a": "aac"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Overlay with Hardware Acceleration
+
+Equivalent to:
+@code{ffmpeg -y -init_hw_device vaapi=va:/dev/dri/renderD128 -hwaccel vaapi
-hwaccel_output_format vaapi -i input.mp4 -i logo.png -filter_complex
"[1:v]format=nv12,hwupload[logo];[0:v][logo]overlay_vaapi=x=10:y=10" -c:v
h264_vaapi -b:v 5M output.mp4}
+
+@example
+@{
+ "global_options": @{
+ "y": true,
+ "init_hw_device": "vaapi=va:/dev/dri/renderD128"
+ @},
+ "inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{
+ "hwaccel": "vaapi",
+ "hwaccel_output_format": "vaapi"
+ @}
+ @},
+ @{
+ "url": "logo.png",
+ "options": @{@}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mp4",
+ "options": @{
+ "filter_complex":
"[1:v]format=nv12,hwupload[logo];[0:v][logo]overlay_vaapi=x=10:y=10",
+ "c:v": "h264_vaapi",
+ "b:v": "5M"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Network Streaming
+
+Equivalent to:
+@code{ffmpeg -y -re -i input.mp4 -c:v libx264 -preset veryfast -tune
zerolatency -c:a aac -f flv rtmp://server/live/stream}
+
+@example
+@{
+ "global_options": @{ "y": true @},
+ "inputs": [
+ @{
+ "url": "input.mp4",
+ "options": @{ "re": true @}
+ @}
+ ],
+ "outputs": [
+ @{
+ "url": "rtmp://server/live/stream",
+ "options": @{
+ "c:v": "libx264",
+ "preset": "veryfast",
+ "tune": "zerolatency",
+ "c:a": "aac",
+ "f": "flv"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@subsection Extracting Streams with Metadata
+
+Equivalent to:
+@code{ffmpeg -y -i input.mkv -map 0:v -map 0:a:0 -map 0:s:0 -c copy -metadata
title="My Movie" -metadata:s:a:0 language=eng -metadata:s:s:0 language=eng
-disposition:a:0 default -disposition:s:0 0 output.mkv}
+
+@example
+@{
+ "global_options": @{ "y": true @},
+ "inputs": [
+ @{ "url": "input.mkv", "options": @{@} @}
+ ],
+ "outputs": [
+ @{
+ "url": "output.mkv",
+ "options": @{
+ "map": ["0:v", "0:a:0", "0:s:0"],
+ "c": "copy",
+ "metadata": ["title=My Movie"],
+ "metadata:s:a:0": "language=eng",
+ "metadata:s:s:0": "language=eng",
+ "disposition:a:0": "default",
+ "disposition:s:0": "0"
+ @}
+ @}
+ ]
+@}
+@end example
+
+@section Conversion Reference
+
+The following table shows how every FFmpeg command-line pattern maps to JSON.
+
+@multitable @columnfractions .45 .55
+@headitem Command Line @tab JSON
+@item @code{-y}
+@tab @code{"y": true}
+@item @code{-n}
+@tab @code{"n": true}
+@item @code{-loglevel info}
+@tab @code{"loglevel": "info"}
+@item @code{-c:v libx264}
+@tab @code{"c:v": "libx264"}
+@item @code{-b:v 2M}
+@tab @code{"b:v": "2M"}
+@item @code{-ar 48000}
+@tab @code{"ar": 48000}
+@item @code{-ss 00:01:00}
+@tab @code{"ss": "00:01:00"}
+@item @code{-vn}
+@tab @code{"vn": true}
+@item @code{-noautorotate}
+@tab @code{"noautorotate": true}
+@item @code{-map 0:v -map 0:a}
+@tab @code{"map": ["0:v", "0:a"]}
+@item @code{-map -0:s}
+@tab @code{"map": ["-0:s"]}
+@item @code{-filter_complex "..."}
+@tab @code{"filter_complex": "..."}
+@item @code{-/filter_complex graph.txt}
+@tab @code{"/filter_complex": "graph.txt"}
+@item @code{-attach pic.jpg}
+@tab @code{"attach": "pic.jpg"}
+@item @code{-attach a.jpg -attach b.jpg}
+@tab @code{"attach": ["a.jpg", "b.jpg"]}
+@item @code{-metadata title=Test}
+@tab @code{"metadata": "title=Test"}
+@item @code{-preset medium -crf 23}
+@tab @code{"preset": "medium", "crf": "23"}
+@item @code{-movflags +faststart}
+@tab @code{"movflags": "+faststart"}
+@item @code{-init_hw_device vaapi=va:...}
+@tab @code{"init_hw_device": "vaapi=va:..."}
+@end multitable
+
+@section Notes
+
+@itemize @bullet
+@item
+The JSON is converted to a standard argv array and processed by the same
+option parser as normal command-line arguments. Every option that works
+on the command line works identically in JSON.
+@item
+Options added in future FFmpeg versions will work automatically without
+any changes to the JSON parser.
+@item
+AVOptions (codec/format/filter-specific options) work without any special
+handling.
+@item
+JSON's native string handling eliminates shell escaping issues. Filter
+graphs, metadata with special characters, and paths with spaces all work
+without any escaping beyond standard JSON string escaping.
+@item
+Use @code{null} or @code{false} values to conditionally disable options
+when generating JSON programmatically.
+@end itemize
+
+@c man end JSON COMMAND FILES
--
2.49.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]