Skip to content

Conversation

@alexdelorenzo
Copy link

@alexdelorenzo alexdelorenzo commented Nov 17, 2022

Problem

ffmpeg-python's .compile() method to generate FFmpeg commands doesn't quote or escape filenames with spaces, so it will generate commands like so:

>>> ' '.join(output.compile())
ffmpeg -fflags +genpts -i /tmp/video with spaces in name.mkv \
 -acodec copy -movflags faststart -scodec copy -threads 12 -vcodec libx264 -vlevel 4.1 \
 /tmp/video with spaces in name [out].mkv -y

(Note that I edited escaped new lines into this example's output for readability, they don't exist in .compile()'s output before or after merging this pull request.)

Running that compiled command fails:

/tmp/video: No such file or directory

Solution

This pull request quotes filenames using shlex.quote() by wrapping filenames parsed by .compile()'s helper functions.

As a result, the following command can run correctly because filenames with spaces were quoted:

>>> ' '.join(output.compile())
ffmpeg -fflags +genpts -i '/tmp/video with spaces in name.mkv' \
  -acodec copy -movflags faststart -scodec copy -threads 12 -vcodec libx264 -vlevel 4.1 \
  '/tmp/video with spaces in name [out].mkv' -y

(Again, escaped new lines were just added to this example for readability, this pull request does not add them to output.)

@alexdelorenzo alexdelorenzo changed the title Quote filenames to handle paths with spaces in command created with .compile() Quote filenames to handle paths with spaces in commands created with .compile() Nov 17, 2022
@charlesgwaldman
Copy link

Having dealt with similar issues, I can tell you that the shlex.quote approach will fail on the Windows platform. shlex.quote will use single quotes, which are not effective in the Windows "shell", you need double-quotes there. As the Python docs spell out "Warning: The shlex module is only designed for Unix shells." https://docs.python.org/3/library/shlex.html#shlex.quote

@gsauthof
Copy link

gsauthof commented Oct 4, 2025

Since ffmpeg-python's compile() returns a list and nobody forces you to ' '.join that list, why don't you simply supply the whole list to subprocess.run(), which expects the command as a list, by default, anyways?

If you can't use a sane API that supports command lists - such as subprocess - then this is out of scope for ffmpeg-python, I would argue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants