Finar.ru
web.finar.ru
video.finar.ru
Темы для BootstrapNew!

Русификация HDTV-рипов

с помощью AviSynth

Автор: Филипп Казаков | 2006-10-12 | просмотров 7514
Тэги

Заметка посвящена наложению русского звука/субтитров на HDTV рипы. Как сделать такой рип, читайте в статье "h264 - год спустя". В принципе, заметка применима для русификации любых других рипов. Предполагается, что читатель обладает базовым пониманием Avisynth, а также владеет терминологией. Основы Avisynth тут .

Русификация HDTV-рипов.

Содержание:

  1. Часть 1. Замена звуковой дорожки.
  2. Часть 2. Наложение перевода.
  3. Часть 3. Ввод субтитров.
  4. Часть 4. Что же со всем этим делать?

Дано: добытое из неких источников HDTV MPEG-TS видео на иностранном языке, ее русскоязычный эквивалент (RUS.ac3) полученный из неких источников.

Задача: синхронизировать оригинальную (далее ENG) и русскоязычную (далее RUS) звуковые дорожки, чтобы в процессе кодирования заменить ENG на RUS.

Дополнительные условия: 1) ENG и RUS зажаты в ac3. Если они зажаты во %что угодно%, все приведенные скипты нужно слегка изменить, подключив нужный для декодирования %чего угодно% avisynth-плагин. То же касается и всех остальных описываемых файлов. 2) Все рабочие файлики лежат в одной папке. Поэтому не надо прописывть пути в скриптах. Если у вас они в разных папках, изменяйте пути в скриптах.

Общая рекомендация: если у вас не очень быстрый компьютер (<3.2 ГГц PIV в интеловском эквиваленте), рекомендуется создать из d2v-проекта маленькое (~320х240) видеопревью закодированное быстрым кодеком без межкадрового сжатия, например PicVideo mjpeg или DV. Это займет не более пары часов работы ПК, зато сильно увеличит комфорт работы по синхронизации. Соответственно, в скриптах с видео в этом случае заменяйте путь к нему и метод его декодирования.

Часть 1. Замена звуковой дорожки.

Рациональнее заменять звуковую дорожку с самого начала, еще до пережатия видео. Почему? Потому что от успешности замены зависит необходимость пережимать звук, и, соответственно, расчетный битрейт видео. Первое, что нужно сделать, проверить, вдруг RUS чудесным образом сам по себе синхронизован с видео. Cоздаем из оригинальных TS d2v-проект с именем video.d2v, в результате чего, кстати, заодно демукснется ENG. Теперь пишем незамысловатый avs-скрипт с именем RUS.avs:

mpeg2source("video.d2v") 

Открываем в Classic Media Player'e RUS.avs и смотрим. Вернее слушаем. Синхронно? Если да, вам очень повезло, дальше можете не читать.

Если нет, открываем Настройки -> Аудиопереключатель. Ставим галку "смещение звука (в мс.)" и начинаем подбирать сдвиг. После каждого изменения параметра нужно перезапустить файл. Сначала нужно добиться синхронизации в самом начале фильма. Выберите какую-нибудь характерную сцену (выстрел, хлопок двери, или монолог героя крупным планом) и подбирайте нужный сдвиг. Начало синхронизовали? Отлично! Теперь смотрите, что творится в конце фильма. Если все ОК, вам сюда. Если конец рассинхронизован - придется сжать/растянуть RUS на некоторую величину.

Запоминаем величину задержки, которую ввели в Classic Media Player'e. Пусть она будет D1 мс. Теперь переписываем наш скрипт:

video = mpeg2source("video.d2v") #вводим видео
audio = NicAC3Source("rus.ac3").delayAudio(D1/1000) #вводим звук, смещаем его на D1 в секундах.
AudioDub(video, audio) #сводим звук и видео.

Сохраняем его как %только не RUS, и не ENG%.avs, чтобы не мешался старый звук. Открываем %только не RUS, и не ENG%.avs и убираем задержку в Classic Media Player. Начало, теоретически, должно быть в синхроне, проверяем, так ли это.

