View Single Post
Old 11th January 2010, 05:30   #1  |  Link
grv575
Registered User
 
Join Date: May 2003
Posts: 25
Batch encoding to h264

Powershell script to batch 2-pass encode files to h264/aac using the same bitrate as the source file.

Required tools -
x264: http://x264.nl/
bepipe: http://speeddemosarchive.com/w/images/e/e3/BePipe.zip
neroaacenc: http://speeddemosarchive.com/w/image...gitalAudio.zip
mp4box: http://www.videohelp.com/tools/mp4box
AviSynth: http://sourceforge.net/projects/avisynth2/files/
avsutil: http://members.optusnet.com.au/squid_80/avsutil.zip

# An AVS script is generated for every AVI that is found in the source folder
# The source video total bitrate is approximated based on the filesize and video runtime. This will give a good value to use as the bitrate for a 2-pass encode to ensure
# little loss of quality during transcoding.
#
# If you haven't used Powershell before, you can download it from Microsoft for free, then type in "Set-ExecutionPolicy RemoteSigned" to allow execution of unsigned scripts.
# Save the code in a .ps1 file, navigate to that folder in Powershell (works just like in cmd.exe) and type in ".\encode.ps1".
# Or you can just open a cmd shell and type: "powershell .\encode.ps1"

# Description: Batch encoding from various file formats to x264/AAC in an MP4 container.
# Example Usage: .\encode.ps1
# Required tools: x264, bepipe, neroaacenc, mp4box, AviSynth, avsutil - be sure to adapt exe paths below

#Param (
#[string]$Path
#)

# Configure paths here.
# Videos to encode are in $Path
# Temporary files (AVS, video, audio) are saved in $TempPath which is cleared out after every file except on exceptions.
# Muxed video is saved to $OutPath
# $FileTypes lists all file types in $Path that will be encoded

$Path = 'C:\video\source\'
$TempPath = 'C:\video\temp\'
$OutPath = 'C:\video\encoded\'
$FileTypes = @("*.avi","*.mpg","*.mpeg","*.wmv","*.rmvb","*.mkv")

# Configure exe paths here.

$ExePath = @{}
$ExePath['x264'] = 'C:\video\bin\x264.exe'
$ExePath['bepipe'] = 'C:\video\bin\BePipe.exe'
$ExePath['neroaacenc'] = 'C:\video\bin\neroAacEnc.exe'
$ExePath['mp4box'] = 'C:\video\bin\MP4Box.exe'
$ExePath['avsutil'] = 'C:\video\bin\avsutil.exe'

# Configure AVS script and command line parameters here

$Config = @{}
$Config['AVS'] = 'DirectShowSource("$FilenameIn", convertfps=true)'
#$Config['x264'] = '--crf 22 --ref 5 --mixed-refs --bframes 3 --b-adapt 2 --b-pyramid --weightb --deblock -1:-1 --trellis 2 --partitions all --8x8dct --me umh ' +
#'--threads auto --thread-input --progress --no-psnr --no-ssim --output "$FilenameVideo" "$FilenameAVS"'
$Config['x264pass1'] = '--pass 1 --bitrate $BitrateKbps --stats "$FilenameStats" --output NUL "$FilenameAVS"'
$Config['x264pass2'] = '--pass 2 --bitrate $BitrateKbps --stats "$FilenameStats" --output "$FilenameVideo" "$FilenameAVS"'
$Config['neroaacenc'] = '-q 0.55 -if - -of "$FilenameAudio"'
$Config['AVSBitrate'] = 'DirectShowSource("$FilenameIn")' + "`r`n" +
'filename = "$FilenameDuration"' + "`r`n" +
'WriteFileStart(filename, "FrameCount/FrameRate")'

