Last active
June 5, 2021 22:26
-
-
Save khaosx/32774efa7ce110d0be9a908faf86f12c to your computer and use it in GitHub Desktop.
Convert media using Don Melton's Other Video Transcoding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
######################################################## | |
# hw-convert-media | |
##################################################-kan-# | |
<# | |
.Synopsis | |
This script will create batch files to convert media using Don Melton's Other Video Transcoding project. | |
.DESCRIPTION | |
This script examines all .mkv files located in a specified directory to determine appropriate transcoding options based around Don Melton's Other Video Transcoding project(see links). | |
Once examined, .cmd files will be generated for each file for later processing. | |
.EXAMPLE | |
hw-convert-media.ps1 -mode [mode] | |
Sets the script options based on what kind of output is desired. | |
hw-convert-media.ps1 -help | |
Displays help for script options. | |
.NOTES | |
Author : Copyright 2020 - K. Austin Newman | |
Version : 2.5.0 | |
Date : 06/05/2021 | |
.INPUTS | |
Inputs to this script file | |
- mode [default,hevc,testing,testsuite,customdir] | |
.OUTPUTS | |
Creates a cmd file with same name as input file. | |
.LINK | |
https://github.com/donmelton/other_video_transcoding | |
#> | |
# Define arguments | |
Param( | |
[Parameter( Mandatory = $false )] | |
[ValidateSet( "default","qsv","testing","testsuite","customdir" )] | |
[string]$mode | |
) | |
# Define user vars | |
$dirWorkflowRoot = "workflows" | |
$dirWorkflowName = "transcoding" | |
$optionSet = $mode | |
# Define Functions | |
function findDriveLetterForVolume { | |
param ($volumeName) | |
try { | |
$drvData = get-volume -FileSystemLabel "$volumeName" -ErrorAction Stop | |
$script:strRootVol = $drvData.DriveLetter | |
} | |
catch { | |
Write-warning "Volume $volumeName not available" | |
exit 1 | |
} | |
} | |
function buildAndVerifyWorkingDirectories { | |
$script:dirWorkFlow = "$strRootVol`:\$dirWorkflowRoot\$dirWorkflowName" | |
if ( $mode -ne "testsuite" ) { | |
$script:dirReady = "$dirWorkFlow\ready" | |
} | |
else { | |
$script:dirReady = "C:\Users\kris\Documents\test-suite" | |
} | |
if ( $mode -ne "testsuite" ) { | |
$script:dirOutbox = "$dirWorkFlow\outbox" | |
} | |
else { | |
$script:dirOutbox = "$dirTesting" | |
} | |
$script:dirManual = "$dirWorkFlow\manual" | |
$script:dirLogs = "$dirWorkFlow\encodingLogs" | |
$script:dirArchive = "$dirOutbox\archive" | |
$script:dirQueue = "$dirWorkFlow\queue" | |
$script:dirTesting = "$dirWorkFlow\testing" | |
$script:dirOverrides = "$dirWorkFlow\overrides" | |
if ( $mode -ne "testing" -AND $mode -ne "testsuite" ) { | |
$script:engine = "other-transcode" | |
} | |
else { | |
$script:engine = "beta-other-transcode" | |
} | |
$aPaths = $dirWorkFlow,$dirReady,$dirOutbox,$dirManual,$dirLogs,$dirArchive,$dirQueue,$dirTesting,$dirOverrides | |
foreach ( $dir in $aPaths ) { | |
If (!( Test-Path "$dir" )) { | |
New-Item -ItemType Directory -Force -Path $dir -ErrorAction SilentlyContinue | |
} | |
} | |
} | |
function verifyAllToolRequirements { | |
$aTools = "ruby","beta-other-transcode","ffmpeg","mpv","ffprobe","remux","mkvmerge","jq","mkvpropedit","filebot" | |
foreach ( $tool in $aTools ) { | |
if ( $null -eq ( Get-Command "$tool" -ErrorAction SilentlyContinue )) { | |
Write-warning -Message "Executable not in path: $tool" | |
$strExit = $true | |
} | |
if ( $strExit -eq $true ) { | |
Write-warning "Exiting due to previous errors" | |
exit 1 | |
} | |
} | |
} | |
Function Get-Folder($initialDirectory="") { | |
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null | |
$foldername = New-Object System.Windows.Forms.FolderBrowserDialog | |
$foldername.Description = "Select a folder" | |
$foldername.rootfolder = "MyComputer" | |
$foldername.SelectedPath = $initialDirectory | |
if($foldername.ShowDialog() -eq "OK") | |
{ | |
$folder += $foldername.SelectedPath | |
} | |
return $folder | |
} | |
# Begin Processing | |
## Define immutable vars | |
$dirStartingLoc = Get-Location | |
$strTVRegEx = "([sS]([0-9]{2,}|[X]{2,})[eE]([0-9]{2,}|[Y]{2,}))" | |
## Verify all paths and tools | |
findDriveLetterForVolume "data" | |
buildAndVerifyWorkingDirectories | |
verifyAllToolRequirements | |
### Define variables | |
#### Defaults | |
switch ( $optionset ) { | |
qsv { | |
$strVidOpts = "--decode all --qsv-device 1 --qsv" | |
$strAudOpts = "--all-eac3 --keep-ac3-stereo --add-audio all --pass-dts" | |
$strTargets = "--target 2160p=16000 --target 1080p=8000 --target 720p=4000 --target 480p=2000" | |
$strSafeOpts = "--max-muxing-queue-size 1024" | |
} | |
default { | |
$strVidOpts = "--hevc --nvenc-recommended --8-bit-vc1" | |
$strAudOpts = "--aac-only --add-audio all" | |
$strTargets = "" #"--target 2160p=8000 --target 1080p=4000 --target 720p=2000 --target 480p=1000" | |
$strSafeOpts = "--max-muxing-queue-size 1024" | |
} | |
testing { | |
$strVidOpts = "--hevc --nvenc-recommended --8-bit-vc1" | |
$strAudOpts = "--aac-only --add-audio all" | |
$strTargets = "" | |
$strSafeOpts = "--max-muxing-queue-size 1024" | |
} | |
testsuite { | |
$strVidOpts = "--hevc --nvenc-recommended --8-bit-vc1" | |
$strAudOpts = "--aac-only --add-audio all" | |
$strTargets = "" | |
$strSafeOpts = "--max-muxing-queue-size 1024" | |
} | |
customdir { | |
$strVidOpts = "--hevc --nvenc-recommended --8-bit-vc1" | |
$strAudOpts = "--aac-only --add-audio all" | |
$strTargets = "" #"--target 2160p=8000 --target 1080p=4000 --target 720p=2000 --target 480p=1000" | |
$strSafeOpts = "--max-muxing-queue-size 1024" | |
} | |
} | |
## Process all MKV files | |
if ( $optionSet = "customdir" ) { | |
$dirReady = Get-Folder | |
} | |
$fArray = Get-ChildItem -recurse $dirReady -include *.mkv -File | |
foreach ($element in $fArray){ | |
Write-Output "Processing $element" | |
$strTheFile = $element.ToString() | |
$strFilename = (Get-Item $strTheFile).Basename | |
$strExtension = (Get-Item $strTheFile).Extension | |
### Run ffprobe against result | |
$strMI = ffprobe -i "$strTheFile" -show_format -show_streams -show_data -v quiet -print_format json=compact=1 -v quiet | |
### Check for overrides file and apply | |
$strOverrides = "" | |
if ( Test-Path "$dirOverrides\$strFilename.txt" ) { | |
$strOverrides = Get-Content $dirOverrides\$strFilename.txt | |
} | |
### if TV episode, set significantly lower bitrates | |
If ($strTheFile -match $strTVRegEx){ | |
$strOverrides = "$strOverrides --nvenc-cq 28" | |
} | |
### Set Subtitle Options - Soft add all eng subtitles, find forced and mark in file | |
$strSubOpts = "" | |
$strSubInfo = ffprobe -i "$strTheFile" -select_streams s -show_streams -print_format json=compact=1 -v quiet | |
$intSubCount = 0 | |
$subtrack = "$strSubInfo" | jq -r '.streams[] | .disposition | .forced' | |
ForEach ( $element in $subtrack ){ | |
$strLanguage = "$strSubInfo" | jq -r ".streams[$intSubCount] | .tags | .language" | |
$intSubCount++ | |
if ( "$element" -eq "1" -And "$strLanguage" -eq "eng" ){ | |
$strSubOpts = "$strSubOpts --add-subtitle $intSubCount=forced" | |
} | |
elseif ( "$strLanguage" -eq "eng" ){ | |
$strSubOpts = "$strSubOpts --add-subtitle $intSubCount" | |
} | |
} | |
$stroptionsLine = "$strVidOpts $strTargets $strAudOpts $strSafeOpts $strSubOpts $strOverrides" | |
### Write command file | |
$outfile = Join-Path -Path "$dirQueue" -ChildPath "$strFilename.cmd" | |
if ( Test-Path $outfile ) { | |
write-warning "$outfile already exists - Skipping" | |
continue | |
} | |
New-Item -Path "$dirQueue" -Name "$strFilename.cmd" -Force -ItemType "file" | |
out-file $outfile -Append -encoding OEM -inputObject "@ECHO Off" | |
out-file $outfile -Append -encoding OEM -inputObject "$strRootVol`:" | |
out-file $outfile -Append -encoding OEM -inputObject "cd ""$dirOutbox""" | |
out-file $outfile -Append -encoding OEM -inputObject "call $engine $stroptionsLine ""$strTheFile""" | |
if ( $mode -ne "testing" -AND $mode -ne "testsuite" ) { | |
out-file $outfile -Append -encoding OEM -inputObject "move ""$strTheFile"" ""$dirArchive""" | |
out-file $outfile -Append -encoding OEM -inputObject "move ""$dirOutbox\$strFilename.mkv.log"" ""$dirLogs""" | |
If ($strTheFile -match $strTVRegEx){ | |
out-file $outfile -Append -encoding OEM -inputObject "filebot -rename ""$dirOutbox\$strFilename.mkv"" --db TheTVDB --format "".\{n} - {s00e00} - {t}"" -non-strict" | |
} else { | |
out-file $outfile -Append -encoding OEM -inputObject "filebot -rename ""$dirOutbox\$strFilename.mkv"" --db TheMovieDB --format c:\bin\movies_final.groovy -non-strict" | |
} | |
} | |
out-file $outfile -Append -encoding OEM -inputObject "DEL ""%~f0""" | |
} | |
Write-Output "No files remain to be processed. Exiting..." | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment