[FFmpeg-user] How to embed subtitles into video using Python
Jim DeLaHunt
list+ffmpeg-user at jdlh.com
Wed Jul 6 23:36:30 EEST 2022
On 2022-07-06 02:46, Pavel Yermolenko via ffmpeg-user wrote:
> Hello,
>
> I'm looking for a command format to embed subtitles into video (not to
> burn them).
>
> This command, that I found somewhere on the web works fine - the
> subtitles are just embedded into video, quite rapid process.
>
> ffmpeg -i video.mp4 -i video.srt -map 0:v -map 0:a -c copy -map 1
> -c:s:0 mov_text -metadata:s:s:0 language=fra output.mp4
>
> I need to process many files in batch mode, so I decided to use Python.
>
Hello, Pavel. I am Jim. I have done quite a bit of work recently with
Python programs which call FFmpeg. Let me see if I can help.
> In Python there is ffmeg support package: *ffmpeg-python*.
> ffmpeg-python 0.2.0 <https://pypi.org/project/ffmpeg-python/>
> Unfortunately in the documentation [there] is no examples on how to
> process subtitles.
For what it is worth, I looked at using the ffmpeg-python package for my
work, and decided it did not do what I wanted. I construct my FFmpeg
invocation as a Python list of strings, and invoke it using
`subprocess.run()`. This is also what Carl Zwanzig suggests.
> What option in the command I wrote at the beginning causes the
> subtitles to be embedded as metadata, and not rendered with particular
> frames?
I believe that in your example ffmpeg command above, it is `-c:s:0
mov_text` which embeds the subtitles in the output, using the mov_text
codec, with supporting roles by `-metadata:s:s:0 language=fra` and `-map
1`. In the bad example you posted, the command uses the subtitles filter
instead, and it burns subtitles into video frame instead of embedding
subtitle text in metadata.
See <http://ffmpeg.org/ffmpeg-all.html#Main-options> for a description
of the `-c` and `-metadata` options. See
<http://ffmpeg.org/ffmpeg-all.html#Advanced-options> for a description
of the `-map` option.
But perhaps you are asking, how to specify those options via the
*ffmpeg-python* package? You are right, the documentation does not
describe this well. The clue seems to be in the .run() and .run_async()
function documentation: "**kwargs – keyword-arguments passed to
get_args()". (See: <https://kkroening.github.io/ffmpeg-python/#ffmpeg.run>).
So I guess that this asks you to do either (and stand by for a
discussion of the really big problem with this):
ffmpeg
.input(input_dir+video_file)
.input(input_dir+subtl_file)
.get_args(map='0:v', map='0:a', c='copy', map='1',
'c:s:0'='mov_text', 'metadata:s:s:0'='language=fra') ***Big problem!
.output(input_dir+'output.mp4')
.run()
Or, because .run() and .run_async() take keyword args,
ffmpeg
.input(input_dir+video_file)
.input(input_dir+subtl_file)
.output(input_dir+'output.mp4')
.run(map='0:v', map='0:a', c='copy', map='1', 'c:s:0'='mov_text',
'metadata:s:s:0'='language=fra') ***Big problem!
There is, of course, a big problem with this list of keyword args. That
is that the syntax of Python keyword args is more limited than the
syntax of ffmpeg command-line options. It is not valid to have the same
key used multiple times in a kwargs group, but this FFmpeg command line
uses `-map` three times. It is not valid to have colons in keyword
names, but this FFmpeg command line uses options like `-c:s:0`.
It might be that the author of `ffmpeg-python` thought about this
problem, and has a solution. Finding it will probably require reading
the source code. I have not taken the time to do this. So I don't know
how to solve the problem. My answer to these limitations, for my
program, was to invoke FFmpeg directly using Python's `subprocess.run()`.
If you find out how `ffmpeg-python` deals with this limitation, I
encourage you to post the answer here. It would be good for the archives
of this list to have the answer. Also, consider making a pull request at
the GitHub repo for `ffmpeg-python` which improves the documentation to
answer this question. That will help future people in your situation,
and in mine.
I hope this is helpful for you.
--Jim DeLaHunt, Vancouver, Canada
More information about the ffmpeg-user
mailing list