More development, added more robustness and error checking and cleaned output

main
Jonatan Nilsson 2021-09-28 07:44:56 +00:00
parent 4dce237600
commit 81ed27cd05
1 changed files with 48 additions and 17 deletions

View File

@ -2,13 +2,14 @@ param (
[String] $EncoderPath = "aomenc-3.0.0-335.exe",
[String] $FFmpegPath = "ffmpeg.exe",
[String] $FFprobePath = "ffprobe.exe",
[Switch] $PrintCommands,
[int] $EncoderType = 1, # Encoder type. 1 = aomenc, 2 = SVT-AV1
[int] $Renderer = 1, # Frame type, 1 = ffmpeg native, 2 = avisynth
[int] $MinChunkSec = 10,
[int] $Threads = 0,
[String] $Framerate = "auto",
[String] $AnalyzeVidSize = "848x480",
[String] $AnalyzeVidEnc = "-hide_banner -loglevel info -i {0} -map 0:0 -vf zscale={1}:f=spline36 -vcodec libx264 -preset veryfast -crf 40 -x264-params keyint={2}:min-keyint=5:scenecut=40 -y -pix_fmt yuv420p {3}",
[String] $AnalyzeVidEnc = "-hide_banner -hide_banner -loglevel error -stats -i {0} -map 0:0 -vf zscale={1}:f=spline36 -vcodec libx264 -preset veryfast -crf 40 -x264-params keyint={2}:min-keyint=5:scenecut=60 -y -pix_fmt yuv420p {3}",
[String] $AvisynthScript = "LSMASHVideoSource({0})",
[String] $EncoderOptions = "--cpu-used=8 --passes=1 --cq-level=10 --rt -o {0} -",
[parameter(Position=0)] [String] $InputFile = ""
@ -21,6 +22,7 @@ public struct KeyFrameData {
public int start;
public int end;
public decimal startstamp;
public int length;
}
"@
@ -37,8 +39,6 @@ public class ProjectChunkData {
}
"@
Write-Host ""
function Write-OurHelp {
Write-Host ""
Write-Host "S. Powershell variant of av1an"
@ -60,6 +60,7 @@ function Write-OurHelp {
Write-Host " -Framerate auto Frame rate of the video. Auto will use ffprobe"
Write-Host " to autodect. Otherwise you can specify it using"
Write-Host " rate/scale"
Write-Host " -PrintCommands Print all ffmpeg/ffprobe commands run and arguments"
Write-Host ""
Write-Host "Analyze options:"
Write-Host "The analyze file will be used to generate scenecut changes as well as other"
@ -83,6 +84,31 @@ function Assert-OurParameters {
Install-Module -Name ThreadJob -Scope CurrentUser
Write-Host "Install complete"
}
try {
$gobble = Invoke-NativeCommand -FilePath 'cmd' -ArgumentList ('/c', 'echo test') | Receive-RawPipeline
} catch {
Write-Host "Use-RawPipeline was not found, automatically installing for scope local user"
Install-Module -Name Use-RawPipeline -Scope CurrentUser
Write-Host "Install complete"
}
try {
$gobble = Invoke-NativeCommand -FilePath $FFprobePath -ArgumentList ('-loglevel', 'quiet', '-version') | Receive-RawPipeline
} catch {
Write-Error ("Error, unable to run or find $FFprobePath, make sure path or program exists. Error: " + $_.Exception.Message)
exit 1
}
try {
$gobble = Invoke-NativeCommand -FilePath $FFmpegPath -ArgumentList ('-loglevel', 'quiet', '-version') | Receive-RawPipeline
} catch {
Write-Error ("Error, unable to run or find $FFmpegPath, make sure path or program exists. Error: " + $_.Exception.Message)
exit 1
}
try {
$gobble = Invoke-NativeCommand -FilePath $EncoderPath -ArgumentList ('--help') | Receive-RawPipeline
} catch {
Write-Error ("Error, unable to run or find $EncoderPath, make sure path or program exists. Error: " + $_.Exception.Message)
exit 1
}
$writehelp = $false
if ($inputfile -eq "") {
@ -156,9 +182,12 @@ function Write-ProjectFile {
# Check if framerate is auto and grab it from the source file
if ($Framerate -eq 'auto') {
Write-Host "Framerate is auto, checking framerate from source"
$fpsPropeArgs = "-v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate $identifier1".Split(' ')
$fpsPropeArgs = Rename-ArrayIdentifiers $fpsPropeArgs $identifier1 $InputFile
if ($PrintCommands) { Write-Host "[Running] $FFprobePath $fpsPropeArgs" }
$Framerate = Invoke-NativeCommand -FilePath $FFprobePath -ArgumentList $fpsPropeArgs | Receive-RawPipeline
Write-Host "Framerate is: $Framerate"
}
# Split the framerate (rate/scale) to their respective values and calculate
@ -180,25 +209,22 @@ function Write-ProjectFile {
$analyzeffmpegSplitted = Rename-ArrayIdentifiers $AnalyzeVidEnc.Split(' ') $identifier1 $InputFile $identifier2 $analyzefilename
Write-Host "Creating $analyzefilename to generate keyframe split data from"
Write-Host ""
Write-Host "$FFmpegPath $analyzeffmpegSplitted"
Write-Host ""
# Create our analyze file
# Reason we use Invoke-NativeCommand is "ffmpeg.exe" if located in the same
# folder as script will make the Invoke-Expression fail as it requires .\ in
# front of it. Invoke-NativeCommand allows us to specify filepath and it will
# run regardless
if ($PrintCommands) { Write-Host "[Running] $FFmpegPath $analyzeffmpegSplitted" }
# Invoke-NativeCommand -FilePath $FFmpegPath -ArgumentList $analyzeffmpegSplitted | Receive-RawPipeline
Write-Host ""
Write-Host "Reading keyframe data from $analyzefilename"
Write-Host ""
$analyzekeyframefilename = $workproject + '_kf.txt'
# Start probing and analyzing our analyze file
$analyzePropeArgs = "-hide_banner -show_entries packet=pts_time,flags -select_streams v:0 -of csv=print_section=0 $identifier1".Split(' ')
$analyzePropeArgs = Rename-ArrayIdentifiers $analyzePropeArgs $identifier1 $InputFile
$analyzePropeArgs = "-loglevel error -hide_banner -show_entries packet=pts_time,flags -select_streams v:0 -of csv=print_section=0 $identifier1".Split(' ')
$analyzePropeArgs = Rename-ArrayIdentifiers $analyzePropeArgs $identifier1 $analyzefilename
if ($PrintCommands) { Write-Host "[Running] $FFprobePath $analyzePropeArgs" }
$videodata = Invoke-NativeCommand -FilePath $FFprobePath -ArgumentList $analyzePropeArgs | Receive-RawPipeline
# Invoke-Expression ".\$FFprobePath -hide_banner -show_entries packet=pts_time,flags -select_streams v:0 -of csv=print_section=0 $analyzefilename > $analyzekeyframefilename"
@ -210,7 +236,9 @@ function Write-ProjectFile {
for ($i = 0; $i -lt $videodata.Length; $i++) {
$split = $videodata[$i].Split(',')
if ($split.Count -gt 1 -and $split[1][0] -eq 'K') {
$keyframes.Add((New-Object KeyFrameData -Property @{ start = $i; startstamp = [convert]::ToDecimal($split[0]) }))
$keyframes.Add((New-Object KeyFrameData -Property @{
start = $i;
startstamp = [convert]::ToDecimal($split[0]) }))
}
}
@ -230,9 +258,11 @@ function Write-ProjectFile {
if ($length -gt $maxkeyint) {
if ($keyframes[$i - 1].start - 1 -gt $start.start) {
$start.end = $keyframes[$i - 1].start - 1
$start.length = $start.end - $start.start
$next = $keyframes[$i - 1]
if ($start.end - $start.start -lt $maxkeyint / 2) {
$start.end = $keyframes[$i].start - 1
$start.length = $start.end - $start.start
$next = $keyframes[$i]
}
$project.Add($start)
@ -245,14 +275,15 @@ function Write-ProjectFile {
}
}
$start.end = $videodata.Length - 1
$start.length = $start.end - $start.start
$project.Add($start)
$projectoutput = '{'
$projectoutput += "`n `"fps`":`"" + $Framerate + "`","
$projectoutput += "`n `"chunks`": ["
$projectoutput += "`n [" + $project[0].start + ", " + $project[0].end + ", " + $project[0].startstamp + "]"
$projectoutput += "`n [" + $project[0].start + ", " + $project[0].end + ", " + $project[0].startstamp + ", " + $project[0].length + "]"
for ($i = 1; $i -lt $project.Count; $i++) {
$projectoutput += ",`n [" + $project[$i].start + ", " + $project[$i].end + ", " + $project[$i].startstamp + "]"
$projectoutput += ",`n [" + $project[$i].start + ", " + $project[$i].end + ", " + $project[$i].startstamp + ", " + $project[$i].length + "]"
}
$projectoutput += "`n ]"
$projectoutput += "`n}"
@ -265,6 +296,10 @@ function Write-ProjectFile {
-------------------------------------------------------------------
#>
function Start-OurEncoding {
if ($Threads -lt 1) {
$Threads = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
}
Write-Host "Starting our chunk encoder with maximum $Threads workers"
Write-Host ""
$encodefile = $workproject + '_output'
@ -404,10 +439,6 @@ function Start-OurEncoding {
try {
Assert-OurParameters
if ($Threads -lt 1) {
$Threads = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
}
$workproject = [io.path]::GetFileNameWithoutExtension($InputFile)
$projectfile = $workproject + '_spav1an.json'