2

I'm looking for a way to automate file conversions. I'm using an Ubuntu virtual machine through which I'm accessing a Windows installation. The normal syntax should be:

ffmpeg -i file.mp4 file.mp3

So this is what I'm trying to do:

ls | while read i; do echo ffmpeg -i \"$i\" \"${i/mp4/mp3}\"; done

As you can see I added "echo" to see the generated command first and this is what I get:

ffmpeg -i "Accepting Amendments.mp4" "Accepting Amendments.mp3"

As you can see, the file names may have spaces, so I'm trying to escape them. However this command doesn't work when I remove the "echo". What happens is only some conversions are made and I'm getting error messages with split file names such as "ccepting Amendments.mp4" for instance. So basically the first ffmpeg command runs fine, then the second one fails, and so on.

I've noticed that when I run an ls command, I'm getting filenames with single quotes, but when I create a file myself, there are no quotes.

$ls
'Accepting Amendments.mp4'
$touch test
$ls
'Accepting Amendments.mp4'
test

Could that be the issue?

1 Answer 1

3

No, the problem is that (by using \") you're telling ffmpeg to transform a file "Accepting Amendments.mp4", with quotation marks contained in the name. That file doesn't exist, so ffmpeg fails. What you really want to do is use unescaped quotation marks that the shell interprets as "don't split the contained value": ffmpeg -i "$i" "${i/mp4/mp3}"

Besides, instead of piping ls's output you can/should have the shell loop on its own:

for i in *.mp4; do ffmpeg -i "$i" "${i/mp4/mp3}"; done

With ffmpeg this still doesn't work properly, though, because it reads from stdin for some reason and seems to swallow some characters in the file names that way. The -nostdin flag helps:

for i in *.mp4; do ffmpeg -nostdin -i "$i" "${i/mp4/mp3}"; done

(The single quote you see in your ls output is added by your version of ls for file names that contain e.g. spaces, so that you can simply take that output on the command line as the argument for another program. That has nothing to do with who created the file, you just didn't trigger the behavior with your file named test.)

4
  • 1
    This syntax is what I first tried but it didn't work. I'm still getting one command to work out of two. So the first file is converted and then for the second one, I get this: "Parse error, at least 3 arguments were expected, only 1 given in string 'complishing Surrenders.pptx.mp4'" The name of the second file starts with "Accomplishing" so the first character is removed. Feb 16, 2021 at 16:31
  • 2
    This seems to be a problem of ffmpeg reading from stdin for some reason, see bash FAQ 89. Does adding -nostdin or </dev/null to the ffmpeg call help?
    – DonHolgo
    Feb 16, 2021 at 17:34
  • 1
    Awesome, the "-nostdin" did the trick :) You should update your reply. Feb 16, 2021 at 19:13
  • 1
    Done – glad I could help!
    – DonHolgo
    Feb 16, 2021 at 20:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .