Несмотря на то, что видеокассеты уже давно вышли из повседневной жизни, услуги по их оцифровке продолжают пользоваться спросом. Кассеты с любительскими записями есть почти в каждой семье, и рано или поздно их нужно перевести в цифру, ведь срок жизни магнитной ленты ограничен.
Зимой 2025 года в мои руки попало 35 кассет формата VHS и VHS-C из семейного архива, и встала задача по их оцифровке. С учетом того, что на каждой кассете было записано приблизительно по 60 минут видео, а средний ценник услуг по захвату сейчас составляет 400 рублей в час, общая стоимость конвертации составила бы около 14 тысяч рублей. Эта сумма показалась мне слишком большой, и было решено сделать все самостоятельно. В данной статье я хочу рассказать об относительно новом методе оцифровки видеокассет, на котором я остановился, и сравнить его с классическими подходами.
Оцифровка видео — это сложно
Оцифровка данных с аналоговых носителей — непростая задача. В случае с видео она осложняется тем, что приходится работать с очень большим потоком информации. Если на аудиокассете ширина полосы пропускания составляет 12-16кГц, то на кассете стандарта VHS — около 5МГц, то есть в 300 раз больше. Это накладывает жесткие требования на качество оборудования и точность его работы. Кроме того, видеосигнал имеет сложную структуру и рассчитан на телевизор с кинескопом, который рисует кадр строчку за строчкой. А значит, нужно как-то интерпретировать для конвертации в цифровой файл.
Из-за этих и многих других сложностей для качественной оцифровки видео обычно требуется дорогое оборудование, настроенное правильным образом. Споры о том, какой магнитофон, карта захвата и программа дают лучший результат, не утихают по сей день.

Популярные способы оцифровки видео
Методы оцифровки видео можно условно поделить на две категории:
Любительский — используется дешевая внешняя USB карта захвата, например AVerMedia DVD EZMaker 7, и бытовой VHS магнитофон. Стоимость такого комплекта составляет приблизительно 9 тысяч рублей при покупке с рук;
Профессиональный — используется дорогая внешняя или внутренняя карта захвата, например Canopus ADVC-300, и S-VHS магнитофон с функцией Time Based Correction (TBC), ведь серьезные карты захвата очень требовательны к стабильности сигнала, и при работе в паре с бытовым магнитофоном гарантировано будут потери кадров. Стоимость такого комплекта начинается с 35 тысяч рублей при покупке с рук.
Конечно, это упрощенная классификация, в которой не учтены экзотические походы. Например, в качестве карты захвата можно использовать старую камеру стандарта Digital8, подключив ее к компьютеру по FireWire.
Что такое VHS-Decode?

VHS-Decode — это программа, создатели которой обещают результат профессионального качества при минимальных затратах на оборудование. Предлагается использовать бытовой магнитофон, но брать сигнал не с видеовыхода, а с предусилителя магнитных головок, после чего оцифровывать его с высокой частотой простым АЦП. Последующая работа по интерпретации данных выполняется на компьютере. Таким образом, программа заменяет собой схемотехнику магнитофона и карты захвата.
Не смотря на название, VHS-Decode позволяет оцифровывать следующие форматы аналогового видео:
VHS (NTSC, NTSC-J, PAL, PAL-M);
SVHS (NTSC, NTSC-J, PAL, PAL-M);
U-Matic Low Band (PAL, NTSC);
U-Matic High Band (PAL);
Betamax (PAL, NTSC);
SuperBeta (NTSC);
Video8 и Hi8 (PAL, NTSC);
1" Type C (SMPTE Type C) (PAL, NTSC);
1" Type B (SMPTE Type B) (PAL, NTSC);
EIAJ (PAL);
Philips VCR и Philips VCR "LP" (PAL).
Проект активно развивается, и возможно этот список будет расширен в будущем. Также, важно заметить, что VHS-Decode является форком проекта LD-Decode, который нацелен на работу с LaserDisk.
Подготовка к оцифровке с помощью VHS-Decode
Для оцифровки кассет с помощью VHS-Decode вам потребуется следующее оборудование:
Видеомагнитофон формата VHS. Подойдет любой исправный аппарат, но, если есть выбор, лучше взять машину от Panasonic или JVC с поддержкой Hi-Fi. Стоимость такого магнитофона на Авито от 2 до 5 тысяч рублей;
Аудиокарта для записи звука. Подойдет любой приличный вариант с поддержкой захвата 24bit 48kHz. Стоимость такой карты на Авито начинается от 4 тысяч рублей;
Кассета формата VHS с записанным на нее фильмом длиной не менее получаса и цифровая версия этого фильма. Они пригодятся нам при калибровке скрипта для синхронизации аудио и видео. Кассету можно найти на дальней полке шкафа или на Авито за несколько сотен рублей;
Высокочастотный кабель длиной не более метра с импедансом 50Ом и высокочастотными разъемами мама-папа на концах. Авторы проекта рекомендуют разъемы BNC, однако ниже я объясню, почему лучше остановиться на разъемах SMA. Такой кабель можно найти на Ozon за 600 рублей;
Тюбик нейтрального эпоксидного клея-пластилина или силиконового герметика. Можно найти где угодно приблизительно за 300 рублей;
Керамический конденсатор номиналом от 3.3 до 10мкФ. Можно найти где угодно за несколько рублей;
Карта видеозахвата формата PCIe 1x на основе чипа Conexant CX2388x, как на картинке ниже. Такую карточку можно найти по запросу «карта видеозахвата 640x480» на Ozon или Aliexpress. Стоить она будет около 1700 рублей.

Как говорилось выше, мы будем подключаться к предусилителю магнитных головок. Для этого нужно вскрыть корпус магнитофона и найти на плате контакт, предусмотренный для проверки сигнала при ремонте устройства. В зависимости от производителя он может быть подписан по-разному. Например, в моем LG L494 используется обозначение “RF”. Более подробно о том, как найти площадку и подключиться к ней, написано в вики VHS-Decode.
Необходимо отрезать кусок высокочастотного кабеля и припаять его к найденному контакту через конденсатор. Для удобства в корпусе магнитофона можно проделать дополнительное отверстие и вывести кабель через него, нанеся на место стыка силиконовый герметик или эпоксидную смолу для фиксации.
Описанные операции могут показаться сложными, однако занимают не более получаса и безопасны для магнитофона.
Карту видеозахвата также необходимо доработать. Во-первых, требуется удалить разъем RCA и припаять к освободившимся контактным площадкам ответную часть кабеля. При этом суммарная длина этого куска и того, что был установлен в магнитофон, не должна превышать 50 сантиметров. Во-вторых, для снижения уровня шума при оцифровке рекомендуется удалить конденсатор C31. Более подробно модификации карты описаны здесь. Эти манипуляции тоже занимают не более получаса.
Теперь, можно установить карту в компьютер. Однако, в случае использования разъема BNC вы не сможете это сделать, так как он шире прорези в корпусе. Именно поэтому лучше использовать более мелкий разъем SMA.
Осталось установить необходимые программы:
Драйвер АЦП под Ubuntu 22.04 или Windows. Второй имеет статус экспериментального, однако работает без нареканий;
Набор утилит из проекта VHS-Decode для Windows, MacOS или Linux. На момент написания статьи актуальна версия 0.3.5;
Консольная программа SoX для захвата звука.
Я работаю под Windows, однако большая часть того, что будет сказано далее, справедливо и для Linux версий программ.
Процесс оцифровки
Процесс оцифровки состоит из семи шагов:
Настройка BIOS и перевод Windows в тестовый режим;
Настройка АЦП;
Захват сигнала с магнитофона и сохранение его в файл (capture);
Выделение из сырых данных полезной информации (decode);
Экспорт видео (export);
Синхронизация аудио и видео (align);
Постобработка.
В этом и двух следующих разделах будет дано подробное описание каждого из них. Если вам это не интересно, вы можете перейти к разделу “Сравнение с классическими методами”.
Для корректной работы драйвера АЦП необходимо отключить опцию Secure Boot в BIOS. Под Windows требуется также перевести ОС в тестовый режим, выполнив команду
bcdedit -set testsigning on
и перезагрузив компьютер. После того, как вы захватили все кассеты, можно вернуть ОС в обычный режим с помощью команды
bcdedit -set testsigning off
и повторной перезагрузки.
Настройка АЦП выполняется через специальные команды драйвера. При этом необходимо указать следующие параметры:
Разъем, с которого будет захватываться сигнал (vmux);
Применять ли ко входному сигналу дополнительное усиление на 6дБ (sixdb);
Уровень цифрового усиления входного сигнала (level);
Центрирование значений при оцифровке (center_offset).
Мы используем ту площадку АЦП, где изначально стоял разъем RCA, поэтому в качестве первого значения необходимо указать единицу. Дополнительное усиление я рекомендую выключить, так как оно вносит шумы в сигнал. Оставшиеся значения зависят от модели магнитофона и драйвер может подобрать их автоматически. Для этого нужно запустить на магнитофоне воспроизведение и выполнить команду драйвера leveladj. При перезагрузке настройки сбрасываются, поэтому чтобы не восстанавливать их вручную, можно подготовить bat файл. Мой скрипт выглядит следующим образом
prepare.bat
:: вывести список доступных АЦП (в системе их может быть до 255)
"C:\Program Files\cxadc\tools\cxadc-win-tool.exe" scan
:: настроить первый АЦП
"C:\Program Files\cxadc\tools\cxadc-win-tool.exe" set \\.\cxadc0 vmux 1
"C:\Program Files\cxadc\tools\cxadc-win-tool.exe" set \\.\cxadc0 sixdb 0
:: эти два параметра у вас могут отличаться
"C:\Program Files\cxadc\tools\cxadc-win-tool.exe" set \\.\cxadc0 level 31
"C:\Program Files\cxadc\tools\cxadc-win-tool.exe" set \\.\cxadc0 center_offset 8
:: проверить, что настройки сохранились
"C:\Program Files\cxadc\tools\cxadc-win-tool.exe" get \\.\cxadc0
pause
Подробнее о настройке драйвера под Windows можно прочитать здесь, а описание Linux версии приведено здесь.
Теперь мы готовы к оцифровке сигнала. Подключим самодельный кабель, идущий из магнитофона, к АЦП, а красный и белый RCA разъемы к аудио карте. Наконец, запустим такой скрипт
capture.bat
:: запустить запись аудио и видео одновременно на X секунд
start /high "" cmd /c ""C:\Program Files (x86)\sox-14-4-2\sox.exe" -t waveaudio 0 -e signed-integer -b 24 -c 2 -r 48000 "audio.wav" trim 0 X"
start /high "" cmd /c ""C:\Program Files\cxadc\tools\cxadc-win-tool.exe" capture \\.\cxadc0 capture.u8" & timeout /t X /nobreak > nul & taskkill /im cxadc-win-tool.exe /f
и нажмем клавишу Play на магнитофоне. В директории, в которой находится скрипт, появятся файлы audio.wav и capture.u8, в которые будет сохраняться поток аудио и видео соответственно. Запись будет продолжаться в течение X секунд, если вы не прервете ее досрочно. При этом магнитофон можно подключить к телевизору, чтобы контролировать процесс.
По завершении захвата требуется запустить следующий скрипт, сохраняющий время, когда началась запись аудио и видео в файл time.txt. Эта информация пригодится далее для сведения дорожек.
time.bat
echo "Начало захвата видео" >> time.txt
powershell -command "(Get-Item "capture.u8").CreationTime.ToString(\"HH:mm:ss.fff\")" >> time.txt
echo "Начало захвата аудио" >> time.txt
powershell -command "(Get-Item "audio.wav").CreationTime.ToString(\"HH:mm:ss.fff\")" >> time.txt
echo "Смещение начала аудио относительно начала видео (миллисекунд). Если больше 0, то нужно добавить тишину, а если меньше 0 — отрезать начало" >> time.txt
powershell -command "((Get-Item "audio.wav").CreationTime - (Get-Item "capture.u8").CreationTime).TotalMilliseconds" >> time.txt
Теперь мы можем расшифровать сигнал и экспортировать его в видео. Для этого запустим команды
decode pal.bat
:: декодировать сигнал формата PAL с кассеты формата SP
"C:\Program Files\vhs-decode\decode.exe" vhs -p -t 3 --tf vhs --cxadc --recheck_phase --ire0_adjust capture.u8 decoded
:: экспортировать в видео формата FFV1 с чересстрочной разверткой
:: "C:\Program Files\vhs-decode\tbc-video-export.exe" decoded.tbc
pause
Первая запустит длительный процесс расшифровки видео. При этом будет создан ряд файлов с названием decoded и разными расширениями. Далее, будет сформирован файл decoded.mkv с результатом. У утилиты decode есть великое множество аргументов, описанных здесь. Приведенный выше набор параметров кажется мне оптимальным на данный момент (к сожалению, аргумент --chroma_trap сейчас сломан). Программа tbc-video-export тоже предоставляет широкий набор возможностей. Например, можно экспортировать видео в более привычный формат со сжатием h.265 и прогрессивной разверткой. При этом для устранения чересстрочности будет применяться относительно простой алгоритм bwdif.
Наконец, нужно синхронизировать видео с аудиодорожкой с помощью
sync audio.bat
:: добавить X секунд тишины в начало аудио (X отличается от раза к разу)
"C:\Program Files (x86)\sox-14-4-2\sox.exe" audio.wav padded_audio.wav pad X
:: отрезать первые Y секунд аудио (Y отличается от раза к разу)
"C:\Program Files (x86)\sox-14-4-2\sox.exe" audio.wav padded_audio.wav trim Y
:: выровнять аудио, приняв частоту дискретизации аудиодорожки за Z (Z нужно найти один раз)
"C:\Program Files\vhs-decode\ffmpeg.exe" -i padded_audio.wav -filter_complex "channelmap=map=FL-FL|FR-FR" -f s24le -ac 2 - | "C:\Program Files\vhs-decode\AutoAudioAlign.exe" stream-align --sample-size-bytes 6 --stream-sample-rate-hz Z --json decoded.tbc.json --rf-video-sample-rate-hz 40000000 | "C:\Program Files\vhs-decode\ffmpeg.exe" -f s24le -ar Z -ac 2 -i - -af aresample=48000 -sample_fmt s32 sync_audio.wav
pause
Таким образом, мы получим файл sync_audio.wav со звуком для нашего видео. Про параметры X, Y и Z из этого скрипта будет рассказано в следующем разделе.
После оцифровки первой кассеты рекомендую открыть файлы decoded.tbc и decoded.tbc.json в программе ld-analyze, входящей в состав VHS-Decode и проверить отношение сигнала к шуму (SNR). Эта величина должна быть не менее 30дБ.

