Extension/Rate.rd.ext.ps1
|
<# .Synopsis Adjusts the rate of media. .Description Adjusts the playback rate of media, making it slower or faster. .Notes This uses a variety of filters: * setpts * atempo * asetpts .LINK https://ffmpeg.org/ffmpeg-filters.html#setpts .LINK https://ffmpeg.org/ffmpeg-filters.html#atempo #> [Management.Automation.Cmdlet("(?>Edit|Show)","Media")] # It extends Edit or Show-Media param( # The new rate of the media. [Parameter(Mandatory,ParameterSetName='Rate')] [double] $Rate, # The target time for the media. # This will adjust the rate to match this target time. [Parameter(Mandatory,ParameterSetName='TargetTime')] [ValidateScript({ if ( $_ -isnot [TimeSpan] -and $_ -isnot [int] -and $_ -isnot [double] ) { throw "Must be timespan, int, or double" } if ( $_ -le 0 ) { throw "Must be positive: $_" } return $true })] [psobject] $TargetTime ) $streams = $MediaInfo.streams $hasVideo = $streams | Where-Object { $_.Codec_Type -eq 'Video'} $hasAudio = $streams | Where-Object { $_.Codec_Type -eq 'Audio'} if ($targetTime -is [timespan]) { $rate = [TimeSpan]::FromSeconds($streams[0].duration) / $TargetTime } elseif ($TargetTime) { $rate = $streams[0].duration / $TargetTime } if ($hasVideo -and $hasAudio) { $videoRate = 1 / $rate "-filter_complex" if ($rate -ge .05 -and $rate -le 100) { "[0:v]setpts=$videoRate*PTS[v];[0:a]atempo=$Rate[a]" } else { Write-Warning 'Stream Contains Audio and is being adjusted by a factor greater than 2. Audio frames will be dropped rather instead of adjusting the tempo.' "[0:v]setpts=$videoRate*PTS[v];[0:a]asetpts=$videoRate*PTS[a]" } "-map" '[v]' "-map" '[a]' } elseif ($hasVideo) { $videoRate = 1 / $rate '-vf' "setpts=$videoRate*PTS" } elseif ($hasAudio) { '-af' if ($rate -ge .05 -and $rate -le 100) { "atempo=$Rate" } else { Write-Warning 'Stream Contains Audio and is being adjusted by a factor greater than 2. Audio frames will be dropped rather instead of adjusting the tempo.' "asetpts=$Rate*PTS" } } |