Сдвиг субтитров

В выходные занимался просмотром фильмов на английском языке, а так как еще не всегда удаётся понимать речь на лету — приходиться использовать субтитры. И нет ничего более раздражающего чем когда субтитры немного сдвинуты отностительно звуковой дорожки. К сожалению мне попалось несколько подобных случаев. Правда, к счастью субтитры у меня были не «вшиты» в видео файл, а в отдельном .srt файле.

Srt — это обычный текстовый файл в котором сначала указан временной отрезок, а затем текст, примерно так:

2
00:00:09,376 --> 00:00:10,604
Good morning.

3
00:00:20,620 --> 00:00:21,848
Hey, Alfredo.

Чтобы исправить задержку времени, достаточно разобрать строку со временем на компоненты, преобразовать их в тип DateTime, прибавить (или отнять) несколько секунд, и затем преобразовать в исходный формат. Остальные строки надо оставить неизменными.

На написание oneliner’а в консоли у меня ушло минут 10, зато нервов я сэкономил часа на три🙂 Оригинал я публиковать не буду (он совсем не читабельный😉 ), а лучше приведу в нормальный «продакшн» вид🙂


Function Set-Subtitle ($File, [int]$Seconds)
{
    #Регулярное выражение для отбора нужных строк, и захвата отрезков с временем
    $Pattern = "([\d:,]+) --> ([\d:,]+)"
    #Маска для разбора значения времени, и форматирования обратно
    $Mask = "HH:mm:ss,fff"
    #Получаем содержимое файла и передаем по конвейеру
    Get-Content $File | 
        #Для каждой строки...
        ForEach {
            #Если строка подпадает под регулярное выражение...
            if ($_ -match $Pattern)
            {
                #Получаем время начала  показа в виде DateTime
                $DateStart = [datetime]::parseExact($matches[1],$mask,$null)
                #И аналогично время завершения показа
                $DateEnd = [datetime]::parseexact($matches[2],$mask,$null)
                #Прибавляем к датам указанное количество секунд
                $DateStart = $DateStart.AddSeconds($Seconds)
                $DateEnd = $DateEnd.AddSeconds($Seconds)
                #Выдаем преобразованные даты дальше по конвейеру, отформатировав
                #их соответствующим образом с помощью оператора -f
                "{0:$mask} --> {1:$mask}" -f $DateStart,$DateEnd
            }
            #Иначе - передаем по конвейеру строку без изменений.
            else {$_}
        #Помещаем данные из конвейера в переменную $Result (знак $ не является 
        #частью имени переменной, так что его не указываем.
        } | Set-Variable -Name Result
    #Помещаем результат в файл
    $Result | Set-Content $File
}

В параметре -File указываем файл субтитров для обработки, а в -Seconds соответственно время сдвига в секундах (можно указывать и отрицательное значение).

Ну и пара ссылок на приемы работы с датами которые я тут использовал: ParseExact и оператор -f.

комментария 2 to “Сдвиг субтитров”

  1. homo Says:

    видимо всё-таки oneliner’a а не onliner’a🙂

  2. Xaegr Says:

    2 homo: Разумеется🙂 Пофиксил, спасибо.
    Главное чтоб в теле скрипта подобных опечаток не было🙂


Обсуждение закрыто.

%d такие блоггеры, как: