Hello,
I'm not 100% sure this is an issue with this library or if it's something else, but basically I am attempting to use the 'subtitles' filter by feeding it an mkv file, ffmpeg always crashes and when I printed the stream arguments I got the below:
['-i', "tes't.mkv", '-filter_complex', "[0]subtitles=tes\\\\\\\\\\\\\\'t.mkv[s0]", '-map', '[s0]', "tes't.mkv2.mkv"]
This is for a file called tes't.mkv
This is a script I recreated this with:
import ffmpeg
import sys
file_path = "tes't.mkv"
def convert_video(file_path):
#Create a stream
stream = ffmpeg.input(file_path)
#Apply subtitle filter
stream = ffmpeg.filter_(stream,'subtitles',str(file_path))
#Output file
stream = ffmpeg.output(stream, file_path + '2.mkv')
#Get to work
print(ffmpeg.get_args(stream))
convert_video(file_path)
If I attempt to run this stream then ffmpeg crashes with the below error:
[Parsed_subtitles_0 @ 0x5591972f24a0] Unable to open tes\'t.mkv
[AVFilterGraph @ 0x5591972cd1c0] Error initializing filter 'subtitles' with args 'tes\\\'t.mkv'
Error initializing complex filters.
No such file or directory
Traceback (most recent call last):
File "test.py", line 16, in <module>
convert_video(file_path)
File "test.py", line 14, in convert_video
ffmpeg.run(stream)
File "/home/baa/.local/lib/python3.6/site-packages/ffmpeg/_run.py", line 212, in run
raise Error('ffmpeg', out, err)
ffmpeg._run.Error: ffmpeg error (see stderr output for detail)
Possibly relevant discussion: https://github.com/kkroening/ffmpeg-python/pull/25 (merged PR)
It might be a bug in ffmpeg. Try running the same command from the command-line and do the escaping yourself. No matter how many or few \ characters you put in the command line, ffmpeg chokes.
Works(subtitles in sub.srt):
ffmpeg -i in.mp4 -filter_complex "[0]subtitles=sub.srt[s0]" -map "[s0]" out.mp4 -y
Doesn't work (subtitles in sub'tst.srt):
ffmpeg -i in.mp4 -filter_complex "[0]subtitles=sub'tst.srt[s0]" -map "[s0]" out.mp4 -y
ffmpeg -i in.mp4 -filter_complex "[0]subtitles=sub\'tst.srt[s0]" -map "[s0]" out.mp4 -y
ffmpeg -i in.mp4 -filter_complex "[0]subtitles=sub\\'tst.srt[s0]" -map "[s0]" out.mp4 -y
ffmpeg -i in.mp4 -filter_complex "[0]subtitles=sub\\\'tst.srt[s0]" -map "[s0]" out.mp4 -y
# (etc)
As 153957 mentioned above, ffmpeg escaping is weird/confusing. Having lots and lots of \ chars to escape a single input character is actually normal: multiple levels of unescaping happen in ffmpeg when parsing the command line, and each layer essentially multiplies the number of escapes characters by 2 (i.e. exponential amounts of escaping). We were equally surprised when figuring this out for the first time.
Also note that there's _yet another_ level of escaping that happens as standard python when printing representations of python strings, e.g.:
>>> chr(92)
'\\'
Running against the same issue when trying to scale down.
Simplified code example:
inputstream = ffmpeg.input(infile, ss='00:00:10.000', t='00:00:20.000')# start after 10s, sequence of 20s duration
# v0 = inputstream['v'].filter_('scale',"320:240") # this doesn't work, resulting in get_args item: '[0:v]scale=320\\\\\\\\\\\\:240[s0]'
v0 = inputstream['v'].filter_('scale',"320x240") # this works, resulting in get_args item '[0:v]scale=320x240[s0]'
a0 = inputstream['a']
outstream = ffmpeg.output(v0,a0, outfile, acodec='aac', audio_bitrate='96K',vcodec='libx265', crf='23' )
print(outstream.get_args())
outstream.run()
I'm actually trying to scale conditionally (only scale down for if source has bigger dimensions), for that I need to enter a more complex scaling value which involves expressions as found on https://trac.ffmpeg.org/wiki/Scaling
Running against the same issue when trying to scale down.
Simplified code example:inputstream = ffmpeg.input(infile, ss='00:00:10.000', t='00:00:20.000')# start after 10s, sequence of 20s duration # v0 = inputstream['v'].filter_('scale',"320:240") # this doesn't work, resulting in get_args item: '[0:v]scale=320\\\\\\\\\\\\:240[s0]' v0 = inputstream['v'].filter_('scale',"320x240") # this works, resulting in get_args item '[0:v]scale=320x240[s0]' a0 = inputstream['a'] outstream = ffmpeg.output(v0,a0, outfile, acodec='aac', audio_bitrate='96K',vcodec='libx265', crf='23' ) print(outstream.get_args()) outstream.run()I'm actually trying to scale conditionally (only scale down for if source has bigger dimensions), for that I need to enter a more complex scaling value which involves expressions as found on https://trac.ffmpeg.org/wiki/Scaling
I ran into the same issue with the crop filter using expressions that requires single quotes. In that case the single quotes should not be escaped for ffmpeg to work correctly. In my case I simply modified the FilterNode._get_filter option (nodes.py file) to remove the escaping of single quotes.
In my use cases I don't need that escaping, however it might be required in other use cases. I feel like fixing this and keep everything else working would require multiple modifications to the code therefore I don't plan on submitting a pull request.
If somebody else has a solution for this, let me know.
Hi, has this problem been solved? I have the same problem.
Most helpful comment
Hi, has this problem been solved? I have the same problem.