1- from collections .abc import Sequence
2- from . import ffmpegprocess , configure , utils , FFmpegError
1+ from . import ffmpegprocess as fp , configure , utils , FFmpegError
32
43__all__ = ["transcode" ]
54
@@ -13,13 +12,13 @@ def transcode(
1312 two_pass = False ,
1413 pass1_omits = None ,
1514 pass1_extras = None ,
16- ** options
15+ ** options ,
1716):
1817 """Transcode media files to another format/encoding
1918
2019 :param inputs: url/path of the input media file or a sequence of tuples, each
2120 containing an input url and its options dict
22- :type inputs: str or sequence of (str,dict)
21+ :type inputs: str or a list of str or a sequence of (str,dict)
2322 :param outputs: url/path of the output media file or a sequence of tuples, each
2423 containing an output url and its options dict
2524 :type outputs: str or sequence of (str, dict)
@@ -34,24 +33,24 @@ def transcode(
3433 :type show_log: bool, optional
3534 :param two_pass: True to encode in 2-pass
3635 :param pass1_omits: list of output arguments to ignore in pass 1, defaults to
37- None (removes 'c:a' or 'acodec')
38- :type pass1_omits: seq(str), optional
36+ None (removes 'c:a' or 'acodec'). For multiple outputs,
37+ specify use list of the list of arguments, matching the
38+ length of outputs, for per-output omission.
39+ :type pass1_omits: seq(str), or seq(seq(str)) optional
3940 :param pass1_extras: list of additional output arguments to include in pass 1,
4041 defaults to None (add 'an' if `pass1_omits` also None)
4142 :type pass1_extras: dict(int:dict(str)), optional
4243 :param \\ **options: FFmpeg options. For output and global options, use FFmpeg
43- option names as is. For input options, prepend "input\_ " to
44- the option name. For example, input_r =2000 to force the
45- input frame rate to 2000 frames/s (see :doc:`options`).
44+ option names as is. For input options, append "_in " to the
45+ option name. For example, r_in =2000 to force the input frame
46+ rate to 2000 frames/s (see :doc:`options`).
4647
4748 If multiple inputs or outputs are specified, these input
4849 or output options specified here are treated as common
4950 options, and the url-specific duplicate options in the
5051 ``inputs`` or ``outputs`` sequence will overwrite those
5152 specified here.
5253 :type \\ **options: dict, optional
53- :return: returncode of FFmpeg subprocess
54- :rtype: int
5554
5655
5756 """
@@ -60,38 +59,49 @@ def transcode(
6059 input_options = utils .pop_extra_options (options , "_in" )
6160 global_options = utils .pop_global_options (options )
6261
63- # detect single input/output argument
64- if isinstance (inputs , str ) or not isinstance (inputs , Sequence ):
65- inputs = [(inputs , None )]
66- if isinstance (outputs , str ) or not isinstance (outputs , Sequence ):
67- outputs = [(outputs , None )]
62+ def format_arg (arg , defopts ):
63+ def test (a , is_list ):
64+ try :
65+ assert len (a ) == 2
66+ assert isinstance (a [1 ], dict )
67+ return (a [0 ], {** defopts , ** a [1 ]})
68+ except :
69+ if is_list :
70+ return (a , defopts )
71+ raise
72+
73+ # special case: a list of inputs w/out options
74+ if type (arg ) == list :
75+ return [test (a , True ) for a in arg ]
76+
77+ # attempt to map url-options pairs
78+ try :
79+ return [test (a , False ) for a in arg ]
80+ except :
81+ return [(arg , defopts )]
82+
83+ inputs = format_arg (inputs , input_options )
84+ outputs = format_arg (outputs , options )
6885
6986 # initialize FFmpeg argument dict
7087 args = configure .empty (global_options )
7188
7289 for url , opts in inputs :
73- opts = {** input_options , ** (opts or {})}
7490 input_url , stdin , input = configure .check_url (url , False , opts .get ("f" , None ))
7591 configure .add_url (args , "input" , input_url , opts )
7692
7793 for url , opts in outputs :
78- opts = {** options , ** (opts or {})}
7994 output_url , stdout , _ = configure .check_url (url , True )
8095 i , _ = configure .add_url (args , "output" , output_url , opts )
8196
8297 # convert basic VF options to vf option
8398 configure .build_basic_vf (args , None , i )
8499
85100 kwargs = (
86- {
87- "pass1_omits" : None if pass1_omits is None else [pass1_omits ],
88- "pass1_extras" : None if pass1_extras is None else [pass1_extras ],
89- }
90- if two_pass
91- else {}
101+ {"pass1_omits" : pass1_omits , "pass1_extras" : pass1_extras } if two_pass else {}
92102 )
93103
94- pout = (ffmpegprocess .run_two_pass if two_pass else ffmpegprocess .run )(
104+ pout = (fp .run_two_pass if two_pass else fp .run )(
95105 args ,
96106 progress = progress ,
97107 overwrite = overwrite ,
0 commit comments