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

Error initializing filter 'subtitles' with args

Open X-SZM opened this issue 1 year ago • 6 comments

Here's my python code:

import ffmpeg
input_dir = "C:/Users/27433/Desktop/1/"
video_file = '1_1_1.mp4'
subtl_file = '1_1_1.srt'

(
    ffmpeg
    .input(input_dir + video_file)
    .filter('subtitles', input_dir + subtl_file)
    .output(input_dir + 'output.mp4')
    .run()
)

I'm sure all the files are in the right place: video in "C:\Users\27433\Desktop\1\1_1_1.mp4", subtitle in "C:\Users\27433\Desktop\1\1_1_1.srt" And the srt file's encoding is UTF-8, But the ffmpeg reported error:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:/Users/27433/Desktop/1/1_1_1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.71.100
    description     : Packed by Bilibili XCoder v2.0.2
  Duration: 00:00:27.73, start: 0.000000, bitrate: 231 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 45 kb/s, 30 fps, 30 tbr, 16k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 176 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
[Parsed_subtitles_0 @ 0000025a67d4d200] libass API version: 0x1502002
[Parsed_subtitles_0 @ 0000025a67d4d200] libass source: commit: 0.15.2-69-gf664ced049394e2a5d4300ba526e206df73ec729
[Parsed_subtitles_0 @ 0000025a67d4d200] Shaper: FriBidi 1.0.11 (SIMPLE) HarfBuzz-ng 4.2.0 (COMPLEX)
[Parsed_subtitles_0 @ 0000025a67d4d200] Unable to open C\:/Users/27433/Desktop/1/1_1_1.srt
[AVFilterGraph @ 0000025a67d6f280] Error initializing filter 'subtitles' with args 'C\\\:/Users/27433/Desktop/1/1_1_1.srt'
Error initializing complex filters.
Invalid argument
Traceback (most recent call last):
  File "C:\Users\27433\Desktop\Ermu1.5\test.py", line 11, in <module>
    .run()
  File "C:\Users\27433\Desktop\Ermu1.5\venv\lib\site-packages\ffmpeg\_run.py", line 325, in run
    raise Error('ffmpeg', out, err)
ffmpeg._run.Error: ffmpeg error (see stderr output for detail)

Then I tried to replace the ""to "\"or"/",but the error are still there, And I also tried to use ``` file_path=r"C:\Users\27433\Desktop\1\1_1_1.mp4" subtitle_path=r"C:\Users\27433\Desktop\1\1_1_1.srt" output_path=r"C:\Users\27433\Desktop\1\output.mp4" os.system("ffmpeg.EXE -i {} -vf subtitles={} {}".format(file_path, subtitle_path, output_path))

(The ffmpeg.exe are in the same folder as the .py file)
But it also raise error:

[subtitles @ 0000027c04691ac0] Unable to parse option value "Users27433Desktop11_1_1.srt" as image size Last message repeated 1 times [subtitles @ 0000027c04691ac0] Error setting option original_size to value Users27433Desktop11_1_1.srt. [Parsed_subtitles_0 @ 0000027c04600600] Error applying options to the filter. [AVFilterGraph @ 0000027c091ac300] Error initializing filter 'subtitles' with args 'C:Users27433Desktop11_1_1.srt' Error reinitializing filters! Failed to inject frame into filter network: Invalid argument Error while processing the decoded data for stream #0:0 [aac @ 0000027c041d0bc0] Qavg: 11856.707 [aac @ 0000027c041d0bc0] 2 frames left in the queue on closing Conversion failed!

or replace the "\" to"\\"or"/"

[subtitles @ 0000018074536a80] Unable to parse option value "Users27433Desktop11_1_1.srt" as image size Last message repeated 1 times [subtitles @ 0000018074536a80] Error setting option original_size to value Users27433Desktop11_1_1.srt. [Parsed_subtitles_0 @ 0000018071885ec0] Error applying options to the filter. [AVFilterGraph @ 0000018076c88900] Error initializing filter 'subtitles' with args 'C:\Users\27433\Desktop\1\1_1_1.srt' Error reinitializing filters!