Подробнее о сведении аудио и видео
Сведение аудио и видео дорожек не так очевидно, как может показаться на первый взгляд. На это есть три причины:
Захват аудио и видео начинается не одновременно. Эта разница может достигать десятых долей секунды в ту или иную сторону;
При работе с сырым сигналом утилита decode выравнивает поля кадра так, чтобы их частота составляла ровно 50Гц (речь идет о стандарте PAL). Требуется передвинуть фрагменты аудио вслед за ними;
Мы считаем, что частота тактового генератора в карте захвата видео равняется 28636363Гц, а в карте захвата аудио — 48000Гц. Однако, на практике всегда существует погрешность на сотые доли процента из-за которой оцифрованное аудио будет воспроизводится чуть быстрее или чуть медленнее оцифрованного видео. Таким образом, за час может набегать до 5 секунд расхождения.
Первая проблема решается проще всего. Один из скриптов, приведенных выше, сформировал файл time.txt, в котором указано, на сколько миллисекунд раньше или позже был создан файл audio.wav относительно capture.u8. Эта величина может служить первым приближением, чтобы решить, сколько миллисекунд добавить к аудио или отрезать от него, чтобы выровнять дорожки. Большей точности можно добиться, оценив эту величину самостоятельно в видеоредакторе. При этом важно смотреть только на самое начало записи. Смещение — это случайная величина, поэтому так придется делать каждый раз при оцифровке очередной кассеты.

Вторую проблему за нас решит утилита AutoAudioAlign, входящая в состав VHS-Decode. Она подгонит звук под видео. Однако, для правильной работы этой программы нужно решить третью проблему. Тут то и пригодится кассета с фильмом, для которого у нас цифровая версия с идеально синхронизированными дорожками. Выполним следующие действия:
Оцифруем не менее получаса фильма с кассеты. Получим файлы decoded.mkv и audio.wav;
Выровняем начало audio.wav, методом, описанным выше. Назовем этот файл padded_audio.wav (смотрите скрипт sync audio.bat);
В видеоредакторе разместим параллельно видеодорожку с кассеты и цифровую версию фильма, совместим их с точностью до кадра;
Для начала будем считать, что аудиокарта работает с частотой Z=48000Гц;
Запустим утилиту AutoAudioAlign с текущим значением Z. Назовем получившийся файл sync_audio.wav (смотрите скрипт sync audio.bat);
Добавим на временную шкалу видеоредактора аудиодорожку sync_audio.wav, совместив ее начало с началом decoded.mkv;
Оценим, торопится ли sync_audio.wav относительно дорожки с цифровой версии фильма или отстает от нее;
Если sync_audio.wav торопится, нужно уменьшить величину Z на несколько Гц и вернуться к шагу 5;
Если sync_audio.wav отстает, нужно увеличить величину Z на несколько Гц и вернуться к шагу 5;
Будем уточнять Z до тех пор, пока не добьемся приемлемой точности.

Таким образом, с помощью эталона мы подбираем такую частоту Z, при которой утилита AutoAudioAlign будет выдывать правильный результат. Величину Z нужно найти один раз, после чего ее можно жестко прописать в скрипте sync audio.bat. Например, в моем случае она равна 47989Гц и погрешность не превышает 0.03 секунды на 30 минут видео.
Постобработка
Теперь, когда у нас есть видеодорожка decoded.mkv и аудиодорожка sync_audio.wav, мы можем объединить их в любом видеоредакторе. Дальнейшая постобработка — дело вкуса, однако я рекомендую выполнить следующие шаги:
Устранение чересстрочности — на данный момент мы имеем видео с чересстрочной разверткой, однако для корректного отображения на современных мониторах необходимо перейти к прогрессивной. Есть много методов устранения чересстрочности, но самым продвинутым считается QTGMC. Я пользуюсь реализацией этого алгоритма, входящей в состав StaxRip;

Временное шумоподавление — VHS-Decode экспортирует именно то, что записано на кассете. В результате получается шумное во времени видео. Если применить к нему фильтр, который удалит помехи с учетом соседних кадров, это значительно улучшит результат;

Коррекция кривой яркости — VHS-Decode экспортирует видео с диапазоном яркости 16-235. Это телевизионный стандарт, который может неправильно отображаться в некоторых видеоплеерах. Поэтому зачастую требуется исправить контраст, растянув яркость на полный диапазон 0-255.

Вывод о процессе оцифровки
Процесс оцифровки, описанный выше, может показаться сложным, однако после того, как вы откалибруете скрипт для синхронизации аудио, все будет сводиться к простым шагам:
Перевести Windows в тестовый режим;
Подключить магнитофон к компьютеру;
Последовательно запустить скрипты prepare.bat и capture.bat;
Запустить воспроизведение на магнитофоне и дождаться конца кассеты;
Остановить скрипт capture.bat;
Последовательно запустить скрипты time.bat и decode pal.bat;
Оценить, сколько миллисекунд нужно убрать или добавить в начало аудиодорожки, основываясь на подсказке из файла time.txt и том, что вы видите в видеоредакторе. Прописать эту величину в скрипт sync audio.bat
Запустить скрипт sync audio.bat;
Объединить дорожки в видеоредакторе;
Выполнить устранение чересстрочности, шумоподавление и коррекцию кривой в видеоредакторе (опционально).
Сравнение с классическими методами
Наконец, посмотрим, на что способен VHS‑Decode. В сравнении будут участвовать следующие подходы:
Любительский — магнитофон LG L494 → дешевый конвертер AV2HDMI → дешевая карта захвата для компьютера → запись через OBS. Стоимость такого комплекта без учета кабелей около 4 тысяч рублей;
Профессиональный — магнитофон Panasonic NV-HS 860 (TBC включено, а 3D DNR - нет) → передача по S-Video → карта захвата Canopus ADVC-300 → запись через Pinnacle Studio → устранение чересстрочности с помощью QTGMC → экспорт в FFV1. Стоимость такого комплекта без учета кабелей около 40 тысяч рублей;
Новый — магнитофон LG L494 → карта захвата видео на чипе Conexant CX23883-39 и карта захвата аудио Roland Rubix 22 → драйвер для Windows → обработка с помощью VHS-Decode 0.3.5 → устранение чересстрочности с помощью QTGMC → экспорт в FFV1 → временное шумоподавление и коррекция кривой в DaVinci Resolve → экспорт в FFV1. Стоимость такого комплекта без учета аудиокарты около 6 тысяч рублей. С минимально приемлемой аудиокартой комплект стоил бы около 10 тысяч рублей.
Сначала сравним качество изображения. На свежую кассету TDK был записан фильм Звонок 2002 года. Запись выполнена с цифрового исходника с разрешением 720x480 на магнитофоне Panasonic NV-HS830. Оцифруем первые 5 минут фильма разными методами и будем оценивать, насколько результат близок к оригиналу.
Для удобства я также подготовил стоп-кадры.
Кадр 1




