More development, added more robustness and error checking and cleaned output
This commit is contained in:
parent
4dce237600
commit
81ed27cd05
1 changed files with 48 additions and 17 deletions
65
spav1an.ps1
65
spav1an.ps1
|
@ -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'
|
||||
|
||||
|
|
Loading…
Reference in a new issue