Теперь по совершенно аналогичному алгоритму синхронизируем конец фильма. Это нужно лишь для оценки рассинхрона, так что будет достаточно точности +- секунда. Синхронизовали конец, и запоминили коррекционный свиг как D2 ms. Пусть длительность RUS = L1 ms. Значит, необходимая длительность RUS_target = L1 + D2 (тут D2 может быть и отрицательным). Тогда, RUS_target "длиннее" RUS.avs в (L1+D2)/L1 раз. Или, в процентах, 100*(L1+D2)/L1. Можете посчитать это число в столбик, можете на калькуляторе, а можете вообще его не считать а записать в скрит в виде формулы - пусть Avisynth считает :):

video = mpeg2source("video.d2v") #вводим видео
audio = NicAC3Source("rus.ac3").delayAudio(D1/1000).TimeStretch(tempo=100*(L1+D2)/L1) \\
#вводим звук, смещаем его на D1 в секундах, растягиваем/сжимаем по времени
AudioDub(video, audio) #сводим звук и видео.

Замечательно. Собираем волю в кулак и в очередной раз тестируем, открывая новый скрипт (не забудьте убрать задержку в Classic Media Player). Конец из-за мелких погрешностей будет чуть-чуть в рассинхроне. Подгоните конец с точностью до 1 сек., варьируя коэффициент TimeStretch с шагом примерно в 0.05%. То есть tempo=100.05*...; tempo=100.1*...; tempo=100.15*...; и т.д. или в обратную сторону: tempo=99.95*...; и т.д.

Подогнали? Очень хорошо. Начало в синхроне, и конец почти в синхроне. Что осталось проверить? Правильно, середину. Прокликайте весь фильм. Если рассинхрон везде небольшой (не больше, чем в конце), и ближе к началу уменьшается, все идет по плану. Добейтесь окончательной синхронизации конца, варьируя параметр tempo с уменьшающимися шажками до тех пор, пока ошибка синхронизации не снизится до 50-100 ms в зависимости от вашего терпения. Я замечаю рассинхрон в 100 ms, а начиная с 200 ms он меня раздражает. Так что уж постарайтесь не схалтурить на заключительном этапе. Не схалтурив, отправляйтесь сюда.

Ну ладно, а что делать, если начало в синхроне, и конец в синхроне, а в середине творится какая-то чехарда? Дайте-ка подумать... Пойдем от простого к сложному. Простое - это если RUS вы взяли из чъего-то многодискового рипа, в котором на этапе кодинга было совершено некое преборазование частоты кадров/длительности. В таком случае вам не нужен RUS одним файлом, обратитесь к первоисточнику и возьмите N оригинальных ac3-файлов. Пусть для примера N=2, а файлы называются rus1.ac3 и rus2.ac3. Создаем такой скрипт:

video = mpeg2source("video.d2v") #вводим видео
audio = NicAC3Source("rus1.ac3").delayAudio(delay1).TimeStretch(tempo=temp1) \\
+ NicAC3Source("rus1.ac3").delayAudio(delay2).TimeStretch(tempo=temp2) \\
#вводим 1 файл, смещаем его, растягиваем/сжимаем по времени в разах, \\
затем добавляем второй файл с аналогичными преобразованем.
AudioDub(video, audio) #сводим звук и видео.

где delayN - задержка rusN в секундах, tempN - изменение длительности rusN в %. Алгоритм подбора этих параметров аналогичен описанному, но точки синхронизации придется находить еще и в момент смены первого и второго звуковых файлов. Суеты конечно больше, но все же этот способ лучше, чем следующий.

А следующий вот какой. Если вы получили перевод из надежного источника, и в его качестве не приходится сомневаться, значит либо косяк в оригинальном звуке, либо это перевод для другой версии фильма. Понять, в чем же дело без хирургического вмешательства не получится. "Резать к чертовой матери, не дожидаясь перитонитов!". Резать будем вот таким скриптом:

NicAC3Source("rus.ac3").delayAudio(D1/1000).GetChannel(3) \\
#выделяем только фронтальный канал из синхронизованного по началу RUS'a.