Кадр 2




Кадр 3




Кадр 4




AV2HDMI, очевидно, занимает третье место. Причем проблема не в магнитофоне, так как даже в паре с продвинутым Panasonic NV-HS 820 качество не сильно лучше.
Разница между Canopus ADVC-300 и VHS-Decode не так очевидна, но она есть. Обратите внимание на цвет лица героини на втором кадре. Там, где классический метод увел все в зелень, VHS-Decode смог восстановить оттенки красного. Глядя на остальные кадры, мы также можем заметить это различие. Таким образом, VHS-Decode обеспечивает лучшую цветопередачу и уровень детализации.
Теперь сравним стабильность изображения. Возьмем кассету Fujifilm формата VHS-C, выпущенную в 1994 году, с записью 1998 года. Лента сохранилась плохо, и на ней есть проблемные места. Посмотрим, на сколько стабильна картинка при оцифровке разными способами.
Можно видеть, что при использовании VHS-Decode искажения минимальны. Однако, удивляет то, на сколько отличаются цвета при оцифровке разными методами.
Возможные аппаратные доработки
Я описал базовый набор оборудования для VHS-Decode. Как показано выше, этого достаточно для получения хорошего результата при работе с кассетами формата VHS. Однако существует ряд модификаций, которые могут улучшить качество оцифровки:
Установка усилителя между магнитофоном и картой захвата видео — сигнал, идущий от предусилителя магнитных головок, очень слаб, и его приходится усиливать перед оцифровкой. В карте АЦП есть встроенный усилитель, однако он вносит помехи. Предварительное усиление сигнала перед подачей в карту может улучшить отношение сигнала к шуму. Кроме того, это позволит увеличить длину кабеля, идущего от магнитофона к компьютеру;
Увеличение частоты АЦП — изначально карта захвата видео работает на частоте 28.6МГц, однако, если заменить кварцевый резонатор, можно разогнать ее до 40МГц и выше. При этом микросхемы будут выделять больше тепла, а значит на них желательно установить радиатор. Данная модификация может повысить отношение сигнала к шуму, а также улучшить качество оцифровки форматов, более сложных чем VHS, например S-VHS;
Установка второй карты захвата для оцифровки Hi-Fi аудио — зачастую кассеты формата VHS содержат Hi-Fi звук. Такое аудио кодируется схожим образом, что и видео и считывается отдельной головкой. Тогда можно припаять к магнитофону еще один провод и установить в компьютер еще одну карту захвата, чтобы оцифровывать в высоком качестве не только видео, но и звук. В VHS-Decode есть ряд утилит для декодирования аудио;
Тактирование карт захвата одним генератором — развитие предыдущей модификации. Как говорилось в одном из прошлых разделов, частота любого тактового генератора всегда немного отличается от теоретического значения. Из-за этого оцифрованная аудиодорожка будет воспроизводиться чуть быстрее или чуть медленнее оцифрованного видео, и за час может набегать до 5 секунд расхождения. Мы научились компенсировать этот эффект с помощью скрипта sync audio.bat, но, если хочется решить проблему окончательно, можно установить общий тактовый генератор для двух карт захвата.
Недостатки VHS-Decode
Помимо преимуществ у VHS-Decode есть два недостатка, с которыми вы неизбежно столкнетесь, если решите попробовать этот метод.
Во-первых, сырые данные, полученные с кассеты, занимают много места на диске. Так, для часа видео файл capture.u8 будет весить около 96ГБ, decoded.tbc и decoded_chroma.tbc — по 117ГБ, а decoded.mkv - еще 43ГБ . Итого около 373ГБ без учета аудио. Проблему можно немного сгладить, сжав сырые данные без потерь
"C:\Program Files\flac\flac.exe" -f capture.u8 --threads 64 --best --sample-rate=28636 --sign=unsigned --channels=1 --endian=little --bps=8 capture.flac
и удалив исходник. Это уменьшит суммарный размер до 333ГБ, что все равно прилично.
Во-вторых, на момент написания статьи декодирование сырых данных утилитой decode занимает очень много времени. Так, расшифровка часовой записи занимает около 12 часов на процессоре Ryzen 7 7700. При этом по ходу обработки процесс замедляется с 8 кадров в секунду до 1. Кроме того, увеличение количества потоков может не ускорить, а замедлить процесс. Авторы программы знают о проблеме и признают, что код написан неоптимальным образом, однако пока что не нашлось желающих переписать его. Хочется верить, что однажды это будет сделано.


Вывод
При оцифровке кассет формата VHS проект VHS-Decode позволяет получить превосходный результат при минимальных финансовых затратах. Кроме того, с годами по мере выхода из строя продвинутых магнитофонов с функцией TBC он может стать единственным профессиональным методом оцифровки аналогового видео. Не стоит забывать и о том, что помимо VHS проект поддерживает множество других носителей.
Однако, на данный момент первичная подготовка для оцифровки этим методом может представлять трудности для неподготовленного человека. Также в нынешнем виде VHS-Decode непригоден для быстрой обработки большого количества кассет. В том числе в коммерческих целях.
Таким образом, по моему мнению сейчас VHS-Decode может представлять интерес для энтузиастов, стремящихся получить видео максимального качества без оглядки на временные затраты. Но проект развивается, а значит можно ждать изменений к лучшему в будущем.

