Matt McManis
Matt McManis

Reputation: 4675

Start-Process with Process Priority in Loop doesn't recognize variable

I'm using FFmpeg with PowerShell.

I have a loop that goes through a folder of mpg files and grabs the names to a variable $inputName.

FFmpeg then converts each one to an mp4.


Works

Batch Processing

$files = Get-ChildItem "C:\Path\" -Filter *.mpg; 

foreach ($f in $files) {

    $inputName = $f.Name; #name + extension
    $outputName = (Get-Item $inputName).Basename; #name only

    ffmpeg -y -i "C:\Users\Matt\Videos\$inputName" -c:v libx264 -crf 25 "C:\Users\Matt\Videos\$outputName.mp4"
}

Not Working

Batch Processing with Process Priority

$files = Get-ChildItem "C:\Path\" -Filter *.mpg; 

foreach ($f in $files) {

    $inputName = $f.Name; #name + extension
    $outputName = (Get-Item $inputName).Basename; #name only

    ($Process = Start-Process ffmpeg -NoNewWindow -ArgumentList '-y -i "C:\Users\Matt\Videos\$inputName" -c:v libx264 -crf 25 "C:\Users\Matt\Videos\$outputName.mp4"' -PassThru).PriorityClass = [System.Diagnostics.ProcessPriorityClass]::AboveNormal;
    Wait-Process -Id $Process.id 

}

If I set the Process Priority using Start-Process PriorityClass, the $inputName variable is no longer recognized.

Error:
C:\Users\Matt\Videos\$inputName: No such file or directory

Upvotes: 0

Views: 187

Answers (1)

ArcSet
ArcSet

Reputation: 6860

Lets go over a few basic things.

In powershell we love piping |, It allows use to pass the information from one command to another command.

A good example of this is the ForEach you have.

Instead of Foreach($F in $Files) you can pipe | into a foreach-object

Get-ChildItem "C:\Path\" -Filter *.mpg | Foreach-Object{
    $_
}

When Piping | a command powershell automatically creates the variable $_ which is the object that is passed in the pipe |

The next thing is there are 2 types of quotes " and '.

If you use ' then everthing is taken literally. Example

$FirstName = "TestName"
'Hey There $FirstName'

Will return

Hey There $FirstName

While " allows you to use Variables in it. Example

$FirstName = "TestName"
'Hey There $FirstName'

Will return

Hey There TestName

Now one last thing before we fix this. In powershell we have a escape char ` aka a tick. Its located beside the number 1 on the keyboard with the tilde. You use it to allow the use of char that would otherwise break out of the qoutes. Example

"`"Hey There`""

Would return

"Hey There"

OK so now that we covered the basics lets fix up the script

Get-ChildItem "C:\Users\Matt\Videos\" -Filter *.mpg -File | Foreach-Object{
    ($Process = Start-Process ffmpeg -NoNewWindow -ArgumentList "-y -i `"$($_.FullName)`" -c:v libx264 -crf 25 `"C:\Users\Matt\Videos\$($_.Name)`"" -PassThru).PriorityClass = [System.Diagnostics.ProcessPriorityClass]::AboveNormal;
    Try{
        Wait-Process -Id $Process.id
    }catch{
    }
}

In the case above I changed

Add -File to the Get-ChildItem to designate that you only want Files returned not folders

Pipe | into a Foreach-Object

Changed the Outside Brackets in the -ArgumentList to be double quotes " instead of literal quotes '

Removed the $InputName and $OutputName in favor of the Foreach-Object variable $_

Upvotes: 1

Related Questions