Субтитры — замечательная вещь, особенно когда не удается с первых десяти попыток разобрать что же сказал персонаж фильма или сериала сквозь грохот взрывов и скрежет рушащихся зданий. Однако случается так, что субтитры (в частности, те, что находятся в отдельном файле) не совпадают с видеорядом. Если отставание (или наоборот) составляет несколько секунд, то в этом нет ничего ужасного. В большинстве плееров это выправляется нажатием нескольких кнопок. Однако когда отставание составляет уже минуты и для того, чтобы нагнать видеоряд приходится совершить пару сотен нажатий — это несколько другое дело.
Здесь может помочь следующий скрипт.
В нем используются такие вещи как регулярные выражения, функция -f для форматирования данных нужным нам образом, а также статическая функция [datetime]::Parse(). Можно довольно долго рассказывать о каждой из них по-отдельности, поэтому я не буду вдаваться в детали в этом посте, а просто выложу скрипт, а точнее функцию.
Для ее использования нужно указать путь к исходному файлу (параметр path_original), путь к результирующему файлу (path_result), временной промежуток, на который нужно сдвинуть (параметры minutes и seconds), а также в каком направлении нужно сдвинуть субтитры — в сторону увеличения временных меток (Increase — значение по-умолчанию, поэтому явно параметр указывать не обязательно) или в сторону их уменьшения (Decrease).
function moveit { [CmdletBinding(DefaultParameterSetName="Increase")] Param( [parameter(Mandatory=$true)] [string] $path_original, [parameter(Mandatory=$true)] [string] $path_result, [int] $minutes = 0, [ValidateRange(0,59)] [int] $seconds = 0, [parameter(Mandatory=$false, ParameterSetName="Increase")] [switch] $Increase = $true, [parameter(Mandatory=$true, ParameterSetName="Decrease")] [switch] $Decrease ) if($Decrease) {$Increase = $false} $PSCmdlet.ParameterSetName $offset = New-TimeSpan -Minutes $minutes -Seconds $seconds $content = Get-Content $path_original #[datetime]$refstart = 0 #[datetime]$refend = 0 Set-Content -Value $null -Path $path_result foreach($line in $content) { if($line -match '(?\d\d:\d\d:\d\d,\d\d\d) --> (?\d\d:\d\d:\d\d,\d\d\d)') { $refstart = [datetime]::Parse($($matches.start -replace ',','.')) $refend = [datetime]::Parse($($matches.end -replace ',','.')) if($Increase) { $offstart = $refstart+$offset $offend = $refend+$offset } else { if($refstart.TimeOfDay -lt $offset) { $offstart = [datetime]0 } else { $offstart = $refstart-$offset } if($refend.TimeOfDay -lt $offset) { $offend = [datetime]0 } else { $offend = $refend-$offset } } Add-Content -Value $("{0:HH:mm:ss,fff} --> {1:HH:mm:ss,fff}" -f $offstart,$offend) -Path $path_result } else { Add-Content -Value $line -Path $path_result } } }
Страницы в социальных сетях:
Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell