Reputation: 43
I want to use ffmpeg to convert .m4a files in to .mp3 files.
I can do it for each single file, but that takes a lot of effort to type in.
ffmpeg -i '.\song.m4a' -ac 2 -b:a 192k '.\song.mp3'
Is there a way to do this with powershell using variables? ex:
ffmpeg -i $v -ac 2 -b:a 192k $v.mp3
The problem with this is that then the -ac
flag is taken as part of the path and not of ffmpeg anymore.
Is there a way around this in powershell?
Or could this be done with an array? If I use $v=Get-ChildItem -Name
and iterate over the array with a foreach loop in to the ffmpeg command.
I am very new to PowerShell and don't have a lot of experience but it seems to me that should be possible to do.
I would appreciate any help I can get.
Upvotes: 1
Views: 192
Reputation: 8868
If you do just Get-Childitem -Name
you would end up with song.m4a.mp3
unless you took care of that with a replace statement, etc. If you keep it as an object then you could reference the name and later the basename.
get-childitem -Filter *.m4a |
foreach {ffmpeg -i “$($_.name)“ -ac 2 -b:a 192k “$($_.basename).mp3”}
I have not tested this so you may need to adjust the quotes.
Upvotes: 2
Reputation: 438208
Note:
Your real problem is not with -ac
, but with argument $v.mp3
While the immediate fix would be "$v.mp3"
- i.e. to simply double-quote your argument - that would result in doubled file extensions (.mp4.mp3
), for which Doug Maurer's answer offers a fix.
The following focuses generally on how PowerShell interprets a command-line argument such as $v.mp3
.
In order for $v.mp3
to be interpreted as the value of variable $v
as a whole followed by verbatim text .mp3
, you must double-quote the argument ("$v.mp3"
), as shown in js2010's answer.
Unquoted arguments are often, but not always, implicitly treated like expandable strings, but a single variable reference such as $v
or even a subexpression such as $($v.BaseName)
or ($v.BaseName)
followed by something that looks like a property access or even method call - such as $v.mp3
here - is a notable exception and is interpreted as just that:
Therefore, PowerShell interprets the .mp3
part as a property access: that is, it tries to return the value of a property named mp3
of the object stored in variable $v
; if $v
contains a string, there will be no such property, which means that the expression evaluates to $null
and no argument at all is passed to the external program (ffmpeg
).
The rules for how PowerShell treats variable references and subexpressions in unquoted command-line arguments are complex:
Upvotes: 1
Reputation: 27473
$v.mp3 doesn't seem to work. Make a variable set to 'song.mp3' instead. Or use double quotes "$v.mp3".
echoargs $v.mp3 # no output
echoargs "$v.mp3"
Arg 0 is <song.mp3>
Upvotes: 1