Это RUS у нас как мы договорились нормальный, а ENG.ac3 со спутника в TS хватали, и потому там полно ошибок. Его нужно сначала полечить чудной тулзой DelayCut  (назовем коррекцию ENG'.ac3), после чего он возможно будет проигрываться через Nic. А может и не будет. Если будет, то:

NicAC3Source("ENG'.ac3").GetChannel(3) #выделяем только фронтальный канал из скорректированного оригинала через Nic.
DirectShowSource("ENG'.ac3").GetChannel(3) \\
#выделяем только фронтальный канал из скорректированного оригинала через DirectShow.

В последнем случае не забудьте правильно настроть свой DirectShow ac3-декодер. Чтобы на 6ть каналов выводил, и без всяких глупостей вроде нормализации и т.д. Настроили? Протестили скриптик в Classic Media Player'e? Отлично! Скачиваем вторую чудную тулзу BeHappy  или ее авторскую сборку . Вы должно быть впадете в экстаз услышав, что эта утилитка умеет гнать .avs скрипты в stdin внешних кодеров! Берем два последних скрипта и через BeHappy выгоняем фронтальные каналы из RUS и ENG' в wav'ы. Получим, к примеру, файлы rus_front.wav и eng_front.wav. Берем эти файлики и засовываем в CoolEdit 2.x или Adobe Audition 1/2 в режиме мультитрэк. Если до этого все было выполнено правильно, начало обеих аудиодорожек будет визуально синхронизовано. Предстоит немного поплясать с бубном. Используя сдвиги, растяжение (Time -> Stretch) и разрезы постарайтесь добиться синхронизации по всему фильму. Обратите внимание, есть ли какая-нибудь закономерность в изменении синхронизации между каналами. Например, если при синхронных начале и конце в середине вы увидите что-нибудь вроде этого:

Рассинхронизация
Рассинхронизация

хотя бы дважды, можете смело забивать на RUS. Это перевод от чуть другой версии фильма, и нормально синхронизовать его слишком трудоемко. Учитите, что все произведенные вами с центральным каналом действия придется потом либо запрограммировать в .avs-скрипте, либо совершить с остальными пятью каналами вручную _абсолютно_ идентично. Если на этом этапе вас потиг успех (что правда довольно маловероятно), сводите все 6-mono wav'-файлов таким скриптом:

a1=WAVSource("ch1.wav") #первый канал
a2=WAVSource("ch2.wav") #второй канал
a3=WAVSource("ch3.wav") #третий канал
a4=WAVSource("ch4.wav") #четвертый канал
a5=WAVSource("ch5.wav") #пятый канал
a6=WAVSource("ch6.wav") #шестой канал
MergeChannels(a1,a2,a3,a4,a5,a6) #микшируем все каналы

или кодируйте запрограммированный avs-скрипт. Если успех обошел вас стороной, читайте дальше.

Часть 2. Наложение перевода.

Судя по всему, не судьба вам заменить звуковую дорожку. Тогда попробуем наложить закадровый перевод. Обычно это одно-двуголосый mono mp3-файл посредственного качества с кривой частотой дискретизации. Назовем его trans.mp3. Создаем следующий .avs скрипт:

audio = NicAC3Source("ENG'.ac3") #декодируем ENG
trans = NicMPG123Source("trans.mp3").resampleaudio(48000).delayAudio(T1).TimeStretch(tempo=T2) \\
#декодируем перевод, ресемплируем в нужную частоту, сдвигаем на T1 секунд и растягиваем в T2 раз
a1=GetChannel(audio,1) #достаем 1й канал
a2=GetChannel(audio,2) #достаем 2й канал
a3=MixAudio(GetChannel(audio,3),trans) \\
#достаем 3й (центральный) канал и накладываем на него перевод
a4=GetChannel(audio,4) #достаем 4й канал
a5=GetChannel(audio,5) #достаем 5й канал
a6=GetChannel(audio,6) #достаем 6й канал
MergeChannels(a1,a2,a3,a4,a5,a6) #микшируем все каналы заново

По вкусу можно еще и обработать trans.mp3 разными фильтрами, наример AmplifydB() или другими см. справку к Аvisynth. Как вы уже догадались, дополнительные параметры надо вводить через точку. "Предпрослушл" будет работать в реальном времени, без рендеринга, так что вы без труда подберете подходящие параметры T1 и T2.

Кстати, так как вы уже имеете чудный файлик eng_front.wav, ничто не мешает смешать его с trans.mp3 в вашем любимом звуковом редакторе, заодно по-возможности увеличив качество звука перевода. В таком случае вам понадобится скрипт, который заменит в ENG центральный канал на ваш новый микс front_transed.wav:

audio = NicAC3Source("ENG'.ac3") #декодируем ENG
a1=GetChannel(audio,1) #достаем 1й канал
a2=GetChannel(audio,2) #достаем 2й канал
a3=WAVSource("front_transed.wav") #третьим каналом будет внешний файл
a4=GetChannel(audio,4) #достаем 4й канал
a5=GetChannel(audio,5) #достаем 5й канал
a6=GetChannel(audio,6) #достаем 6й канал
MergeChannels(a1,a2,a3,a4,a5,a6) #микшируем все каналы заново

Добившись желаемого результата, сжимайте получившийся скрипт.

Часть 3. Ввод субтитров.

Если ничего не помогло, и перевод также не желает ложится в синхроне, попробуйте подцепить к видео русские субтитры. Досконально расписывать как это делать мне не интересно, так что лучше я остановлюсь на двух характерных примерах.

Пример 1 Есть русские субтитры для именно для этого фильма, но их нужно сдвинуть/сжать/растянуть.

Берем замечательную утилитку Subtitle Workshop , загружаем в нее наши титры, открываем заготовленный файлик и avi-превьюшку будущего рипа, которую на этом этапе все же придется сделать. Тыкаем по разным менюшкам и в какой-то момент понимаем, что в Subtitle Workshop встроены уже все необходимые нам функции - и сдвиг, и растяжение и превью даже есть. Что делать дальше, думаю, понятно :)

