ffmpeg-python icon indicating copy to clipboard operation
ffmpeg-python copied to clipboard

multiple values 'map'

Open BramFr opened this issue 4 years ago • 5 comments

Hey,

is there any way to have multi values options like map?

ffmpeg.output(streams_input, path_movie_mp4, **ffmpeg_kwargs).global_args('-map', '0').global_args('-map', '0:m:language:eng').run()

or

ffmpeg.output(streams_input, map=0, map='0:m:language:eng', path_movie_mp4, **ffmpeg_kwargs).run()

I`ll create a python script that will run on a directory within a lot of mkv files. I want to convert every mkv file to mp4. But i do not want any audio language only eng and dutch.

TypeError: output() got multiple values for keyword argument 'map'

BramFr avatar Sep 18 '20 12:09 BramFr

Mapping is handled by ffmpeg-python. You can see this by running ffmpeg.output().compile(). The API Reference documentation shows you how to specify which streams you want to have mapped to your output. Here's an example of how I've used ffmpeg-python to select streams for batch conversion:

outputVid = inputFile['v:0'].filter_('subtitles', subfile, si=subIndex)
outputAud = inputFile['a:0']

ffmpegRun = ffmpeg.output(outputVid, outputAud, outFilename, **ffmpegFlags).run()

You can see here I've specified the first video stream and the first audio stream. Input nodes expose their streams through a dict, and you can specify them using FFMPEG's stream identifiers.

Kotters avatar Sep 25 '20 21:09 Kotters

Mapping is handled by ffmpeg-python. You can see this by running ffmpeg.output().compile(). The API Reference documentation shows you how to specify which streams you want to have mapped to your output. Here's an example of how I've used ffmpeg-python to select streams for batch conversion:

outputVid = inputFile['v:0'].filter_('subtitles', subfile, si=subIndex)
outputAud = inputFile['a:0']

ffmpegRun = ffmpeg.output(outputVid, outputAud, outFilename, **ffmpegFlags).run()

You can see here I've specified the first video stream and the first audio stream. Input nodes expose their streams through a dict, and you can specify them using FFMPEG's stream identifiers.

I understand. But sometimes i have 3 outputAud and the other time just only one. it's not a dict that i can use same as **ffmpegFlags

BramFr avatar Sep 30 '20 05:09 BramFr

I have 4 streams (video, audio, subtitles, attachments) to copy, so I need

'map': '0:s?',
'map': '0:t',

but dict doesn't support duplicates so it ignores 0:s? and only takes 0:t

I tried

stream = stream.global_args('-map', '0:s?')
stream = stream.global_args('-map', '0:t')

but it says trailing options found which will be ignored.

modbender avatar Jun 04 '21 11:06 modbender

I solved multiple map values with:

# The raw command I'm recreating in python using ffmpeg-python library: 
# ffmpeg -i example.webm -i example.ogg -map 0:v -map 1:a -shortest output.mp4

# handles multiple input
video = ffmpeg.input(in_path_video)
audio = ffmpeg.input(in_path_audio)

# handles multiple -map flags
output_video = video['v']
output_audio = audio['a']

ffmpeg
      .filter([video, audio], 'overlay', 10, 10)
      .output(
           output_video,
           output_audio,
           out_path,
           shortest=1,
       )
       .run(
           capture_stdout=True,
           capture_stderr=True,
       )

# for debugging - what do my args look like?       
command_args = ffmpeg.output(output_video, output_audio, out_path, shortest=1)
print(ffmpeg.get_args(command_args))

# printed args - as you can see everything I specified in my bash command is there
[u'-i', 'example.webm', u'-i', 'example.ogg', u'-map', u'0:v', u'-map', u'1:a', u'-shortest', u'1', 'output.mp4']

sophiefitzpatrick avatar Aug 10 '21 11:08 sophiefitzpatrick

This lib is much less intuitive than command line for tricky cases.

PiotrDabkowski avatar Apr 11 '22 14:04 PiotrDabkowski