function Encode($FilenameIn) {
Trap {
write-error $_.Exception.Message
return
}

Write-Host "Encoding $FilenameIn"

$Basename = [system.io.path]::GetFilenameWithoutExtension($FilenameIn)
$FilenameAVS = $TempPath + $Basename + '.avs'
$FilenameAVSBitrate = $TempPath + $Basename + '_bitrate.avs'
$FilenameVideo = $TempPath + $Basename + '_video.mp4'
$FilenameAudio = $TempPath + $Basename + '_audio.mp4'
$FilenameStats = $TempPath + $Basename + '.stats'
$FilenameDuration = $TempPath + $Basename + '_duration.txt'
$FilenameOut = $OutPath + $Basename + '.mp4'

Write-Host '- Generating AVS scripts...'
$Config['AVS'].Replace('$FilenameIn', $FilenameIn) | Out-File $FilenameAVS -Encoding 'ASCII'
$Config['AVSBitrate'].Replace('$FilenameIn', $FilenameIn).Replace('$FilenameDuration', $FilenameDuration) | Out-File $FilenameAVSBitrate -Encoding 'ASCII'

Write-Host '- Getting bitrate...'
& $ExePath['avsutil'] "$FilenameAVSBitrate"

$FileLengthSeconds = Get-Content "$FilenameDuration"
$file = Get-Item "$FilenameIn"
$FileSize = $file.Length
$BitrateKbps = [int]($FileSize / $FileLengthSeconds * 8 / 1000)
Write-Host "$BitrateKbps kbps"

Write-Host '- Encoding video...'
Write-Host '- Pass 1...'
$Execute = $ExePath['x264'] + ' ' + $Config['x264Pass1'].Replace('$FilenameAVS', $FilenameAVS).Replace('$FilenameStats', $FilenameStats).Replace('$BitrateKbps', $BitrateKbps)
& cmd /c "$Execute"

Write-Host '- Pass 2...'
$Execute = $ExePath['x264'] + ' ' + $Config['x264Pass2'].Replace('$FilenameVideo', $FilenameVideo).Replace('$FilenameAVS', $FilenameAVS).Replace('$FilenameStats', $FilenameStats).Replace('$BitrateKbps', $BitrateKbps)
& cmd /c "$Execute"

'- Encoding audio...'
$Execute = $ExePath['bepipe'] + ' --script "Import(^' + $FilenameAVS + '^)"' + ' | ' + $ExePath['neroaacenc'] + ' ' + $Config['neroaacenc'].Replace('$FilenameAudio', $FilenameAudio)
& cmd /c "$Execute"

Write-Host '- Muxing...'
$Execute = $ExePath['mp4box'] + ' -new -add "' + $FilenameVideo + '" -add "' + $FilenameAudio + '" "' + $FilenameOut + '"'
& cmd /c "$Execute"

Write-Host '- Cleaning up...'
Get-ChildItem $TempPath | ForEach-Object { Remove-Item $_.fullname }

Write-Host '- Done'
}

Write-Host '===Begin Batch Encode==='

$OutPath, $TempPath | ForEach-Object {
if ((Test-Path -PathType 'Container' $_) -eq $False) {
if ((Read-Host "Error: Folder `"$_`" not found, type `"y`" to create it") -eq 'y') {
New-Item $_ -Type Directory | Out-Null
} else {
Write-Host 'Exiting. Edit source file to set up temp and output folders!'
exit
}
}
}

foreach ($Exe in $ExePath.Values) {
if ((Test-Path -PathType 'Leaf' $Exe) -eq $False) {
Write-Host "Error: Executable `"$Exe`" not found."
Write-Host 'Exiting. Edit source file to set up exe paths for x264, bepipe, neroaacenc and mp4box!'
exit
}
}

if ($Path -eq '') {
Write-Host 'Error: No path/file specified'
} elseif (Test-Path -PathType 'Leaf' $Path) {
Encode $Path
} elseif (Test-Path -PathType 'Container' $Path) {
Get-ChildItem ($Path + '*') -Include $FileTypes | ForEach-Object { Encode $_.FullName }
} else {
Write-Host "$Path is not a file/folder"
}

Write-Host '===End Batch Encode==='

Last edited by grv575; 11th January 2010 at 05:32.
grv575 is offline   Reply With Quote