0

I'm developing a program in Python that requires the use of FFMPEG. In one step, I need to create a video from a text file containing the list of images (path and duration) that need to be assembled to make a video. To do this, I use the following code:

cmd = [ffmpeg, "-y", "-f", "concat", "-safe", "0", "-i", tmp, "-c:v", "libx264", "-r", "25", "-pix_fmt", "yuv420p", out]
subprocess.run(cmd)
# os.system(" ".join(cmd)) # returns same error

What returns the error: The syntax of the file, directory or volume name is incorrect.

I know that paths can be problematic when they contain spaces, and as my username has one, I've taken care to quote the paths in such a way that :

ffmpeg = '"C:\Users\John Doe\Documents\ffmpeg\bin\ffmpeg.exe"'
tmp = '"C:\Users\John Doe\Desktop\path\to\file.txt"'
out = '"C:\Users\John Doe\Desktop\path\to\video.mp4"'

When I print(" ".join(cmd)), this is what I get in my terminal:

"C:\Users\John Doe\Documentsffmpeg\binffmpeg.exe" -y -f concat -safe 0 -i "C:\Users\John Doe\Desktop\path\to\file.txt" -c:v libx264 -r 25 -pix_fmt yuv420p "C:\Users\John Doe\Desktop\path\to\video.mp4"

However, the problem persists. Has anyone ever had this problem and managed to solve it?

I've also tried the method where you have to escape the spaces (taking care to replace the \ with / and then the with \ ) but nothing works... The error persists.

For your information, here are the contents of one of my .txt files

file C:\Users\John Doe\Desktop\path\to\image_1.png
duration 0.04
file C:\Users\John Doe\Desktop\path\to\image_2.png
duration 0.04
file C:\Users\John Doe\Desktop\path\toimage_3.png
duration 0.04

When I quote the paths in the .txt files

  • subprocess gives me the error: PermissionError: [WinError 5] Access denied
  • os.system gives me the error:
C:\Users\John' is not recognized as an internal or external command, an executable program or a command file.
The syntax of the file, directory or volume name is incorrect.
  • check out https://stackoverflow.com/questions/22766111/ffmpeg-not-working-with-filenames-that-have-whitespace, from a glance it looks like you might be able to use something like %20 instead of spaces – TheDeafOne Jul 21 '23 at 14:34
  • I've also tried with %20 but FFMPEG gives me the error No such file or directory when trying to access images from the txt file. – tomatochan Jul 21 '23 at 15:26
  • Please provide a *complete* example. I suspect that you have too many quotes, not too few, but without seeing actual running code, there is too much guesswork involved. – Ture Pålsson Jul 22 '23 at 12:34

3 Answers3

0

Try to use raw strings ?

ffmpeg = r"C:\Users\John Doe\Documents\ffmpeg\bin\ffmpeg.exe"
tmp = r"C:\Users\John Doe\Desktop\path\to\file.txt"
out = r"C:\Users\John Doe\Desktop\path\to\video.mp4"
matleg
  • 618
  • 4
  • 11
0

In your command, you need to have quotation marks around the path, but when you use the join function:

os.system(" ".join(cmd))

the resulting command won't contain any quotations marks because the quotation marks were not part of the string.

Compare the following lines:

print(" ".join(["one", "two", "three"]))
print(" ".join(["one", '"two"', "three"]))

The output from the second line will contain the quotation marks.

Another method, which I prefer, is using f-strings to form the commands, such as:

ffmpeg = "C:\\Users\\John Doe\\Documents\\ffmpeg\\bin\\ffmpeg.exe"
image_list = "C:\\Users\\John Doe\\Desktop\\path\\to\\file.txt"
output = "C:\\Users\\John Doe\\Desktop\\path\\to\\video.mp4"
print(f""""{ffmpeg}" -y -f concat -safe 0 -i "{image_list}" -c:v libx264 -r 25 -pix_fmt yuv420p "{output}" """)

Also make sure you use double backslah in your windows path strings, such as in:

ffmpeg = "C:\\Users\\John Doe\\Documents\\ffmpeg\\bin\\ffmpeg.exe"
KarelHusa
  • 1,995
  • 18
  • 26
  • I was careful to quote the paths. I admit that the formatting suggests that this isn't the case, but if you look at the output of the print(" ".join(cmd)) that I copied/pasted from my terminal, you can see that the paths contain quotation marks. – tomatochan Jul 21 '23 at 15:43
  • You have provided only snippets of your code, but according to them there are no quotation marks inside the command string. It's not clear how does the "what I get in my terminal" string relates to the code. Anyway, I recommend transforming your command into f-string and add the quotation marks as per given example. – KarelHusa Jul 21 '23 at 16:25
  • Please note two issues need to be treated. Firstly the quotation marks for the paths with spaces, secondly the double backslash for windows paths. Using Windows paths is very error prone, in Linux it's much easier. – KarelHusa Jul 21 '23 at 16:31
0

Another try, using pathlib maybe? And casting to string in the command definition:

from pathlib import Path
ffmpeg = Path("C:\Users\John Doe\Documents\ffmpeg\bin\ffmpeg.exe").resolve()
cmd = [str(ffmpeg), "-y", "-f", ...
matleg
  • 618
  • 4
  • 11