Rename -Scene parameter to -Level in Create-Scenes.ps1, add -Scenes parameter for automatic level search to detect exact scene count with binary search algorithm, update documentation across Create-Scenes.md, SKILL.md, README.md and index.md to explain search behavior and exit code 1 on failure, fix agent skills directory paths to use Windows environment variables and add VS Code location
This commit is contained in:
1 parent
60feb778d3
commit
4378e3fd99
5 files changed
+103
-30
No files matched your search
+62
-14
@@ -2,7 +2,7 @@
|
||||
.SYNOPSIS
|
||||
Detects scenes in a video file with ffmpeg and extracts each scene as a separate video clip file.
|
||||
.DESCRIPTION
|
||||
Analyzes the input video with ffmpeg scene-change detection, using the -Scene threshold, and computes
|
||||
Analyzes the input video with ffmpeg scene-change detection, using the -Level threshold, and computes
|
||||
the first and last frame (0-based) of each detected scene. Each scene is then extracted by calling
|
||||
Create-Clip.ps1 (located in the same directory as this script) with the scene frame range, which in
|
||||
turn calls Clone-Video.ps1.
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
The list of scenes (index, start frame, end frame, frame count, start time, end time) is always displayed.
|
||||
If no scene change is detected, the whole video is treated as a single scene.
|
||||
With -Scenes, the level is adjusted automatically until the requested number of scenes is detected; every
|
||||
attempt is displayed. If that number cannot be reached, the script stops with exit code 1 and creates or
|
||||
deletes nothing.
|
||||
|
||||
Unless -List is specified, existing scene clip files from a previous run (same directory, same source
|
||||
name, same suffix pattern and same extension) are deleted before the new clips are created. Existing
|
||||
@@ -29,9 +32,12 @@
|
||||
.PARAMETER Video
|
||||
Path to the input video file. Can be absolute or relative to current directory. If the path has no
|
||||
extension, .mp4, .webm and .mkv are tried in turn.
|
||||
.PARAMETER Scene
|
||||
Threshold value between 0 and 1.0 to determine scene changes. Lower values mean more sensitive
|
||||
detection (more scenes). Default is 0.3.
|
||||
.PARAMETER Level
|
||||
Threshold level value between 0 and 1.0 to determine scene changes. Lower values mean more sensitive
|
||||
detection (more scenes). Default is 0.3. The value is rounded to 2 decimals.
|
||||
.PARAMETER Scenes
|
||||
Target number of scenes (a positive integer). The level is searched automatically, starting from -Level,
|
||||
until exactly this many scenes are detected. Stops with exit code 1 if the number cannot be reached.
|
||||
.PARAMETER Suffix
|
||||
Scene suffix to use for the output video clip files. Must contain a printf-style number placeholder
|
||||
such as %02d, which is replaced by the scene number starting at 1. By default, "-Scene-%02d" is used.
|
||||
@@ -39,13 +45,16 @@
|
||||
Only displays the list of scenes. No video clip file is created and no existing file is deleted.
|
||||
.PARAMETER ExtraArgs
|
||||
Additional parameters passed as-is to Create-Clip.ps1 and from there to Clone-Video.ps1
|
||||
(ex: -Size 720p -NoAudio -CRF 18 -LTX). The parameters -Video, -Frames, -Suffix and -Target are
|
||||
managed by this script and must not be repeated.
|
||||
(ex: -Size 720p -NoAudio -CRF 18 -LTX). The parameters -Video, -Frames, -Suffix, -Target, -Level and
|
||||
-Scenes are managed by this script and must not be repeated.
|
||||
.EXAMPLE
|
||||
.\Create-Scenes.ps1 -Video P01.mp4 -Scene 0.4 -List
|
||||
.\Create-Scenes.ps1 -Video P01.mp4 -Level 0.4 -List
|
||||
Lists the scenes detected in P01.mp4 without creating or deleting any file.
|
||||
.EXAMPLE
|
||||
.\Create-Scenes.ps1 -Video P01 -Scene 0.3 -Size 720p -NoAudio
|
||||
.\Create-Scenes.ps1 -Video P01.mp4 -Scenes 4 -List
|
||||
Searches the level automatically and lists the scenes once exactly 4 scenes are detected.
|
||||
.EXAMPLE
|
||||
.\Create-Scenes.ps1 -Video P01 -Level 0.3 -Size 720p -NoAudio
|
||||
Creates P01-Scene-01.mp4, P01-Scene-02.mp4, ... scaled to 720p and without audio.
|
||||
.EXAMPLE
|
||||
.\Create-Scenes.ps1 -Video P01.mp4 -Suffix "-Shot-%03d" -WhatIf
|
||||
@@ -59,7 +68,11 @@ param(
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateRange(0.0, 1.0)]
|
||||
[double]$Scene = 0.3,
|
||||
[double]$Level = 0.3,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateRange(1, [int]::MaxValue)]
|
||||
[int]$Scenes,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
@@ -234,16 +247,51 @@ $videoPath = Resolve-VideoPath -Path $Video
|
||||
[object[]]$tokens = @()
|
||||
if ($null -ne $ExtraArgs) { $tokens = @($ExtraArgs) }
|
||||
$extraParams = ConvertTo-ClipArgument -Tokens $tokens
|
||||
foreach ($reserved in 'Video', 'Frames', 'Suffix', 'Target') {
|
||||
foreach ($reserved in 'Video', 'Frames', 'Suffix', 'Target', 'Level', 'Scenes') {
|
||||
if ($extraParams.ContainsKey($reserved)) {
|
||||
throw "-$reserved is managed by Create-Scenes.ps1 and must not be passed as an extra parameter."
|
||||
}
|
||||
}
|
||||
|
||||
$info = Get-VideoInfo -Path $videoPath
|
||||
$changeTimes = @(Get-SceneChangeTime -Path $videoPath -Threshold $Scene)
|
||||
$scenes = @(Get-SceneList -Info $info -ChangeTimes $changeTimes -Template $Suffix)
|
||||
$scenes | Format-Table -AutoSize | Out-Host
|
||||
# Level rounded to 2 decimals. The search rounds each new level to 2 decimals too; the step is not rounded.
|
||||
$sceneLevel = [Math]::Round($Level, 2, [MidpointRounding]::AwayFromZero)
|
||||
if ($PSBoundParameters.ContainsKey('Scenes')) {
|
||||
$sceneStep = 0.1
|
||||
$sceneDirection = 0
|
||||
$pass = 0
|
||||
while ($true) {
|
||||
$pass++
|
||||
$changeTimes = @(Get-SceneChangeTime -Path $videoPath -Threshold $sceneLevel)
|
||||
$sceneList = @(Get-SceneList -Info $info -ChangeTimes $changeTimes -Template $Suffix)
|
||||
'Pass {0}: level {1} -> {2} scene(s)' -f $pass, $sceneLevel, $sceneList.Count | Out-Host
|
||||
$sceneList | Format-Table -AutoSize | Out-Host
|
||||
if ($sceneList.Count -eq $Scenes) { break }
|
||||
if ($sceneList.Count -lt $Scenes) {
|
||||
# Fewer scenes than requested: a lower level detects more scenes.
|
||||
if ($sceneDirection -eq 0) { $sceneDirection = -1 }
|
||||
elseif ($sceneDirection -eq 1) { $sceneDirection = -1; $sceneStep = $sceneStep / 2.0 }
|
||||
}
|
||||
else {
|
||||
# More scenes than requested: a higher level detects fewer scenes.
|
||||
if ($sceneDirection -eq 0) { $sceneDirection = 1 }
|
||||
elseif ($sceneDirection -eq -1) { $sceneDirection = 1; $sceneStep = $sceneStep / 2.0 }
|
||||
}
|
||||
if ($sceneStep -lt 0.01) {
|
||||
throw "The number of scenes -Scenes $Scenes could not be found - Search stopped at scene level $sceneLevel."
|
||||
}
|
||||
$sceneLevel = [Math]::Round($sceneLevel + ($sceneDirection * $sceneStep), 2, [MidpointRounding]::AwayFromZero)
|
||||
if ($sceneLevel -lt 0 -or $sceneLevel -gt 1) {
|
||||
throw "The number of scenes -Scenes $Scenes could not be found - Search stopped at scene level $sceneLevel, which is outside the range 0 to 1.0."
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$changeTimes = @(Get-SceneChangeTime -Path $videoPath -Threshold $sceneLevel)
|
||||
$sceneList = @(Get-SceneList -Info $info -ChangeTimes $changeTimes -Template $Suffix)
|
||||
$sceneList | Format-Table -AutoSize | Out-Host
|
||||
}
|
||||
'Scene level used: {0}' -f $sceneLevel | Out-Host
|
||||
if ($List) { return }
|
||||
|
||||
$confirm = [bool]$PSBoundParameters['Confirm']
|
||||
@@ -251,7 +299,7 @@ $pattern = Get-SceneFilePattern -VideoPath $videoPath -Template $Suffix
|
||||
Remove-ExistingScene -VideoPath $videoPath -Pattern $pattern -WhatIf:$WhatIfPreference -Confirm:$confirm
|
||||
|
||||
$failures = 0
|
||||
foreach ($clipScene in $scenes) {
|
||||
foreach ($clipScene in $sceneList) {
|
||||
$frames = '{0}-{1}' -f $clipScene.StartFrame, $clipScene.EndFrame
|
||||
Write-Verbose ('Scene {0}: frames {1}, suffix {2}' -f $clipScene.Index, $frames, $clipScene.Suffix)
|
||||
# Extra parameters are forwarded as the original token array, not as the hashtable: Create-Clip.ps1
|
||||
|
||||
Reference in new issue
Block a user