P.S.
Хочу выразить благодарность Алексею за помощь в модификации магнитофона и Павлу за запись тестовой кассеты и оцифровку на профессиональном оборудовании.
Если у вас возникли вопросы по VHS-Decode, вы можете задать их в комментариях или написать мне в Telegram @kuprin2000.
Комментарии (128)
r3dfx
06.07.2025 20:31А у вас всё хорошо с цветом без использования amplifyer? Кстати, кварц 40МГц даёт лучшую картину по искажениям (если не изменяет память)
UPD: а зачем вы используете флаги nld и ire0_adjust?AndrewKuprin Автор
06.07.2025 20:31Без промежуточного усилителя отношение сигнала к шуму на кассете со звонком около 36дБ, а это вроде бы неплохо. Но это отношение может зависеть от магнитофона, поэтому что у разных магнитофонов разная амплитуда сигнала на тестовом контакте. Возможно, вам не повезло.
Вы пробовали 40МГц? Я попробовал заменить кварц, но у меня почему-то не завелось, и я вернул все, как было. Как я понимаю, 40МГц нужно скорее для S-VHS, а для обычного VHS хватит и стандартной частоты.
Я не использую флаг nld, потому что он пока что экспериментальный. А флаг ire0_adjust использую, потому что его настоятельно советуют разработчики. И действительно цвета становятся более приятными. В вики VHS-Decode пишут
Automatically adjust the black level on a per-field basis, using the back porch level. Unlike
--clamp
this is done after time base correction. Therefore it can fix the per-field variations caused by the slight carrier shift of VHS-HQ and S-VHS. (more info)сначала меня смутили слова про VHS-HQ и S-VHS, но потом мне обьяснили, что этот аргумент полезен для всех форматов. Обещали исправить формулировку в вики
r3dfx
06.07.2025 20:31Спасибо за ответ. У меня заработал буквально первый попавшийся китайский кварц :) Если хотите, могу скинуть ссылку на лот.
Суть предварительного усилителя не в том, чтобы увеличить отношение С/Ш (это вторично), а согласовать импедансы. Не знаю как у вас, но в моём случае видаку не очень приятно работать в нагрузку 75Ом, которую внезапно прицепили на выход, поэтому на выходе присутствуют ромбовидные артефакты... Я сперва думал что это проникновение цвета в канал яркости (но откуда ему взяться при декодировании?), потом оказалось что это типовая проблема, которая решается только установкой полноценного преда и подбором нагрузки на его стороне
В вики чётко не прописано, но с этими картами категорически не стоит использовать любые частоты дискретизации кроме частоты тактирования. Это связано с появлением отражений (aliasing)...
Для ускорения можно было сделать даунсэмплинг через SOX к 18MSps и "убрать" один бит, т.к. отношение С/Ш позволяет.
С 0ire у меня были опасения что будут видны мгновенные изменения в цветах поля. Надо будет попробовать самому... nld у вас был на скрине с графиком скорости, поэтому я про него и написал)
AndrewKuprin Автор
06.07.2025 20:31Наверное пока что мне не нужен другой кварц. Для целей оцифровки семейных кассет стандартной частоты хватает.
Я не сталкивался с артефактами, поэтому не могу ничего сказать о вашей ситуации. Возможно, в вашем случае действительно не обойтись без усилителя. Видел на алиэкспресс варианты, которые могут подойти.
Для ускорения можно было сделать даунсэмплинг....
Это предложение, как можно ускорить работу Decode? Уменьшить частоту дискретизации до 18МГц, а затем запустить decode с аргументом
--no_resample
? Вы пробовали так делать? Это дает прирост скорости? И есть ли при этом заметная потеря качества?... nld у вас был на скрине...
Это не мой скрин :) Под ним написано, что картинка взята из сети. Если конкретно, то это замеры одного из участников чата VHS-Decode в Discord
r3dfx
06.07.2025 20:31Вы немного не поняли части про ускорение: вы всегда захватываете с частотой дискретизации Х1 от тактирующей, а потом делаете даунсэмплинг. 40 МГц лучше не потому что полоса выше, а потому что АЦП имеет меньшие искажения (по сравнению со стоковыми 28 МГц)...
Уменьшить частоту дискретизации до 18МГц, а затем запустить decode с аргументом
--no_resample
? Вы пробовали так делать? Это дает прирост скорости? И есть ли при этом заметная потеря качества?Я думал вы читали вики 0_0. Можно даже отбросить 1 бит, т.к. 7 бит дают ДД в 42дБ, что покрывает почти все записи с VHS... Если вы цифровали архив, можно было даже использовать
use_saved_levels
т.к. источник записи одинаковый. Я догонял скорость на R7 3700X почти до 8fps на малом отрезкеВидел на алиэкспресс варианты, которые могут подойти.
Я на днях закажу у Гарри платы clockgen и собранный amplifyer, а то что на али, не позволит настроить сопротивление на входе...
Это не мой скрин :) Под ним написано, что картинка взята из сети
Лисичка не читатель
Вообще странно что в статье не показана работа с ld-analyse, а ведь в него необходимо залезать для правильной настройки вывода
AndrewKuprin Автор
06.07.2025 20:31После того, как у меня не завелся кварц на 40МГц, я не особо копал в сторону нестандартных частот. Также я не храню сырые данные, поэтому пропустил разделы про сжатие файлов. Не подумал, это может быть полезно для ускорения декодирования.
Я понимаю, что вы имеете в виду. Семплирование с частотой X1, ресемплинг из файла в файл с понижением частоты дискретизации, отбрасывание одного бита, деродирова6ние с
no_resample
. При этом процесс декодирования укоряется где-то в 1.5-2 раза? И видимой потери качества нет, верно?Я на днях закажу у Гарри платы clockgen и собранный amplifyer, а то что на али, не позволит настроить сопротивление на входе...
Ох, вы находитесь в России? Если да, то можно скооперироваться с вами и заказать два усилителя?
Javian
06.07.2025 20:31Кстати недавно видел описание как работают РЭБ для Дронов - они сигнал модулируют частотой 32768 и это сводит с ума электронику.
SpbDev58
06.07.2025 20:31Если рандомно соединять проводом два устройства 220 вольт, то кого-нибудь может убить током и оцифровка будет идти уже без вас...
Oangai
06.07.2025 20:31не знаю за что минусуют, замечание вполне уместное, думать нужно про такие вещи. Но с конкретно видеомагнитофонами это не опасно, у них обычно корпус не заземлён и гальваническая развязка качественная.
alcotel
06.07.2025 20:31Вас долбануло, когда вы USB-принтер к компу подключали?
Магнитофон штатно подключается к аудио-системе, которая тоже ест 220 В от соседней розетки. И к телевизору той эпохи, в котором на кинескоп вообще 25000 В подаётся. И если это всё нечаянно не заливать
смузипивом, оно нормально работает и током не шарахает.SpbDev58
06.07.2025 20:31Я 43 года занимаюсь электроникой и сжег уже достаточно техники (компьютеры, принтеры, телевизоры и пр.). Вы путаете внешние интерфейсы, которые конечно имеют гальваническую развязку и пр. защитные механизмы и припаиные сопли (даже через конденсатор за 3 рубля) ВНУТРЬ устройства, на который у вас нет достоверной информации об особенностях работы или питания. 85% что оно сгорит, может быть даже не сегодня. Надеяться что вы сделаете лучше чем это сделали в Panasonice как бы совсем наивно. Кстати магнитных головок в видеомагнитофоне как минимум 4. К какой там автор хотел подпаяться?
alcotel
06.07.2025 20:31Я, конечно, извиняюсь за резкость. Но защиту интерфейсов бытовых устройств не стоит переоценивать. Чаще всего на штатных входах/выходах защиты нет никакой, кроме встроенных в любой усилитель паразитных диодов. Гальвано-развязка трансформатором от сети есть, и на том спасибо)))
Наверное, стоило бы добавить последовательный резистор 75 Ом, чтобы согласовать с кабелем и АЦП, и заодно помочь этим самым диодам в борьбе за выживание. Но для разового мероприятия это лишнее.
Кстати магнитных головок в видеомагнитофоне как минимум 4. К какой там автор хотел подпаяться?
Тут пишут, что к двум видео-головам после преампа и коммутатора. Сигнал со звуковой головы пишут на звуковую карту. А синхро-голова, оказывается, только самому магнитофону нужна, а при обработке - нет.
Sap_ru
06.07.2025 20:31Извините, но ЧТО ВЫ НЕСЁТЕ?!!
"RF" это же ни разу не с "видео головки"! Это же "Radio Frequency"! Это самые что ни на есть "обычный" видеосигнал! Вы его спокойно можете найти на разъёме ЛЮБОГО (совершенного любого) видеомагнитофона! Это уже сигнал с головки, сто раз обработанный и преобразованный к какому-то стандарту! Иногда через двойное преобразование (смотря, что у вас за магнитофон и кто и как писал). С потерей информации, между прочим. Его же (этот бедный видео-сигнал, который вы мучаете) сначала сняли с головки, потом декодировали, преобразовали во что-то, потом промодулировали, а вы его теперь демодулируете и декодируете. Причём однозначно криво (что у вас с шумами?!) и с недостаточной полосой пропускания (т.е. мыло у вас сразу с первых шагов заложено). Куча сил угрохана с совершенно сомнительным результатом.
Есть хочется по-настоящему декодировать VHS с целью сохранить архив, то сигнал нужно брать RGB+Sync (ну, или хотя бы RGB) с разъёма SCART - и вот тогда будет картинка с минимумом искажений, которую ещё и проще всего обработать. Причём самая кривая китайская карта, которая может его оцифровывать, при записи в MPEG2 даст результат принципиально лучше того, что вы получили или можете получить.
И вы, главное, не задумайтесь, во что это всё кодировать для своего архива, и что именно происходит с interlaced видео в подавляющем большинстве кодеков, а то с таким энтузиазмом...P.S. Ах, да. Вас там (у вас на экране) не смущает надпись про 576 строк при 25 (!!!) кадрах. Вы же, наверное, слышали, что когда очень давно, во времена VHS, телевидение работало с частотой кадров 50 или 60 герц? Всё ещё ничего не смущает?
Архивы, говорите, сохраняете? За качество боретесь? Разные варианты по качеству (!!!!) сравниваете?! Ну-ну :)))))r3dfx
06.07.2025 20:31Вы не разобрались совсем, а наезжаете на автора... Речь не про антенный разъём, а сигнал с голов. И он RF, т.к. частоты соответствующие
Sap_ru
06.07.2025 20:31Зачем?! Чтобы что? А частотная компенсация, которая у каждой головки и даже у каждого магнитофона своя? Он же её просто "от балды" пытается угадать. А обратная связь от вращения головки? Без неё можно работать, но зачем? А то, что он своим подключением ещё и поломал всю эту компенсацию и теперь восстановить нормальную картинку ( на уровне того, что магнитофон через SCART выдаёт) из этого будет практически невозможно?
А то, что он рассказывает про качество, а у него полоса недостаточная и про чередование строк он "забыл"?r3dfx
06.07.2025 20:31Почему это полоса недостаточная?) Для VHS нужно порядка 5.5МГц, мы даже не учитываем потери при перезаписях
Чередование строк тоже на месте, в статье же 50i... Каждый кадр - это 2 поля
Вы хоть раз видели захват со свистка в MPEG2? Я видел и внезапно(!), разница с vhs decode, мягко говоря, приличнаяldmi
06.07.2025 20:31Меня и Beholder TV H8 + iuVCS устраивает. А всякие пост-обработки на современном железе - это уже вжух! и готово.
а раньше да - дернул мышкой и рассинхрон )))
r3dfx
06.07.2025 20:31Так статья не про вас :)
Decode позволяет вытянуть "мёртвые" ленты и крайне нестабильные источники. Автор правильно написал, это не метод для сгона сотен лент (к тому же полноценной поддержки SECAM пока нет), это инструмент для оцифровки единичных архивов, обладающий максимальной гибкостью (вплоть до настройки фильтров вручную)
SADKO
06.07.2025 20:31Для вытягивания мертвых лен нужна избыточность, а тут ей и не пахнет. Хотя софтина, наверное, позволяет, иначе просто нет смысла огород городить, тк он не лучше TBS.
...я когда-то использовал подобный подход, но у меня была более глубокая модификация видеомагнитофона, который, по сути, превращался в сканер.
sim2q
06.07.2025 20:31Спокойствие, только спокойствие!)
Кто увидел земляную петлю с оплётки из МГТФ и так всё понял :)alcotel
06.07.2025 20:31А что тут такого? В полосе 5-6 МГц этот кусок провода - слону дробинка. В самом магнитофоне от головы к схеме идёт провод ещё длиннее. А тут скорее всего не с головы сигнал снят, а скорее, с предусилителя.
Гораздо важнее, что нет настоящей петли по заземлению - через провод питания. У магнитофонов, слава богу, заземление в шнуре питания не предусмотрено.
Fagear
06.07.2025 20:31Действительно, что ВЫ несёте? Полное непонимание происходящего как минимум :)
zatim
06.07.2025 20:31Ну, скажем так, если бы я чуть менее глубоко разбирался в электронике и аналоговой видеозаписи, из текста статьи я бы тоже ничего не понял. Что откуда берется, почему и зачем. К сожалению, автор не потрудился осветить этот момент подробнее.
iliasam
06.07.2025 20:31Судя по вот этой картинке, там действительно берут усиленный сигнал прямо с головки: https://raw.githubusercontent.com/wiki/oyvindln/vhs-decode/assets/images/graphics/Laymans-Diagrams-FM-RF-Archival-%26-Decoding-Light-Current.png
inkelyad
06.07.2025 20:31Вопрос дилетанта. А если взять все эти разнообразные SDR приёмники, втыкаемые в USB качестве средства оцифровки этого самого сигнала вместо карты видеозахвата - результат каким будет? Они, вообще, справятся или по характеристикам не подойдут?
r3dfx
06.07.2025 20:31Их полосы хватает на захват Hi-Fi сигнала (декодирование Hi-Fi вроде смогли сделать быстрее realtime). Можете почитать в вики vhs decode про разные варианты АЦП
inkelyad
06.07.2025 20:31Ага. Понятно.
Но странно, что они другие варианты не пробовали. RTL-SDR -- это самый дешевый и самый паршивый вариант. Уже давно есть лишь немногим дороже но с лучшими параметрами.
r3dfx
06.07.2025 20:31Там вариантов немного, т.к. без доп. преда, 50 Ом на входе большинства АЦП сделают их по сути одинаково бесполезными)
Под эти CX чипы написан драйвер под Linux (недавно был порт на Win, но в тестовом режиме) плюс они стоят буквально копейки по сравнению с "полноценными" устройствами...
В целом никто не запрещает юзать что-то другое, просто здесь "каноничный" вариант, который обкатан и работает
NutsUnderline
06.07.2025 20:31так там цена такая что canopus выйдет проще и без заморочек. Плюс еще понять надо что делать с iq потоком или как получить сырой поток с АЦП
они и со звуком то мудрят нехило так https://github.com/oyvindln/vhs-decode/wiki/RTLSDR
alcotel
06.07.2025 20:31Как уже сказали, полосы сигнала не хватает. У DVB, под которую USB-свистки заточены, полоса сигнала меньше, чем у аналогового видео с кассеты.
Второй момент - многие из этих свистков оцифровывают сигнал на промежуточной частоте, типа 10 МГц, а не от 0 Гц. Соответственно, если оцифровывать без суровых танцев с аппаратным бубном, придётся из видео-магнитофона брать сигнал с антенного выхода. А он уже точно по качеству не лучше штатного видео-выхода.
avasiukevich
06.07.2025 20:31Я как-то лет 10 назад, когда учился в универе, занялся оцифровкой домашнего архива VHS
Денег у студентов конечно же нет, поэтому был выбран бюджетный вариант: куплена самая стандартная карта захвата (вроде бы от beholder), использовался её же софт для захвата видео (без компрессии), VHS магнитофон взят из дома (panasonic из 90х)
Самой большой проблемой была десинхронизация аудио и видео при захвате, получилось её побороть захватом в
ASF
контейнер, который сохраняет синхронизацию за счет поддержки variable frame rateVFR
(метод был прочитан на каком-то форуме). ПотомVFR
ASF
перегонялся вCFR
AVI
(25 кадров в секунду) черезmencoder
.Минимальная обработка (убрать шумы, обрезать мусор по краям и т д) делалась через
avisynth
. Цель: убрать неразличимые глазом шумы, чтобы снизить размер сжатого файла, минимально улучшить картинку.Деинтерлейсинг я в итоге не стал делать, так как ни один доступный мне тогда деинтерлейсер не показал достойное качество, все мазали картинку. Решено было сохранить оригинальную чересстрочную картинку. Её было комфортно и так смотреть, а при необходимости деинтерлейсинг всегда можно включить непосредственно в плеере
Конечный результат кодировался в
x264
и сохранялся вMKV
. Аудио тривиально кодировалось из несжатогоCFR
AVI
вm4a
используяffmpeg
и тоже добавлялось вMKV
Весь пайплайн был автоматизирован скриптом и выглядел как-то так: VFR ASF -> mencoder -> CFR AVI -> avisynth -> x264 -> MKV.
Запись одной кассеты занимала часа 3, последующая конвертация еще часов 10. Можно было параллелить это и одновременно записывать на одном компе и конвертировать на другом. Исходный несжатый
ASF
файл для трехчасовой кассеты занимал 90GB, финальныйMKV
4-7 GB. Качество получалось идентично тому, что видно на экране в лайве, артефакты компрессии глазу не видны совсем.Получился в итоге довольно интересный студенческий проект на лето, было интересно поэкспериментировать с технологиями видеозаписи и видеокомпрессии.
kvk-2019
06.07.2025 20:31Тоже как-то оцифровывал подобным образом. С шестиголовочного магнитофона захватывал YPbPr сигнал бехолдером 8 (PCI-e 1x). Насколько помню, пришел также в конце концов к захвату в lossless ASF, при записи вручную подстраивал фильтры (нужно было для лучшего качества смотреть на изменение картинки), деинтерлейс делал "на лету" (из всех вариантов, доступных на сайте, был один более или менее подходящий по качеству, как мне показалось), критичной при этом была нагрузка на процессор, настройки фильтров подбирались в том числе исходя из этого. Потом конвертировал ffmpeg в x264 -crf 18. Сейчас, правда при необходимости перекодирую видео видеокартой Nvidia - это намного быстрее, качество вполне устраивает. А в начале захватывал в AVI. Видео со звуком всегда расходилось при этом, причём, насколько помню каждый раз по-разному. Даже скрипт для корректировки расхождения на пайтоне написал исходя из предположения о линейной зависимости, пока не пришёл к описанному выше варианту.
Скрипт: VirtualDub.py
#! python3.5 import bisect import os import re import subprocess import sys import threading import tkinter from tkinter import ttk import win32api import win32com.client import win32con import win32console import win32gui import mylib class Application(ttk.Frame): def __init__(self, master=None): global padx, pady super().__init__(master) master.title(os.path.split(sys.argv[0])[1]) master.resizable(False, False) # Определим размер шрифта для расчета горизонтальных и вертикальных отступов ttk.Style().configure("TLabel", font=font) self.label = ttk.Label(self, text="0" * 2) self.label.pack() padx = self.label.winfo_reqwidth() pady = self.label.winfo_reqheight() self.label["text"] = self.label["text"][0] padx -= self.label.winfo_reqwidth() self.label.destroy() del self.label self.correction_value = tkinter.IntVar() self.correction_value.set(1100) self.correction_focused = None self.sign_factor = -1 self.correction0_value = tkinter.IntVar() self.correction0_value.set(0) self.sign0_factor = -1 self.correction0_focused = None self.saved_value = None self.grid() self.createWidgets() def update_application_window(self): if root.wm_state() == "withdrawn": x = (root.winfo_screenwidth() - root.winfo_reqwidth()) // 2 y = (root.winfo_screenheight() - root.winfo_reqheight()) // 2 root.wm_geometry("+{0:d}+{1:d}".format(x, y)) root.deiconify() # Делаем видимым основное окно for suffix in ("", "0"): correction = getattr(self, "correction{0}".format(suffix)) correction_focused = "focus" in correction.state() if correction_focused and not getattr(self, "correction{0}_focused".format(suffix)): correction.select_range(0, "end") setattr(self, "correction{0}_focused".format(suffix), correction_focused) state = "disabled" if self.correction_value.get() == self.correction0_value.get() else "normal" self.hour["state"] = self.minute["state"] = (state, ) self.update_idletasks() self.update() self.after(100, self.update_application_window) def change_sign(self, widget): def factor(): return "sign{0}_factor".format("0" if correction0 else "") correction0 = self.nametowidget(widget) in (self.correction0, self.sign0_button) setattr(self, factor(), -getattr(self, factor())) button = getattr(self, "sign{0}_button".format("0" if correction0 else "")) button["text"] = "-" if getattr(self, factor()) < 0 else "+" def key_return(self, event): if event.widget == self.run_button: self.run() else: event.widget.tk_focusNext().focus() next_widget = root.focus_get() if next_widget == self.sign0_button: next_widget.tk_focusNext().focus() next_widget = root.focus_get() if next_widget in (self.correction, self.correction0, self.hour, self.minute): next_widget.select_range(0, "end") def validate_correction(self, widget, data, action): correction0 = self.nametowidget(widget) == self.correction0 value = getattr(self, "correction{0}_value".format("0" if correction0 else "")) other_value = getattr(self, "correction{0}_value".format("" if correction0 else "0")) entry = getattr(self, "correction{0}".format("0" if correction0 else "")) valid = re.match(r'^\d+$', data) is not None if action == '0': self.saved_value = value.get() elif action == '1': if not valid: try: value.get() except Exception: value.set(self.saved_value) entry.select_range(0, "end") if data in "-+": self.change_sign(widget) elif data == " ": other_value.set(value.get()) entry.select_range(0, "end") else: return False return valid def validate_time(self, widget, new_value, data, action): def process_widget(name, max_value): widget = getattr(self, name) if widget.get() == '': widget.set(self.saved_value) widget.select_range(0, "end") if data == "-": widget.set(str(max(0, int(widget.get()) - 1))) elif data == "+": widget.set(str(min(max_value, int(widget.get()) + 1))) if action == '0': self.saved_value = self.nametowidget(widget).get() return True elif action == '1': if widget == str(self.hour): valid = re.match(r'^\d$', new_value) is not None if not valid: process_widget('hour', 9) elif widget == str(self.minute): valid = re.match(r'^[0-5]?\d$', new_value) is not None if not valid: process_widget('minute', 59) else: return False return valid def run(self, event=None): config = """VirtualDub.audio.SetSource(1); VirtualDub.audio.SetMode(1); VirtualDub.audio.SetInterleave(1,500,1,0,{2}); VirtualDub.audio.SetClipMode(1,1); VirtualDub.audio.SetConversion(0,0,0,0,1); VirtualDub.audio.SetVolume(); VirtualDub.audio.SetCompressionWithHint(8192,48000,2,0,32000,1024,"AC3ACM"); VirtualDub.audio.EnableFilterGraph({0}); VirtualDub.video.SetInputFormat(0); VirtualDub.video.SetOutputFormat(7); VirtualDub.video.SetMode(0); VirtualDub.video.SetSmartRendering(0); VirtualDub.video.SetPreserveEmptyFrames(0); VirtualDub.video.SetFrameRate2(0,0,1); VirtualDub.video.SetIVTC(0, 0, 0, 0); VirtualDub.video.SetCompression(); VirtualDub.video.filters.Clear(); VirtualDub.audio.filters.Clear(); VirtualDub.audio.filters.Add("input"); VirtualDub.audio.filters.Add("time stretch"); VirtualDub.audio.filters.Connect(0, 0, 1, 0); VirtualDub.audio.filters.instance[1].SetDouble(0, {1:.8}); VirtualDub.audio.filters.Add("output"); VirtualDub.audio.filters.Connect(1, 0, 2, 0); """ try: correction = self.sign_factor * int(self.correction.get()) except ValueError: threading.Thread(target=mylib.MessageBox, args=('Не задана коррекция!', win32con.MB_ICONEXCLAMATION, 5)).start() return try: correction0 = self.sign0_factor * int(self.correction0.get()) except ValueError: threading.Thread(target=mylib.MessageBox, args=('Не задана коррекция нуля!', win32con.MB_ICONEXCLAMATION, 5)).start() return try: time_span = (int(self.hour.get()) * 60 + int(self.minute.get())) * 60 except ValueError: time_span = 0 if not time_span: threading.Thread(target=mylib.MessageBox, args=('Не задано время!', win32con.MB_ICONEXCLAMATION, 5)).start() return if not os.path.exists(PROGRAM): threading.Thread(target=mylib.MessageBox, args=('Не обнаружен "{0}"!'.format(PROGRAM), win32con.MB_ICONEXCLAMATION, 5)).start() return correction -= correction0 if not correction: config = re.sub(r'^.*\.audio\.filters\.(?!Clear).*$', '', config, flags=re.MULTILINE).rstrip() factor = 1.0 + correction / 1000 / time_span with open(CONFIG_NAME, "w") as config_file: config_file.write(config.format(1 if correction else 0, factor, correction0)) subprocess.Popen('"' + PROGRAM + '" /s "{0}"'.format(CONFIG_NAME)) self.quit() def createWidgets(self): self.config(padding=(padx, int(pady/4))) style = ttk.Style() style.configure("TLabel", font=font) style.configure("TButton", font=font) style.configure("C.TButton", font=font, foreground="red") style.configure("TCombobox", font=font) style.configure("TRadiobutton", font=font) root.bind('<Key-Return>', self.key_return) root.bind('<Control-Key-Return>', self.run) row = 0 self.header = ttk.Label(self, text="Задай коррекцию и время") self.header.grid(row=row, column=0, columnspan=4) row += 1 self.correction_label = ttk.Label(self, text="Коррекция(ms)*:") self.correction_label.grid(row=row, column=0, sticky="e") self.clear_button = ttk.Button(self, text="C", width=1, style="C.TButton") self.clear_button["command"] = lambda:self.correction_value.set(0) self.clear_button.grid(row=row, column=1) self.sign_button = ttk.Button(self, text="-", width=1) self.sign_button["command"] = (self.register(self.change_sign), self.sign_button) self.sign_button.grid(row=row, column=2) self.correction = ttk.Entry(self, width=5, textvariable=self.correction_value, validate="key", validatecommand=(self.register(self.validate_correction), '%W', '%S', '%d')) self.correction.grid(row=row, column=3) self.correction.focus() row += 1 self.correction0_label = ttk.Label(self, text="Коррекция нуля(ms)*:") self.correction0_label.grid(row=row, column=0, columnspan=2, sticky="e") self.sign0_button = ttk.Button(self, text="-", width=1) self.sign0_button["command"] = (self.register(self.change_sign), self.sign0_button) self.sign0_button.grid(row=row, column=2) self.correction0 = ttk.Entry(self, width=5, textvariable=self.correction0_value, validate="key", validatecommand=(self.register(self.validate_correction), '%W', '%S', '%d')) self.correction0.grid(row=row, column=3) row += 1 self.time_label = ttk.Label(self, text="Время(h:mm):") self.time_label.grid(row=row, column=0, sticky="e") self.hour = ttk.Combobox(self, width=1, validate="key", validatecommand=(self.register(self.validate_time), '%W', '%P', '%S', '%d')) self.hour["values"] = list(map(lambda x:"{0}".format(x), range(10))) self.hour.current(0) self.hour.grid(row=row, column=1) self.sc1 = ttk.Label(self, text=":") self.sc1.grid(row=row, column=2) self.minute = ttk.Combobox(self, width=2, validate="key", validatecommand=(self.register(self.validate_time), '%W', '%P', '%S', '%d')) self.minute["values"] = list(map(lambda x:"{0:>02}".format(x*5), range(12))) self.minute.current(10) self.minute.grid(row=row, column=3) row += 1 self.space_label = ttk.Label(self, text="*Space-копировать") self.space_label.grid(row=row, column=0, sticky="w") self.run_button = ttk.Button(self, text="Запуск", width=8, command=self.run) self.run_button.grid(row=row, column=1, columnspan=3, pady=int(pady/4)) self.after(100, self.update_application_window) if __name__ == "__main__": FOLDER = os.path.split(sys.argv[0])[0] PROGRAM = os.path.join(FOLDER, "VirtualDub.exe") CONFIG_NAME = os.path.join(FOLDER, "config.vcf") MONIKER = r"winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" SCRIPT_TITLE = os.path.split(sys.argv[0])[1] keep_output = False COMSPEC = os.getenv("comspec") if COMSPEC: # Проверим на запуск в режиме сохраниеия вывода после завершения parent_process_moniker = (MONIKER + ":Win32_Process.Handle=" + str(os.getppid())) try: for i in range(2): parent_process = win32com.client.GetObject(parent_process_moniker) keep_output += re.match('("?)' + COMSPEC.replace("\\", "\\\\").replace(".", "\\.") + '\\1\s+/[ck]\s+', parent_process.CommandLine, re.IGNORECASE) is not None parent_process_moniker = (MONIKER + ":Win32_Process.Handle=" + str(parent_process.ParentProcessId)) except Exception: pass finally: parent_process = None main_hwnd = win32console.GetConsoleWindow() if main_hwnd: if win32api.GetConsoleTitle() != SCRIPT_TITLE: win32api.SetConsoleTitle(SCRIPT_TITLE) if not keep_output: win32gui.ShowWindow(main_hwnd, win32con.SW_HIDE) root = tkinter.Tk() root.withdraw() # Скроем основное окно до прорисовки точно в центре экрана (делаем видимым методом update_application_window) # Важно! Шрифт моноширинный font_sizes = [(0, 8), (480, 10), (864, 12)] font = ("Lucida Console", font_sizes[bisect.bisect(font_sizes, (root.winfo_screenheight(), float("inf"))) - 1][1], "normal") app = Application(master=root) app.mainloop() try: root.destroy() except tkinter.TclError: pass
avasiukevich
06.07.2025 20:31А в начале захватывал в AVI. Видео со звуком всегда расходилось при этом, причём, насколько помню каждый раз по-разному. Даже скрипт для корректировки расхождения на пайтоне написал исходя из предположения о линейной зависимости, пока не пришёл к описанному выше варианту.
Да, я тоже пробовал аналогично корректировать рассинхрон, но такой линейный подход работал не всегда. В конце концов выяснил, что рассинхрон вызывали две независимые причины: (1) разные частоты аудио и видео; (2) дропы кадров, когда видеопоток прерывался
И если с (1) линейная подгонка работала хорошо, то с (2) вообще никак не помогала.
andrewilife
06.07.2025 20:31Еще остались неразмагниченные кассеты?
AndrewKuprin Автор
06.07.2025 20:31Я работал с кассетами, которые содержат записи 1997-2006 года. Все кроме одной живы и здоровы
alcotel
06.07.2025 20:31Зависит от качества носителя и условий хранения. Тут вот товарищ, например, пишет, что не запись, а сам носитель может разваливаться в прах.
Сейчас для долговременного хранения данных в ЦОД и архивах, на сколько я знаю, пользуются стриммерами, как и 50 лет назад - той же магнитной записью на плёнке. И на HDD в общем та же магнитная запись, и, если производитель не косячит, данные десятками лет хранятся без проблем.
zatim
06.07.2025 20:31Прикольная идея! Эх, ее бы мне увидеть лет 6 назад. Была у меня Электроника 590, развандаленная аффинажниками. Механика вся была на месте, а плат не было. И хотелось прочитать видеозапись с катушки. Для этого попытался подкинуть туда кишки от vhs, там форматы записи почти похожи. Но подружить их так и не вышло. А с этой программой могло бы и получиться.
Кстати, интересный вопрос: как она разбирает сигнал на кадры? Если начало/конец строки можно вытащить из сигнала с БВГ, то кадровые синхроимпульсы идут с отдельной головки (объединенной со звуковой).
HardWrMan
06.07.2025 20:31Там не кадровая а синхронизирующая т.н. "трекинг". Причем 25 Гц. Смещение фазы этой частоты приводит к смешению траектории описываемой видеоголовками на ленте. А на саму голову пишется полноценный видеосигнал в FM кодировании со всеми служебными интервалами, поэтому он и называется RF. Разве что цветность может транскодироваться в другой формат (часто видеомагнитофон пишет всегда только в PAL или NTSC, но принимает любой, даже SECAM). Причем, так как головы 2 а обхват чуть более 180 градусов, то они работают по очереди, коммутатор находится непосредственно рядом с трансформатором БВГ вместе с усилителем. Технически, в статье снимают сигнал не с самой головы а после коммутатора-усилителя.
zatim
06.07.2025 20:31Там не кадровая а синхронизирующая
Не нужно придираться к терминологии без причины. Везде, в т.ч. и в википедии, пишут - кадровая.
Вдоль нижнего края ленты записывается управляющая дорожка[6], содержащая кадровые синхроимпульсы[8]
Тем более если знать, что то, что передается с частотой 50 Гц - это поле, при чересстрочной развертке кадр состоит из двух полей, четного и нечетного. Соответственно, кадры идут с частотой 25 Гц.
HardWrMan
06.07.2025 20:31Ещё раз: это не кадровая. Но она вынуждена быть таковой, потому что 1 проход 1 головы это одно поле. 2 прохода 2 голов это как раз 2 поля или 1 оборот барабана - 1 кадр черезстрочной развёртки. И эта синхронизация лишь частично-косвенно используется для восстановления настоящей кадровой синхронизации. Вот RPM БВГ как раз настоящая кадровая частота. И она держится стабильной даже при стоп-кадре, когда синхрочастота равна 0. Если бы бвло как пишут на этой вашей википедии то стопкадр был бы в принципе невозможен.
А что там пишут и не дай Б-г модерируют на википедии давно уже всем известно.
zatim
06.07.2025 20:31А что там пишут и не дай Б-г модерируют на википедии давно уже всем известно.
Там вообще то ссылка на журнал "Радио" за 1987 год. То есть, вы хотите сказать, что в журнале в 1987 году писали и модерировали неправильно?
HardWrMan
06.07.2025 20:31При всём авторитете журнала Радио (и моём личном уважении к нему) даже в нём бывают факапы. Если бы вы его читали как я, то знали бы про постоянную рубрику "По следам публикаций". Вон, ниже уточнили, что в ангельском разделе вики написано правильно.
zatim
06.07.2025 20:31Не вижу тут никаких факапов. Скорее тут у вас факап. Вы решили доколупаться до слов, но не вывезли. В английском варианте написано ровно то же самое, воспользуйтесь переводчиком.
HardWrMan
06.07.2025 20:31А давайте.
Another linear control track at the tape's lower edge holds pulses that mark the beginning of every frame of video; these are used to fine-tune the tape speed during playback, so that the high speed rotating heads remained exactly on their helical tracks rather than somewhere between two adjacent tracks (known as "tracking"). Since good tracking depends on precise distances between the rotating drum and the fixed control/audio head reading the linear tracks, which usually varies by a couple of micrometers between machines due to manufacturing tolerances, most VCRs offer tracking adjustment, either manual or automatic, to correct such mismatches.
Ну и? Где кадровая? Есть только "метка начала кадра". И при этом указано, для чего она там. Ещё раз: как возможен стопкадр или поиск вперёд/назад? Ну, как, если кадровая записана только в синхродороге?
zatim
06.07.2025 20:31pulses that mark the beginning of every frame of video
Это что, по вашему? Смотрю в книгу, вижу фигу?
HardWrMan
06.07.2025 20:31Метка != синхроимпульс. Ниже вам написал. Смиритесь уже вы, не вывозите вы в техчасть да что с того то? А про стопкадр и поиск вы так и не ответили.
A control track is a track that runs along an outside edge of a standard analog videotape (including VHS). The control track encodes a series of pulses, each pulse corresponding to the beginning of each frame. This allows the video tape player to synchronize its scan speed and tape speed to the speed of the recording. Thus, the recorded control track defines the speed of playback (e.g. SP, LP, EP, etc.), and it is also what drives the relative counter clock that most VCRs have.
Вот вам ещё про истинное назначение синхродороги. Заметьте - ни слова про видеосигнал!
zatim
06.07.2025 20:31Что за бред вы несете. Синхроимпульс - он везде синхроимпульс. Если он начал выполнять другую функцию, он не перестал от этого быть синхроимпульсом.
HardWrMan
06.07.2025 20:31Верно, но есть нюанс что именно он синхронизирует. Позицию головы на дорожке или луч кинескопа в телевизоре. Подумайте над этим на досуге.
The control track is used to fine-tune the tape speed during playback, so that the high speed rotating heads remained exactly on their helical tracks rather than somewhere between two adjacent tracks (known as "tracking"). Since good tracking depends on precise distances between the rotating drum and the fixed control/audio head reading the linear tracks, which usually varies by a couple of micrometers between machines due to manufacturing tolerances, most VCRs offer tracking adjustment, either manual or automatic, to correct such mismatches.
ahabreader
06.07.2025 20:31enwiki говорит про это поточнее:
Tracking adjustment and index marking
Another linear control track at the tape's lower edge holds pulses that mark the beginning of every frame of video; these are used to fine-tune the tape speed during playback...
zatim
06.07.2025 20:31pulses that mark the beginning of every frame of video
Да нет, все то же самое. Воспользуйтесь переводчиком. Импульс, который обозначает начало каждого кадра - это (внезапно!) кадровый синхроимпульс.
HardWrMan
06.07.2025 20:31Ещё раз, чисто для вас:
Each of the diagonal-angled tracks is a complete TV picture field, lasting 1⁄60 of a second (1⁄50 on PAL) on the display. One tape head records an entire picture field. The adjacent track, recorded by the second tape head, is another 1⁄60 or 1⁄50 of a second TV picture field, and so on. Thus one complete head rotation records an entire NTSC or PAL frame of two fields.
Видеоголова пишем весь кадр целиком, со всеми синхроимпульсами. Точка. Синхродорога пишет сигнал, внезапно, синхронизации БВГ к этим дорожкам. Смиритесь уже с этим.
ahabreader
06.07.2025 20:31Ну, суть в том, что он не один такой. Для телевизора есть синхронизация в самом видеосигнале на наклонных дорожках - как строчный HBLANK остаётся на месте, так и кадровый VBLANK.
Оффтоп: сейчас странновато смотреть, как в аналоге хранили невидимые части кадра, но тогда это была хорошая идея и в них потом дополнительную информацию пихали. Субтитры, телетекст, мини-настроечная таблица (ITU-T J.63), метаданные на LD...
Про метаданные из IEC 60856-1986 zatim
06.07.2025 20:31строчный HBLANK остаётся на месте, так и кадровый VBLANK.
Это гасящие импульсы. Не путайте их с синхронизирующими.
ahabreader
06.07.2025 20:31В радиоэфире других нет, так что телевизор обречён синхронизироваться по ним. По импульсам внутри импульсов, точнее. По синхронизирующим (vertical sync pulses) внутри гасящих (vertical blanking period).
HardWrMan
06.07.2025 20:31Вот это точнее. По синхродороге весь ЛПМ подстраивается под записанный контент, прямо как дисковод под отформатированный диск: скорость протягивания для правильного звука и фаза поворота БВГ для правильного трекинга (это фаза переключения между головами и продольное, по отношению к ленте, смещение "сканирования" головами нанесённых дорожек). При записи видеомагнитофон всё делает по внутренним опорным генераторам, подпёртыми кварцевыми резонаторами, а при воспроизведении полностью опирается на сигнал с ленты, сравнивая с эталоном только частоту синхросигнала для получения правильной высоты звука. Физически же при этом отклонение движения ленты может быть даже заметным на глаз - полоса ФАПЧ мотора капстана (тонвала) достаточно широкая. Я в бытность ремонта помню модифицировал свой ВМ12 так, что 3 часовая кассета вмещала 4 часа. При этом он без проблем воспроизводил и записи с других магнитофонов.
ahabreader
06.07.2025 20:31как она разбирает сигнал на кадры?
На наклонных дорожках остаётся информация для этого (VBLANK, кадровый гасящий импульс). Теоретически её могли бы выкинуть для экономии места, но субтитры, защита Macrovision и стоп-кадр сообщают, что (все?) невидимые строки на месте.
HardWrMan
06.07.2025 20:31Ничего там не выкинуто, всё в наличии. Немного модифицировано, чтобы влезать в модуляцию, только и всего.
ahabreader
06.07.2025 20:31Такая экономия места (8-9%) ещё бы Hi-Fi Stereo сломала, если подумать.
Но какие-то из невидимых строк должны быть сильно зашумлены в момент смены головок (head switching noise). Вот в книжке пишут, что пришлось постараться, чтобы дорожка Hi-Fi Stereo не щёлкала 50-60 раз в секунду.
HardWrMan
06.07.2025 20:31Ну да, угол HiFi при этом меняется, но о каком HiFi идёт речь в рамках ВМ12? Кассеты предназначались только для воспроизведения на нём же. HiFi и не требовалось, а вот Арвид радовался дополнительной ёмкости.
ahabreader
06.07.2025 20:31Я про саму теоретическую возможность с её теоретическими последствиями.
И приправляю коммент тем, что не знаю, сколько там в норме шума в момент переключения и что там ещё теряется кроме фазы этого антисоветского FM-звука (допустим, сколько частей строки, если бы на ней хранилось что-то полезное).
HardWrMan
06.07.2025 20:31Вы не поняли. Я по сути сделал LP для ВМ12. Это влияло только на скорость протягивания ленты и, как итог, только на стандартную линейную аудиодорожку, как и в другом видеомагнитофоне со штатной функцией LP. А HiFi пишется головками на БВГ, с углом смещения 60 или 42 градуса. Смещение позволяет сдвинуть аудиодорожку относительно видеодорожки потому что плёнка движется непрерывно. Причём, HiFi магнитофоны с функцией LP в большинстве своём умеют писать HiFi даже на скорости LP. Ну а в тракте HiFi там сигнал/шум и частотный диапазон не зависят от скорости протягивания ленты потому что HiFi головки находятся на БВГ и их скорость перемещения стабильная и высокая.
VBDUnit
06.07.2025 20:31Эээ...
Компонентный выход у магнитофона. Y - яркость, Cb - разница между ней и синим, Cr - между ней и красным. Гораздо качественнее композита, где всё по одному проводу Берём хороший бу живой магнитон типа JVC HM‑DH40 000U, который имеет выход Component (то есть три провода для трех каналов цвета — яркость и две цветоразностные)
Берём карту захвата с компонентом типа Intensity
Пихаем компонент сигнал в комп
На стороне компа захватываем видеопоток в RAW без сжатия и без субдискретизации, можно в RGB
Полученное сырьё реставрируем, цветокорим по вектороскопам/осциллоскопам чтобы вправить моск цветам как было. Доп обработка по вкусу, можно нейросетями и/или апскейлом
Жмём в что‑нибудь с большим битрейтом или вообще в Loseless типа ProRes
Если всё правильно сделать, качество будет максимальное, в прямом смысле: мы здесь на каждом этапе теряем минимум информации.
Опционально можно всё или часть делать за один присест, если не гнать этот пайплайн через софт для монтажа, а сразу пропускать и синхронизировать RAW картинку через софт для видеомикширования (не буду показывать пальцем на Tesseract :) )
Тогда сразу будет захватываться готовый результат.
Аналоговый шум надо убирать
Аналоговый шум алгоритмы сжатия видно часто воспринимают как детали картинки и пытаются их сохранить, выкидывая настоящие детали. В итоге к аналоговому шуму добавляется мыло и/или файл получается больше. Потому что оно искренне пытается сохранить каждую мурашку.
Поэтому шумы лучше убирать (если не писать в RAW конечно). По этой же причине стоит 10 раз подумать, прежде чем добавлять художественный шум в видео, которое заливается в соц сети и телеграмы, где царит низкий битрейт.
Упоротый вариант — подцепить АЦП к головке магнитофона. Но это, кхм, сопряжено некоторыми небольшими сложностями :)
AndrewKuprin Автор
06.07.2025 20:31Прочитайте вывод статьи. Я и не настаиваю на том, что это лучший метод. Ваш вариант вполне рабочий. Единственное, в чем VHS-Decode явно лучше других методов - это качество TBC (смотрите второе видео в статье). Ну и цена конечно.
Наверное с точки зрения эффективности разумно было использовать хороший магнитофон и хорошую карту захвата как основной инструмент для оцифровки, а VHS-Decode как вариант для плохо сохранившихся кассет, которые встречаются не так часто.
SADKO
06.07.2025 20:31Да не будет у него лучше качество TBS, а на тянутых лентах даже хуже. Тк и то, и другое происходит в реальном времени, но интегрированный TBS работает в плотной связке с другими системами видеомагнитофона.
Я не отрицаю такой подход более того сам в свое время подобное проворачивал, правда не для VHS, и не в реальном времени, и не только из-за проблем с производительностью. Смысл был в том, чтобы по сути сканировать плёнку, с большой избыточностью. Частота вращения барабана была постоянная и синхронизированная АЦП. А подача плёнки управлялась программно, по мере необходимости.
HardWrMan
06.07.2025 20:31Упоротый вариант — подцепить АЦП к головке магнитофона. Но это, кхм, сопряжено некоторыми небольшими сложностями :)
Однако, это единственный правильный метод вытащить то, что по факту на носителе, исключая все артефакты постобработки конкретного аппарата. Точно так же работает декодирование RF с фотоприёмника LD проигрывателя. Вопрос лишь в целесообразности: насколько важен записанный контент. Есть очень много быстродействующих АЦП на 8-12 разрядов (до сотни МГц сэмплирования), есть хорошие и быстрые FPGA. Можно всё сделать даже ещё лучше, чем описано в статье, вопрос лишь в том, какая конечная цель преследуется.
VBDUnit
06.07.2025 20:31Более чем согласен. Но имхо это как из орбитального ядерного лазера по воробьям. Если воробей какой‑то особенный то норм, но в общем случае не надо :)
много быстродействующих АЦП на 8–12 разрядов (до сотни МГц сэмплирования)
Есть подозрение, что для качества этого мало, и надо не менее 1 ГГц. А так да.
Для годноты можно ещё в FPGA параллельно завести питание через отдельный АЦП, чтобы если вдруг (ну вдруг) по нему наводятся помехи, то алгоритмы обработки были в курсе и могли через пару обработок вычесть из полезного сигнала.
nafikovr
06.07.2025 20:31так вроде в статье как раз и говорится что метод хорошо подходит для проблемных кассет, в отличии от записи с "бытовых" проигрывателей.
HardWrMan
06.07.2025 20:31Более того, если снять то, что по факту на ленте, причём если ещё и стабилизацию протягивания сделать внешнюю, то можно избавиться и от артефактов инертности ФАПЧ капстана и трекинга в целом, при потере сигнала в синхродорожке. А там время реагирования измеряется в секундах.
Точка RF, кстати, используется при ремонте и настройке видеомагнитофона с помощью осциллографа, до получения стабильного равномерного сигнала от обеих голов. Например, вот так:
Настраивается как механика (направляющие ролики и азимут самих кристаллов) так и электроника (средняя фаза автоматического трекинга). Поэтому, тестовая точка RF есть у каждого видеомагнитофона.
LAutour
06.07.2025 20:31Берём карту захвата с компонентом типа Intensity
В обычных(начиная с гибридных, я так цеплялся к Beholder-T8) тв-тюнерах компонентные входы тоже встречались, включая поддержку RGB захвата.
ahabreader
06.07.2025 20:31Компонентный выход у магнитофона.
Гораздо качественнее композита, где всё по одному проводуЕсли принимать это безусловно, можно оцифровку лазердиска испортить. Для него композит - родной формат и наилучший демодулятор вряд ли окажется в старом проигрывателе (а не на стороне приёмника сигнала - т.е. в карте захвата или софте ld-decode).
В случае VHS родной формат на кассете похож на S-Video (цветность отделена от яркости и впихнута в полосу частот под яркостью - т.н. color-under) и компонентный выход (S-Video или YPbPr) позволит избежать лишнего объединения-разделения цветности и яркости, но ЕМНИП, люди не видели однозначного улучшения - полосы частот так порезаны при записи, что заметные артефакты от разделения не возникают.
В S-VHS расширили полосу яркости, в композите она стала явно пересекаться с цветностью (=> артефакты разделения) и поэтому в видаки с поддержкой S-VHS добавили S-Video.
YPbPr в этот видак поставили ради цифрового D-VHS*, HD-сигналу которого есть что терять и который не имел преступных связей с композитом. Ну и ради цифровой обработки (TBC, DNR), то есть ему бы вообще цифровой выход иметь, раз он всё через цифру прогоняет.
Аналоговый шум надо убирать
Сохранять плёночное зерно в 4K сейчас считается нормальным, а тут разрешение в 30 раз меньше и хранить шум слишком дорого? Нет, если шум маскирует нехватку деталей (улучшает субъективное качество), то пусть остаётся. Для видеохостингов SD-видео апскейлят, чтобы заставить их поднять битрейт (потому что это единственный переключатель качества со стороны пользователя, кнопки "576p/480p High Bitrate" у него нет).
Упоротый вариант — подцепить АЦП к головке магнитофона. Но это, кхм, сопряжено некоторыми небольшими сложностями :)
Вся статья про это - в видеомагнитофон залезли настолько глубоко, насколько есть смысл (предусилителю и штуке, которая сигналы с чередующихся головок объединяет, можно и довериться). Залезли в эту точку, получается:
Figure 8.4.5 Block diagram of a color-under system из этой книжки * Это видак 3-в-1 (VHS, S-VHS, D-VHS) и он до сих пор тыщу долларов стоит.
HardWrMan
06.07.2025 20:31Сохранять плёночное зерно в 4K сейчас считается нормальным
Аналоговый шум работает как дизеринг. Он визуально (в случаях звука - аудиально) улучшает качество оцифровки на малых уровнях, когда битовая глубина исчерпывается.
ahabreader
06.07.2025 20:31Ну, я про другой, психологический, эффект говорил. Когда высокочастотное мельтешение не даёт чётко всмотреться и закричать при виде настоящего адского мыло-пластилина. Возможность совершенно ясно увидеть отсутствие деталей бывает неприятной и проявит остальные артефакты.
VBDUnit
06.07.2025 20:31Для видеохостингов SD-видео апскейлят, чтобы заставить их поднять битрейт (потому что это единственный переключатель качества со стороны пользователя, кнопки "576p/480p High Bitrate" у него нет).
Абсолютно точно, именно для этого я в своё время доработал возможность апскейла в фильтры захвата и стрима. Жалко, что многие люди этот приём не используют.
Сохранять плёночное зерно в 4K сейчас считается нормальным, а тут разрешение в 30 раз меньше и хранить шум слишком дорого?
Дело не в дорого, можно, в конце концов, хранить/стримить в loseless или вообще в RAW. PNG/EXR сиквенсы + WAV рулят :)
Дело в том, что этот шум будет отжирать на себя часть битрейта. Ну то есть, грубо говоря, из 100% битрейта 50% уходит на шум. Если битрейт большой вследствие апскейла, 10/16/100500-битности или просто что его большим поставили — да, это допустимо, потому что полезная информация поместится в оставшуюся часть битрейта.
Но часто битрейта не хватает — и я про этот случай. Поголовно люди такие: «О, 576 строк, значит достаточно 480p/720p». И из этого шума вырастает ушатанное пережатое мыло.
если шум маскирует нехватку деталей (улучшает субъективное качество), то пусть остаётся.
Согласен. Но тогда нужно, чтобы этот шум сохранился.
Плёнка есть прогрессивная развёртка. А VHS — это чересстрочка. Которой на стримминговых сервисах и прочих воблачках нет. Поэтому изначальный труъ‑ламповый шум улетает как минимум в деинтерлейсер, который уже превратит его в непойми что. Особенно это касается деинтерлейсеров по оптическому потоку.
Поэтому, если уж заморачиваться, то:
Оцифровываем RAW
Измеряем и сохраняем спектр шума по яркости и цветоразностным (причём в каждом кадре отдельно)
Удаляем шум максимально качественно алгоритмом, способным жрать чересстрочку
Деинтерлейсим качественно
Апскейлим какой‑нибудь хорошей штукой до 4K/8K/16K
На основе ранее запечатлённого спектра генерируем шум яркости и цветоразностных заново. Можно крупный (чтобы пропорционально соотноситься с «пикселями» исходной картинки), можно помельче
YPbPr в этот видак поставили ради цифрового D-VHS*, HD-сигналу которого есть что терять и который не имел преступных связей с композитом. Ну и ради цифровой обработки (TBC, DNR), то есть ему бы вообще цифровой выход иметь, раз он всё через цифру прогоняет.
С одной стороны да, с другой — у нас на том конце провода висит карта захвата, которая тоже может вносить свои косяки. И с компонентом их огрести менее вероятно.
Можно вообще попробовать три карты захвата SVideo для каждого компонента — будет три отдельных АЦП и, по идее, будет вкусно. Но надо тестить, потому что не всё так просто.
но ЕМНИП, люди не видели однозначного улучшения - полосы частот так порезаны при записи, что заметные артефакты от разделения не возникают.
Ну моя идея не в том, что это однозначно улучшит качество, а в том, что при этом мы с меньшей вероятностью потеряем информацию, и даже если она не видна для глаза, она может стать важна для каких‑нибудь алгоритмов обработки, которые мы применим дальше в конвейере.
ahabreader
06.07.2025 20:31в конце концов, хранить/стримить в loseless или вообще в RAW. PNG/EXR сиквенсы + WAV рулят :)
Если оставить в YCbCr, то цветность проредить можно будет (хотя бы по горизонтали для чересстрочного). 4:2:2 уменьшит битрейт в полтора раза, 4:1:1 - в два раза, передовым lossless-сжатием для видео вроде остаётся FFV1 в 2 прохода (уменьшит битрейт ещё чуть больше двух раз).
Ну моя идея не в том, что это однозначно улучшит качество, а в том, что при этом мы с меньшей вероятностью потеряем информацию, и даже если она не видна для глаза, она может стать важна для каких‑нибудь алгоритмов обработки, которые мы применим дальше в конвейере.
На кашу из топора похоже - выбрали аппарат по наличию компонентного выхода (польза для VHS туманна), получили в целом качественный аппарат с TBC (польза очевидна), использовали компонентный выход (раз уж есть, то тупо не использовать*), а проверять гипотезы насчёт композита в конце этого длинного пути уже никому не захочется.
* принцип не работает с лазердисками
Vivado_man
“оцифровывать его с высокой частотой простым ЦАП” - дальше читать не стал.
YegorP
Стоило дочитать хотя бы до того места, где упоминается вполне доступный ЦАП:
Vivado_man
ЦАП не оцифровывает. Оцифровывает АЦП.
AndrewKuprin Автор
Исправил это опечатку, спасибо
gena_k
Кто-то уже нашёл за 1700 руб - поделитесь пожалуйста? За 1700 удалось встретить только на чипе Conexant fusion 878a с мостом PCIe-PCI, а она плохо подходит для оцифровки из-за неотключаемого смещения уровня под уровень чёрного и выключения АЦП во время обратного хода развёртки.
r3dfx
Я покупал около полугода назад за 2200 с али, она ехала ко мне через всю Росиию... За 1700р нигде не видел)