Пример 2 Есть синхронизованные субтитры на %не русском языке, который вы знаете% именно для этого фильма, и есть некий их несинхронизованный русский аналог.

Будем считать, что вы знаете английский. Открываете английские субтитры в Subtitle Workshop и сохраняете их в формате Turbo Titler (файл eng.tts, к примеру). Суете этот файл в Excel, указав "формат данных - с разделителями" и установив в качестве разделителя английскую "P". Что мы видим? Таймкоды и текст хранятся в соседний ячейках! Проводим аналогичную операцию для русских субтитров, после чего копируем столбец русского текста и вставляем его рядом с английским. Теперь (вы ведь знаете английский!) быстро пробегаем глазами два столбца следя за тем, чтобы в каждой строчке находились соответствующие друг другу титры. Скорее всего, предыдущий титровщик схалтурил и перевел не все титры, - можно исправить ошибки перевода или самому чего-нибудь напереводить. Закончив, как вы уже догадались, замените английские титры русскими и сохраните файл как "csv-файл c разделителями точка с запитой". Откройте csv-файл в блокноте и замените все ";" на "P", после чего смените расширение файла на .tts, снова откройте в Subtitle Workshop и сохраните в нужном вам формате.

Синхронизация субтитров займет у вас минут 30-40, а в итоге получите отличный перевод. В принице, данный метод применим ко многим алфавитным европейским языкам, даже если вы их не знаете. А вот с восточными уже так просто не разобраться.

Часть 4. Что же со всем этим делать?

Это зависит от того, какого типа преобразование вы произвели. Рассмотрим варианты.

Вариант 1. Вам повезло и все ограничилось простым сдвигом во времени. В этом случае возможно оставить оригинальный звук без перекодировки. Рекомендуется так и делать, если конечно битрейт звука не слишком придавит битрейт видео. Если вы все же решите пережать звук в аас, см. вариант 2.

Маленький FAQ:

Как можно сдвинуть AC3 или DTS звук по времени назад без перекодировки?

Обрезать начало с помощью DelayCut .

Как можно сдвинуть AC3 или DTS звук по времени вперед без перекодировки?

Ввести задержку с помощью DelayCut .

Вариант 2. Вам неповезло :( Пришлось делать сложное преобразование с растяжением во времени, наложением перевода и т.д. Ну или вы делаете рип на однослойный 4.37 ГБ DVD, при котором оставлять широкобитрейтный DTS звук нерационально.

Так как вся обработка, описанная в данной статье, поизводилась на основе Avisynth, в какой бы момент времени вы не достигли положительного результата, на руках у вас оказался рабочий .avs-скрипт, звук в котором синхронен с видео. Откройте этот скрипт и отключите все, кроме звука. Например, так:

#video = mpeg2source("video.d2v")
#audio =
NicAC3Source("rus.ac3").delayAudio(D1/1000).TimeStretch(tempo=100*(L1+D2)/L1)
#AudioDub(video, audio)

Теперь скачайте этот пак  и пережимайте .avs скрипт в mp4 Неровским энкодером.

Ура! Теперь можно кодировать видео.

Подробнее об Avisynth читайте на сайте Александра Балахнина .




Благодарю RBF и KPEMEHb за непреднамеренную помощь в подготовке материала.

10 декабря 2006 года.

Оставить комментарий 


Ваше имя:
->