Add -Reverse parameter to reencode video backward while keeping audio forward, and add 1284x716 to 1280x720 crop support in Crop-ClipsWan
This commit is contained in:
+41
-10
@@ -33,6 +33,11 @@
|
||||
Constant Rate Factor for video encoding (0-51, lower is better quality). When specified, overrides both the video bitrate and the default -crf 8 value. Only used when re-encoding is required.
|
||||
.PARAMETER Metadata
|
||||
When present, copies available JSON metadata from the source video file to the target video file.
|
||||
.PARAMETER Reverse
|
||||
When present, re-encodes the video so it plays backward (from the last selected frame to the first).
|
||||
Honours all other parameters (StartFrame/EndFrame range, Size, FPS, CRF, container choice, etc.).
|
||||
Audio is NOT reversed; it is processed exactly as it would be without -Reverse (trimmed/replaced/copied as applicable) and plays forward alongside the reversed video.
|
||||
Forces a video re-encode, since the reverse filter cannot be applied to a stream-copied video.
|
||||
.DESCRIPTION
|
||||
This script uses ffmpeg to clone (copy) a video file with optional frame range and audio exclusion.
|
||||
When Sequence is provided, it extracts a specific frame to PNG and then clones the video accordingly.
|
||||
@@ -71,7 +76,10 @@ param(
|
||||
[int]$CRF = -1,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Metadata
|
||||
[switch]$Metadata,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Reverse
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
@@ -173,7 +181,10 @@ if (-not [string]::IsNullOrWhiteSpace($Audio)) {
|
||||
# rather than stream-copied.
|
||||
$ffprobeExtAudioOutput = & ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 -- $AudioPath 2>&1
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$externalAudioCodec = ($ffprobeExtAudioOutput | Select-Object -First 1).Trim().ToLowerInvariant()
|
||||
$extAudioLine = $ffprobeExtAudioOutput | Select-Object -First 1
|
||||
if ($extAudioLine) {
|
||||
$externalAudioCodec = ([string]$extAudioLine).Trim().ToLowerInvariant()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +226,8 @@ if ($ffprobeExit -ne 0) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
$fpsRatio = ($ffprobeFpsOutput | Select-Object -First 1).Trim()
|
||||
$fpsRatioLine = $ffprobeFpsOutput | Select-Object -First 1
|
||||
$fpsRatio = if ($fpsRatioLine) { ([string]$fpsRatioLine).Trim() } else { '' }
|
||||
|
||||
if (-not $fpsRatio -or $fpsRatio -notmatch '^\d+/\d+$') {
|
||||
Write-Error ('Could not determine frame rate for: {0}' -f $SourcePath)
|
||||
@@ -235,7 +247,8 @@ if ($ffprobeExit -ne 0) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
$totalFrames = ($ffprobeFramesOutput | Select-Object -First 1).Trim()
|
||||
$totalFramesLine = $ffprobeFramesOutput | Select-Object -First 1
|
||||
$totalFrames = if ($totalFramesLine) { ([string]$totalFramesLine).Trim() } else { '' }
|
||||
|
||||
if (-not $totalFrames -or $totalFrames -notmatch '^\d+$') {
|
||||
Write-Error ('Could not determine frame count for: {0}' -f $SourcePath)
|
||||
@@ -250,9 +263,12 @@ $ffprobeExit = $LASTEXITCODE
|
||||
|
||||
$videoBitrate = $null
|
||||
if ($ffprobeExit -eq 0) {
|
||||
$bitrateValue = ($ffprobeBitrateOutput | Select-Object -First 1).Trim()
|
||||
if ($bitrateValue -and $bitrateValue -match '^\d+$') {
|
||||
$videoBitrate = $bitrateValue
|
||||
$bitrateLine = $ffprobeBitrateOutput | Select-Object -First 1
|
||||
if ($bitrateLine) {
|
||||
$bitrateValue = ([string]$bitrateLine).Trim()
|
||||
if ($bitrateValue -and $bitrateValue -match '^\d+$') {
|
||||
$videoBitrate = $bitrateValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,13 +278,19 @@ if ($ffprobeExit -eq 0) {
|
||||
$ffprobeVideoCodecOutput = & ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 -- $SourcePath 2>&1
|
||||
$sourceVideoCodec = ''
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$sourceVideoCodec = ($ffprobeVideoCodecOutput | Select-Object -First 1).Trim().ToLowerInvariant()
|
||||
$vCodecLine = $ffprobeVideoCodecOutput | Select-Object -First 1
|
||||
if ($vCodecLine) {
|
||||
$sourceVideoCodec = ([string]$vCodecLine).Trim().ToLowerInvariant()
|
||||
}
|
||||
}
|
||||
|
||||
$ffprobeAudioCodecOutput = & ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 -- $SourcePath 2>&1
|
||||
$sourceAudioCodec = ''
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$sourceAudioCodec = ($ffprobeAudioCodecOutput | Select-Object -First 1).Trim().ToLowerInvariant()
|
||||
$aCodecLine = $ffprobeAudioCodecOutput | Select-Object -First 1
|
||||
if ($aCodecLine) {
|
||||
$sourceAudioCodec = ([string]$aCodecLine).Trim().ToLowerInvariant()
|
||||
}
|
||||
}
|
||||
|
||||
# A source codec not on the target container's stream-copy list forces a re-encode
|
||||
@@ -364,6 +386,9 @@ if ($scaleWidth -gt 0) {
|
||||
if ($FPS -gt 0) {
|
||||
Write-Host (' FPS: {0}' -f $FPS)
|
||||
}
|
||||
if ($Reverse) {
|
||||
Write-Host ' Reverse: video reversed, audio unchanged'
|
||||
}
|
||||
Write-Host (' Target: {0}' -f $TargetPath)
|
||||
|
||||
$ffmpegArgs = @(
|
||||
@@ -375,7 +400,7 @@ if ($AudioPath) {
|
||||
$ffmpegArgs += @('-i', $AudioPath)
|
||||
}
|
||||
|
||||
$needsReencode = $scaleWidth -gt 0 -or $FPS -gt 0 -or $videoCodecMismatch
|
||||
$needsReencode = $scaleWidth -gt 0 -or $FPS -gt 0 -or $videoCodecMismatch -or $Reverse
|
||||
|
||||
if ($StartFrame -gt 0 -or $actualEndFrame -lt $maxFrameIndex) {
|
||||
$filterParts = @('select=between(n\,{0}\,{1})' -f $StartFrame, $actualEndFrame)
|
||||
@@ -386,6 +411,9 @@ if ($StartFrame -gt 0 -or $actualEndFrame -lt $maxFrameIndex) {
|
||||
if ($FPS -gt 0) {
|
||||
$filterParts += ('fps={0}' -f $FPS)
|
||||
}
|
||||
if ($Reverse) {
|
||||
$filterParts += 'reverse'
|
||||
}
|
||||
$videoFilter = $filterParts -join ','
|
||||
$ffmpegArgs += @(
|
||||
'-vf', $videoFilter
|
||||
@@ -410,6 +438,9 @@ if ($StartFrame -gt 0 -or $actualEndFrame -lt $maxFrameIndex) {
|
||||
if ($FPS -gt 0) {
|
||||
$filterParts += ('fps={0}' -f $FPS)
|
||||
}
|
||||
if ($Reverse) {
|
||||
$filterParts += 'reverse'
|
||||
}
|
||||
if ($filterParts.Count -gt 0) {
|
||||
$videoFilter = $filterParts -join ','
|
||||
$ffmpegArgs += @('-vf', $videoFilter)
|
||||
|
||||
Reference in New Issue
Block a user