1- from . import ffmpegprocess , configure , utils , probe , FFmpegError
1+ from collections .abc import Sequence
2+ from . import ffmpegprocess , configure , utils , FFmpegError
23
34__all__ = ["transcode" ]
45
56
67def transcode (
7- input_url ,
8- output_url ,
8+ inputs ,
9+ outputs ,
910 progress = None ,
1011 overwrite = None ,
1112 show_log = None ,
@@ -14,12 +15,14 @@ def transcode(
1415 pass1_extras = None ,
1516 ** options
1617):
17- """Transcode a media file to another format/encoding
18+ """Transcode media files to another format/encoding
1819
19- :param input_url: url/path of the input media file
20- :type input_url: str
21- :param output_url: url/path of the output media file
22- :type output_url: str
20+ :param inputs: url/path of the input media file or a sequence of tuples, each
21+ containing an input url and its options dict
22+ :type inputs: str or sequence of (str,dict)
23+ :param outputs: url/path of the output media file or a sequence of tuples, each
24+ containing an output url and its options dict
25+ :type outputs: str or sequence of (str, dict)
2326 :param progress: progress callback function, defaults to None
2427 :type progress: callable object, optional
2528 :param overwrite: True to overwrite if output url exists, defaults to None
@@ -40,36 +43,44 @@ def transcode(
4043 option names as is. For input options, prepend "input\_" to
4144 the option name. For example, input_r=2000 to force the
4245 input frame rate to 2000 frames/s (see :doc:`options`).
46+
47+ If multiple inputs or outputs are specified, these input
48+ or output options specified here are treated as common
49+ options, and the url-specific duplicate options in the
50+ ``inputs`` or ``outputs`` sequence will overwrite those
51+ specified here.
4352 :type \\ **options: dict, optional
4453 :return: returncode of FFmpeg subprocess
4554 :rtype: int
4655
4756
4857 """
4958
59+ # split input and global options from options
5060 input_options = utils .pop_extra_options (options , "_in" )
61+ global_options = utils .pop_global_options (options )
5162
52- input_url , stdin , input = configure .check_url (
53- input_url , False , input_options .get ("f" , None )
54- )
55- output_url , stdout , _ = configure .check_url (output_url , True )
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 )]
68+
69+ # initialize FFmpeg argument dict
70+ args = configure .empty (global_options )
5671
57- args = configure .empty ()
58- configure .add_url (args , "input" , input_url , input_options )
59- configure .add_url (args , "output" , output_url , options )
72+ for url , opts in inputs :
73+ opts = {** input_options , ** (opts or {})}
74+ input_url , stdin , input = configure .check_url (url , False , opts .get ("f" , None ))
75+ configure .add_url (args , "input" , input_url , opts )
6076
61- # if output pix_fmt defined, get input pix_fmt to check for transparency change
62- # TODO : stream spec?
63- pix_fmt = options .get ("pix_fmt" , None )
64- pix_fmt_in = input_options .get ("pix_fmt" , None )
65- if pix_fmt is not None and pix_fmt_in is None :
66- try :
67- pix_fmt = probe .video_streams_basic (input_url , 0 )[0 ]["pix_fmt" ]
68- except :
69- pass # filter or invalid url, let ffmpeg complain if there is a problem
77+ for url , opts in outputs :
78+ opts = {** options , ** (opts or {})}
79+ output_url , stdout , _ = configure .check_url (url , True )
80+ i , _ = configure .add_url (args , "output" , output_url , opts )
7081
71- # convert basic VF options to vf option
72- configure .build_basic_vf (args , utils . alpha_change ( pix_fmt_in , pix_fmt , - 1 ) )
82+ # convert basic VF options to vf option
83+ configure .build_basic_vf (args , None , i )
7384
7485 kwargs = (
7586 {
0 commit comments