[subtitles @ 000002d7e9858ac0] Unable to parse option value "/Users/27433/Desktop/1/1_1_1.srt" as image size Last message repeated 1 times [subtitles @ 000002d7e9858ac0] Error setting option original_size to value /Users/27433/Desktop/1/1_1_1.srt. [Parsed_subtitles_0 @ 000002d7e9c96bc0] Error applying options to the filter. [AVFilterGraph @ 000002d7ef088a00] Error initializing filter 'subtitles' with args 'C:/Users/27433/Desktop/1/1_1_1.srt'

Why could all these happen?how should I fix it?
I'll be very grateful if anybody could help me.

X-SZM avatar Feb 17 '23 05:02 X-SZM

It's because of filtergraph escaping. You can find more on the docs. Spent about an hour banging my head against a wall until I finally got it. This code is what got it for me:

path_converter = lambda path: path.replace("\\", "/").replace(":", "\:/").replace(" ", "\\ ").replace("(", "\\(").replace(")", "\\)").replace("[", "\\[").replace("]", "\\]").replace("'", "'\\''")
    ```
    so instead of subtitles="subtitles.mkv" or whatever do subtitles=path_converter(path_to_subtitles)

ef1500 avatar Mar 20 '23 02:03 ef1500

@ef1500 I'm curious how you are using this together with the rest of your code. I'm trying to use your solution but not having any luck with mine.

My filename: [SubsPlease] 16bit Sensation - Another Layer - 01 (720p) [FDA8E9E6].mkv Using regular ffmpeg CLI, I need to escape only the brackets like so:

-vf subtitles="\[SubsPlease\] 16bit Sensation - Another Layer - 01 (720p) \[FDA8E9E6\].mkv"

However, I still see an error in ffmpeg-python trying your solution.

It seems to be related to loading the file from a different directory than CWD when using the full file path with drive included. I tested by changing the file to just file.mkv which caused the same issue in loading the filter.

Test 1 Code:

out_file = 'out.webm'
start_time = '00:01:18.400'
end_time = '00:01:29.750'
in_dir = 'I:/'
in_file = os.path.join(in_dir,'file.mkv')
in_put = ffmpeg.input(in_file,ss=start_time,to=end_time)
audio = in_put.audio
video = in_put.video.filter('subtitles',in_file,si=0)
out = ffmpeg.output(audio,video,filename=out_file,acodec='libopus',vcodec='vp9').overwrite_output()
ffmpeg.run(out)

Test 1 Error:

[Parsed_subtitles_0 @ 00000186a3a856c0] Unable to open I\:/file.mkv
[AVFilterGraph @ 00000186a26a7f80] Error initializing filters
Error initializing complex filters.
Invalid argument

Test 2 Code:

path_converter = lambda path: path.replace("\\", "/").replace(":", "\:/").replace(" ", "\\ ").replace("(", "\\(").replace(")", "\\)").replace("[", "\\[").replace("]", "\\]").replace("'", "'\\''")
out_file = 'out.webm'
start_time = '00:01:18.400'
end_time = '00:01:29.750'
in_dir = 'I:/'
in_file = os.path.join(in_dir,'file.mkv')
in_put = ffmpeg.input(in_file,ss=start_time,to=end_time)
audio = in_put.audio
video = in_put.video.filter('subtitles',path_converter(in_file),si=0)
out = ffmpeg.output(audio,video,filename=out_file,acodec='libopus',vcodec='vp9').overwrite_output()
ffmpeg.run(out)

Test 2 Error:

[Parsed_subtitles_0 @ 0000025b34ed4bc0] Unable to open I\\\://file.mkv
[AVFilterGraph @ 0000025b33af7e00] Error initializing filters
Error initializing complex filters.
Invalid argument

Test 3 Code: (file moved to CWD of python script)

out_file = 'out.webm'
start_time = '00:01:18.400'
end_time = '00:01:29.750'
in_file = 'file.mkv'
in_put = ffmpeg.input(in_file,ss=start_time,to=end_time)
audio = in_put.audio
video = in_put.video.filter('subtitles',in_file,si=0)
out = ffmpeg.output(audio,video,filename=out_file,acodec='libopus',vcodec='vp9').overwrite_output()
ffmpeg.run(out)

Test 3 Successful

For good measure, I also tested with my original filename in CWD. Test 4 Code:

out_file = 'out.webm'
start_time = '00:01:18.400'
end_time = '00:01:29.750'
in_file = '[SubsPlease] 16bit Sensation - Another Layer - 01 (720p) [FDA8E9E6].mkv'
in_put = ffmpeg.input(in_file,ss=start_time,to=end_time)
audio = in_put.audio
video = in_put.video.filter('subtitles',in_file,si=0)
out = ffmpeg.output(audio,video,filename=out_file,acodec='libopus',vcodec='vp9').overwrite_output()
ffmpeg.run(out)

Test 4 Successful

ClawhammerLobotomy avatar Oct 15 '23 04:10 ClawhammerLobotomy

I was using it for a project which would allow me to clip videos for personal use. Sadly, due to my current circumstances, I am not in a position where I am near my project's code and won't be for a few months.

If my memory serves correctly, I think used the path converter to escape a full path from user input via radio webui. I was trying to hardcode the subtitles to my output clip and was unable to do it. I stumbled upon this issue, and after some additional searching, I found some related info on the docs (see here as well)

If you read the docs, it says: "A first level escaping affects the content of each filter option value, which may contain the special character : used to separate values, or one of the escaping characters \'.

A second level escaping affects the whole filter description, which may contain the escaping characters \' or the special characters [],; used by the filtergraph description.

Finally, when you specify a filtergraph on a shell commandline, you need to perform a third level escaping for the shell special characters contained within it."

If I had my code, I'd share a snippet, but as I said earlier, I can't access it for the time being. For now, this is really the best I can do to help you.

ef1500 avatar Oct 15 '23 18:10 ef1500

I appreciate the reply. Unfortunate that I can't see your example, but I'm still trying to get this working.

For now, I think I'm resorting to using a symbolic link created on the fly so I don't need to work with drives in the path.

@X-SZM I am wondering if your issue is also due to the full drive path in your subtitles filter? Have you tested with running the python script from the same folder as your inputs and using relative paths?

EX with removed input directory:

import ffmpeg

video_file = '1_1_1.mp4'
subtl_file = '1_1_1.srt'

(
    ffmpeg
    .input(video_file)
    .filter('subtitles',  subtl_file)
    .output('output.mp4')
    .run()
)

This is what I'm going to be using until I can figure this out: (Or maybe this will just end up being my solution)

import os
import ffmpeg

out_file = 'out.webm'
start_time = '00:01:18.400'
end_time = '00:01:29.750'

in_dir = 'I:/'
in_file = os.path.join(in_dir,'file.mkv')
in_link = 'file.mkv'

if not os.path.isfile(in_link):
    os.symlink(in_file, in_link)

input_vid = ffmpeg.input(in_link)
vid = (
    input_vid
    .filter_('subtitles',in_link)
    .trim(start=start_time,end=end_time)
    .setpts('PTS-STARTPTS')
)
aud = (
    input_vid
    .filter_('atrim',start=start_time,end=end_time)
    .filter_('asetpts', 'PTS-STARTPTS')
)
joined = ffmpeg.concat(vid, aud, v=1, a=1).node
output = ffmpeg.output(joined['v'], joined['a'], filename=out_file,acodec='libopus',vcodec='vp9').overwrite_output()
output.run()

if os.path.isfile(in_link):
    os.remove(in_link)

ClawhammerLobotomy avatar Oct 15 '23 21:10 ClawhammerLobotomy

The escaping for subtitle filters seems overzealous with the drive path. Unsure if it affects other filters, but I had no ill effects from my testing with my other FilterNodes.

The output of the FilterNode class for .filter('subtitles','I:/file.mkv') results in subtitles=I\\\\\\:/file.mkv being passed to ffmpeg.

However, this is causing one extra backslash to be passed to the program as seen in my errors. [Parsed_subtitles_1 @ 000001f0025056c0] Unable to open I\:/file.mkv

I removed the last escape_chars call from this class and everything worked as expected. subtitles=I\\\:/file.mkv is being passed to ffmpeg with no errors.

No amount of manual pre-escaping was able to get me a successful result with the existing code.

Would be nice to be able to omit escaping like #358 suggests. I think I will stick with my workaround of using symlink creation. Hope this info is helpful to someone that may have this same issues.

ClawhammerLobotomy avatar Oct 16 '23 02:10 ClawhammerLobotomy

I was using it for a project which would allow me to clip videos for personal use. Sadly, due to my current circumstances, I am not in a position where I am near my project's code and won't be for a few months.

@ef1500 hi , I also had similar problem , can you share some full working code , thanks . I tried use the funtion path_converter you methoned , but still not work.

iorilu avatar Jan 25 '24 07:01 iorilu