Escape special characters in FFmpeg subtitle filename

3k Views Asked by At

If your subtitle file name is "Hi, y'all.srt", how do you escape this properly for FFmpeg? The comma works escaped with backslash, but I can't get the quote to work no matter what tricks I try!

$ ffmpeg -vf subtitles="Hi\, y\\\'all.srt" -t 1 -f null -

ffmpeg version 3.3.3 Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 8.1.0 (clang-802.0.42)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-libass --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma --enable-vda
  libavutil      55. 58.100 / 55. 58.100
  libavcodec     57. 89.100 / 57. 89.100
  libavformat    57. 71.100 / 57. 71.100
  libavdevice    57.  6.100 / 57.  6.100
  libavfilter     6. 82.100 /  6. 82.100
  libavresample   3.  5.  0 /  3.  5.  0
  libswscale      4.  6.100 /  4.  6.100
  libswresample   2.  7.100 /  2.  7.100
  libpostproc    54.  5.100 / 54.  5.100
[Parsed_subtitles_0 @ 0x7fba7af36080] Shaper: FriBidi 0.19.7 (SIMPLE) HarfBuzz-ng 1.4.8 (COMPLEX)
[Parsed_subtitles_0 @ 0x7fba7af36080] Unable to open Hi, yall.srt
[AVFilterGraph @ 0x7fba7ad05d60] Error initializing filter 'subtitles' with args 'Hi, y\all.srt'
Error reinitializing filters!
Failed to inject frame into filter network: No such file or directory
Error while processing the decoded data for stream #0:0
Conversion failed!
4

There are 4 best solutions below

7
Gyan On

On Windows 7, this works:

subtitles="Hi\, y\\\'all.srt"
0
Reggie The Veggie On

I know this is an old question but I wanted to post an answer here because I came across a similar issue and figured out a way around it. This was tested in Windows 8.1.

The workaround is to create a symlink to your file first with a name that ffmpeg likes, and use that instead.

eg.

mklink input.mkv "my file with [strange] characters.mkv"

Then you can use it with ffmpeg like so:

ffmpeg -i input.mkv -vf subtitles=input.mkv -y output.mp4

This works for .srt files as well.


There seems to be a bug with ffmpeg where if you're using a file in the subtitles filter that has special characters in it, ffmpeg won't find the file. I had a collection of files I wanted to burn subtitles in but they all had special characters (square brackets) in the filename. I could rename all of my files, and remove the special characters, but that seemed like a pain to do and I'd rather find a way that doesn't care about how the source file is named. The best workaround I could find is to just create a symlink to the file itself and have ffmpeg call on the symlink. If I'm iterating over many files, all I would need to do is change the symlink to the next file.

0
Wen Frazier On

Assuming you have a file named subtitle's.srt in a D:\Videos folder you can escape it like this "subtitles='D\:\\Videos\\subtitle'\\\''s.srt'".

Example:

ffmpeg.exe -in file.mkv -c:a copy -c:v libx264 -crf 20 -pix_fmt yuv420p -map 0:v:0 -map 0:a:0 -vf "subtitles='D\:\\Videos\\subtitle'\\\''s.srt':si=0" file.mp4

This was tested on Windows 10.

0
bppcomplete On

Here's what I've got for Bash.

$ ls                                                                                                                                                               
'file [with] spaces : colons : , commas, %percents%, '\'' single and "double"'\'' quotes, and \ backslashes\.mp4'

with which the following invocation will work:

i=$(ls)
e=${i//\\/\\\\\\\\} # escape backslashes
e=${e//:/\\\\:}     # escape : (used to pass params to filter)
e=${e//,/\\,}       # escape , (used to separate filters)
e=${e//;/\\;}       # escape ; (used to separate filterchains)
e=${e//\'/\\\\\\\'} # escape ' (parsed by filter)
e=${e//\[/\\[}      # escape [ (used to name components of filtergraph)
e=${e//\]/\\]}      # escape ] (same as above)

ffmpeg -i "${i}" -vf "subtitles=${e}:si=8" "out.mp4"

The input filename was

file [with] spaces : colons : , commas, %percents%, ' single and "double"' quotes, and \ backslashes\.mp4

and the final escaped string looks like

file \[with\] spaces \\: colons \\: \, commas\, %percents%\, \\\' single and "double"\\\' quotes\, and \\\\ backslashes\\\\.mp4

This seems to be all of the (printable) special characters, as a file with name

!@#$%^&*()-_+=[]{}\|;:,.<>?`~'
.mp4

(with the literal newline) works for this invocation.

Note that if you want to escape for drawtext, you need to double the number of backslashes (e=${i//\\/\\\\\\\\\\\\\\\\}) and add an escape for %.