Help with automated powershell script
Posted: Mon Mar 28, 2016 6:27 am
I am working on a PS script to monitor a folder for large video files if detected it will auto convert the file.
I learned a bit of PS for the soul purpose of making this automating script so I am a big nub at PS
this is the code so far:
the script works like it should the problem is when HandBrakeCLI is called it outputs all info not just the progress of the encoding.
Anyone that can help me on what I am doing wrong here? It would be much appreciated .
I learned a bit of PS for the soul purpose of making this automating script so I am a big nub at PS
this is the code so far:
Code: Select all
$Folder = "E:\Series" #Folder to be monitored for large video files.
$global:Output = "E:\Encoded" #Folder where encoding jobs go to, and that will be monitored for completed jobs to replace the original file with.
$global:MaxMB = 15 #Max MB a minute
$global:Elapsed = 0 #Variabel to store elapesed time of the convertion process.
$global:CurrentEncode = "" #Loction to the current encoding job
$global:EstimateSize = "" #Estimeated file size
$global:LastSizeCheck = "" #Last time the file size whas checked
$global:Rep_Source = $true #whether or not to replace the source with the output.
$global:MI_CLI = "C:\Program Files\MediaInfoCLI\MediaInfo.exe" #Location of MediaInfoCLI
$global:HB_CLI = "C:\Program Files\Handbrake\HandBrakeCLI.exe" #Location of HandBrakeCLI
$global:HB_Container = "Copy" #HandBrake container output(Copy,mp4,mkv) copy only works when the source is mp4 or mkv
$global:HB_Audio = "Copy" #Audio format for the output file
$global:HB_aBitRate = 192 #Audio Bitrate
$global:HB_Width = "Copy" #The Width for the video to be converted.
$global:HB_ConstQ = 20 #Constant Quality value
$global:HB_Codec = "x265" #Codec used to convert file(Copy,x264,x265) copy only works when the source is x264 or x265
$global:Kodi_URI = "http://127.0.0.1:8080/jsonrpc" #URL of kodi webserver if password protected then add to url ex. "http://USERNAME:PASSWORD@127.0.0.1:8080/jsonrpc"
$global:Kodi_Notify = $true #Wheter or not script should send a notification on new and completed converions to kodi
$global:kodi_IMG = "https://handbrake.fr/img/logo.png" #Image displayed in the notification
$Filter = '*.*'
$fsw = New-Object IO.FileSystemWatcher $Folder, $Filter
$fsw.IncludeSubdirectories = $true
$fswOnChange = Register-ObjectEvent $fsw Changed -SourceIdentifier FileUpdated -Action {
Start-Sleep -s 2
$FilePath = $EventArgs.FullPath
$DirPath = $FilePath.Split('\')
$DirPath = $DirPath[0..($DirPath.Length - 2)] -join "\"
$FileName = $FilePath.Split('\')[-1]
if($FilePath -imatch '\.(?:mp4|mkv)$'){
$Converted = if(Test-Path -LiteralPath "$Output\Converted.log"){Get-Content "$Output\Converted.log"}
if((Test-Path -LiteralPath $filePath) -and -not ((Test-Path -LiteralPath "$Output\$FileName") -or $Converted -contains $FileName)){
if(Test-FileReady $FilePath){
$MediaInfo = Get-MediaInfo $FilePath
$Size = $MediaInfo.General.FileSize
$SizeString = $MediaInfo.General.FileSizeString4
$Duration = $MediaInfo.General.Duration
$TimeFormat = if($Duration -ge 36e5){"hh\h\mm\mss\s"}else{"mm\mss\s"}
$Resolution = $MediaInfo.Video.Width + "x" + $MediaInfo.Video.Height
$Source_MBm = [math]::Round(($Size / ($Duration / 6e4)) / 1MB, 2)
if($Source_MBm -gt $MaxMB){
$global:CurrentEncode = "$Output\$FileName"
Set-CrusorPosistionX 0
Write-Host "Large Video Detected: `"$($FileName)`""
Write-Host "`t$((Get-Date).DateTime)"
Write-Color "`tSource:::White $SizeString | $(Format-Time $Duration $TimeFormat) | $Source_MBm MiB/m | $Resolution::Gray"
Write-Host "`tSending To HandBrake..."
if($Kodi_Notify){Notify-Kodi -Title "New Convertion Started." -Message $FileName -IMG $kodi_IMG -URI $Kodi_URI}
HB-Convert $FilePath $Output
$Completed = (Get-Content $Output\$($FileName -replace `"\[|\]`", `"`").log) -match 'encoded.*?'
if($Completed){
$time = [int]((([regex]::matches($completed, "\d+(?:\.\d+)?s") | %{$_.value}) -replace "[s.]","")) * 10
$time = Format-Time $time $(if($time -eq 36e5){"hh\hmm\mss\s"}else{"mm\mss\s"})
$Completed = $Completed -replace "\d+(?:\.\d+)?s" , $time -replace "^e", "E"
$MediaInfo = Get-MediaInfo "$Output\$FileName"
$Size = $MediaInfo.General.FileSize
$SizeString = $MediaInfo.General.FileSizeString4
$Duration = $MediaInfo.General.Duration
$TimeFormat = if($Duration -ge 3600000){"hh\h\mm\mss\s"}else{"mm\mss\s"}
$Resolution = $MediaInfo.Video.Width + "x" + $MediaInfo.Video.Height
$MBm = [math]::Round(($MediaInfo.General.FileSize / ($MediaInfo.General.Duration / 6e4)) / 1MB,2)
$FileName >> "$Output\Converted.log"
$global:CurrentEncode = ""
$global:EstimateSize = ""
$global:LastSizeCheck = ""
Set-CrusorPosistionX 0
Write-Host "`t$Completed$(`" `" * 30)"
Write-Color "`tOutput:::White $SizeString | $(Format-Time $Duration $TimeFormat) | $MBm MiB/m | $Resolution::Gray"
Write-Host "`tReplacing source with output..."
if($Rep_Source){Move-Item "$Output\$FileName" $DirPath -force}
Write-Host "`tConversion Completed!`n" -ForegroundColor White
if($Kodi_Notify) {Notify-Kodi -Title "Convertion Completed." -Message $FileName -IMG $kodi_IMG -URI $Kodi_URI}
}else{
$global:CurrentEncode = ""
$global:EstimateSize = ""
$global:LastSizeCheck = ""
Write-Host "`n`tFailed to convert file!!! Check log for more details.`n" -ForegroundColor DarkRed
if($Kodi_Notify){Notify-Kodi -Title "Convertion Failed." -Message $FileName -IMG $kodi_IMG -URI $Kodi_URI}
}
}
}#else{Set-CrusorPosistionX 0;write-host "File IS LOCKED"}
}
}
}
function global:HB-Convert{
param ( [parameter(Mandatory=$true)][string]$source,
[parameter(Mandatory=$true)][string]$dest )
if(-not (Test-Path -LiteralPath $source) -or -not (Test-Path -LiteralPath $dest)) {return}
$FileName = $source.split('\')[-1]
$LogFile = "$dest\$($FileName -replace `"\[|\]`", `"`").log"
& $HB_CLI -i `"$source`" -o `"$dest\$FileName`" -f mkv -w 1280 --crop 0:0:0:0 --loose-anamorphic --modulus 2 -e $HB_Codec -q $HB_ConstQ --vfr -a 1 -E $HB_Audio -6 dpl2 -R Auto -B $HB_aBitRate -D 0 --gain 0 --audio-fallback ac3 --encoder-preset=faster --verbose=0 2> "$LogFile" | HB-UpdateProgress
}
function global:HB-UpdateProgress{
Process{
$Progress = @($input)[0]
$Percentage = ([regex]"(\d+(?:\.\d+)?)\s%").Matches($Progress) | select Groups
if($Percentage -and $CurrentEncode){
$Percentage = $Percentage.Groups[1].Value
$Round = [Math]::Floor($Percentage)
if(($Round %5 -eq 0) -and ($Round -ne 0) -and ($LastSizeCheck -ne $Round)){
if(Test-Path -LiteralPath $CurrentEncode){
$EFS = [math]::Round((((Get-Item $CurrentEncode).length / 1MB) / $Percentage) * 100, 2)
if($EFS -ge 1GB){
$EFS = [string]([math]::Round($EFS / 1GB, 2)) + " GiB"
}else{
$EFS = ", EFS $EFS MiB"
}
$global:EstimateSize = $EFS
$global:LastSizeCheck = $Round
}
}
}
$Progress = ($Progress -replace "00h|00m|task 1 of 1, ", "") -replace "\)", "$EstimateSize)"
$CharCount = $Progress.length
$WhiteSpace = " " * (80 - $CharCount)
Set-CrusorPosistionX 0
Write-Host "`t$Progress$WhiteSpace" -NoNewline -ForegroundColor White
}
}
function global:Set-CrusorPosistionX{
Param([parameter(Mandatory=$true)][int]$X)
$position = $host.ui.rawui.cursorposition
$position.X = $X
$host.ui.rawui.cursorposition = $position
}
function global:Set-CrusorPosistionY{
Param([parameter(Mandatory=$true)][int]$Y)
$position = $host.ui.rawui.cursorposition
$position.Y = $Y
$host.ui.rawui.cursorposition = $position
}
function global:Test-FileReady {
Param([parameter(Mandatory=$true)]$path)
if (Test-Path -LiteralPath $path) {
trap {
return $false
}
$stream = New-Object system.IO.StreamReader $path
if ($stream) {
$stream.Close()
return $true
}
}
}
function global:Notify-Kodi{
param( [parameter(Mandatory=$true)][string]$Title,
[parameter(Mandatory=$true)][string]$Message,
[parameter(Mandatory=$true)][string]$IMG,
[parameter(Mandatory=$true)][string]$URI )
$body = "[{`"jsonrpc`": `"2.0`", `"params`": {`"image`": `"$IMG`", `"title`": `"$Title`" , `"message`": `"$Message`"}, `"method`": `"GUI.ShowNotification`", `"id`": `"HandBrake`"}]"
Invoke-RestMethod -Method Post -Uri $URI -Body $body -Header @{"Content-Type"="application/json"}
}
Function global:Format-Time {
param ( [parameter(Mandatory=$true)][int]$MilliSeconds,
[Parameter(Mandatory=$false)][string]$Format ='hh\:mm\:ss' )
Return [timespan]::FromMilliseconds($MilliSeconds).ToString($Format)
}
function global:Get-MediaInfo{
param ([parameter(Mandatory=$true)][string]$source)
if(-not (Test-Path -LiteralPath $source)){return ""}
$rawInfo = & $MI_CLI `"$source`" --Language=raw --Full
if(-not $rawInfo){return ""}
$rawInfo = $rawInfo -split '[\r\n]'
$MediaInfo = @{}
$type = ""
for ($i=0; $i -lt $rawInfo.length; $i++) {
$info = $rawInfo[$i] -split ':'
if($info.length -eq 1){
$type = $info[0].trim()
if(-not $type){continue}
$MediaInfo[$type] = @{}
continue
}
$words = $info[0].trim() -split "[\s(/)]"
if($words.length -gt 1){
$info[0] = ''
foreach($word in $words){
if($word -and $word.length -gt 1){
$info[0] += $word.substring(0,1).toupper() + $word.substring(1).tolower()
}elseif($word -and $word.length -eq 1){
$info[0] += $word
}
}
}
$MediaInfo[$type][$info[0].trim()] = $info[1].trim()
}
return $MediaInfo
}
function global:Write-Color{
param ([parameter(Mandatory=$true)][string]$Message)
$MessageArray = $Message -split("::\w+")
$ColorsArray = ([regex]"::\w+").Matches($Message) | select value
if($MessageArray.Length -gt 1){
for($i=0; $i -le $ColorsArray.Length - 1; $i++){
write-host $MessageArray[$i] -ForegroundColor ($ColorsArray[$i].value -replace "::","") -NoNewline
}
Write-Host
}
}
Write-Host "When HandBrake is converting hit 'p' to pauze and 'r' to resume."
Write-Host "Monitoring folder `"$Folder`" for large video files...`n"
Anyone that can help me on what I am doing wrong here? It would be much appreciated .