Скрипт для сдвига субтитров по времени в файлах .srt

Субтитры — замечательная вещь, особенно когда не удается с первых десяти попыток разобрать что же сказал персонаж фильма или сериала сквозь грохот взрывов и скрежет рушащихся зданий. Однако случается так, что субтитры (в частности, те, что находятся в отдельном файле) не совпадают с видеорядом. Если отставание (или наоборот) составляет несколько секунд, то в этом нет ничего ужасного. В большинстве плееров это выправляется нажатием нескольких кнопок. Однако когда отставание составляет уже минуты и для того, чтобы нагнать видеоряд приходится совершить пару сотен нажатий — это несколько другое дело.

Здесь может помочь следующий скрипт.

В нем используются такие вещи как регулярные выражения, функция -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


Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s