Skip to content

Latest commit

 

History

62 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SubsAnywhere

Оригинальные субтитры поверх видео, перевод целых реплик и отдельных фраз на русский, китайские субтитры с пиньинем для YouTube.

0.11.0 — кандидат первого выпуска, не заявление о готовности 1.0. Проверки и незакрытые сценарии перечислены в матрице приёмки. Обслуживание и диагностика · Данные и приватность.

Возможности

  • Одна выбранная оригинальная дорожка из HTML5-плеера, включая доступные фреймы, либо свой SRT: UTF-8 / Windows-1251, до 5 МБ.
  • Полный перевод английской реплики и список переведённых фраз через собственный ключ DeepSeek или OpenAI; готовый русский перевод показывается меньшей строкой под оригиналом.
  • На YouTube — получение английской или китайской дорожки на языке оригинала, включая автоматическую. Язык определяется по метаданным; если YouTube его не указал, выберите английский или китайский вручную. Для китайского пиньинь выводится над иероглифами; перевод реплики содержит краткий словарь пиньинь — русский.
  • По отдельной кнопке — загрузка только аудио и локальное распознавание китайской или английской речи на CPU, с прогрессом и приблизительным оставшимся временем.
  • Перетаскивание субтитров за значок ⠿, размер и цвет текста, цвет и непрозрачность фона. Для SRT — смещение и скорость дорожки.
  • Выбор плеера, дорожки, импортированные субтитры и оформление сохраняются отдельно для каждой страницы. Ключи и выбранная модель перевода — общие для расширения.
  • Системное произношение китайских и английских слов и фраз в субтитрах; при наличии используются рабочие голоса Google, выбранные голос и скорость сохраняются, голос можно сразу проверить тестовой фразой.
  • Управление расширением открывается постоянно внутри страницы: окно можно перетаскивать, менять его размер и закрывать крестиком. На обычной странице просмотра YouTube оно встраивается над рекомендациями справа; в широком и полноэкранном режимах становится плавающим.

Установка

Здесь две отдельные части: расширение устанавливается в Chrome; Docker запускает сервер субтитров YouTube и локального распознавания речи. Docker не устанавливает расширение и не получает доступ к профилю Chrome. Для встроенных дорожек и своего SRT сервер не нужен; для DeepSeek или OpenAI нужны интернет и собственный API-ключ, но не Docker.

1. Загрузить расширение

Скачайте исходники выпуска или клонируйте репозиторий и сохраните папку в постоянном месте:

git clone https://github.com/niiikkid/SubsAnywhere.git
cd SubsAnywhere

В Chrome 120 или новее откройте chrome://extensions, включите Режим разработчика, нажмите «Загрузить распакованное расширение» и выберите папку с manifest.json. Сборка JavaScript и установка npm-пакетов для этого не нужны.

2. Запустить сервер одной командой

Нужны работающие Docker и Compose v2: Docker Desktop на macOS/Windows с Linux-контейнерами либо Docker Engine с Compose на Linux. Команды запускайте из папки проекта; основной запуск одинаков в терминале macOS/Linux и PowerShell:

Если уже работает нативный сервер на 43817, не запускайте второй экземпляр. Можно продолжить пользоваться нативным сервером или дождаться его заданий и штатно остановить его в своём терминале, когда решите перейти на Docker. Не завершайте чужой процесс вслепую; нативные файлы не переносятся в Docker автоматически.

docker compose up -d --build

Первая сборка требует интернета и места для образа с CPU-распознаванием. Python, FFmpeg, yt-dlp и зависимости FunASR устанавливаются внутрь образа, не на хост. Базовый Compose ограничивает сервер 4 CPU и 8 ГБ памяти; это фиксированные пределы, не треть ресурсов любого компьютера. Для автоматического расчёта трети используйте настройку ниже.

Сервер доступен только на http://127.0.0.1:43817. Адрес в расширении фиксирован; смена опубликованного порта в Compose сама по себе его не перенастраивает.

docker compose ps
docker compose exec subtitles python healthcheck.py

Проверьте также http://127.0.0.1:43817/health в браузере. healthy означает, что API отвечает, а не что модели импортированы, YouTube доступен или распознавание проверено.

3. Один раз импортировать модели — только для распознавания

Образ не содержит и не скачивает веса моделей. Получение готовых дорожек YouTube не требует весов. Для кнопки «Создать свои субтитры» нужен уже имеющийся полный локальный кэш:

iic/
  SenseVoiceSmall/
  speech_fsmn_vad_zh-cn-16k-common-pytorch/

Обе папки должны содержать как минимум непустые model.pt и configuration.json; копируйте полные каталоги, а не только эти два файла. После сборки образа выполните один вариант.

macOS / Linux:

docker compose run --rm --volume "$HOME/.cache/modelscope/hub/models/iic:/source:ro" model-import
docker compose restart subtitles

Windows PowerShell:

$ModelsSource = Join-Path $HOME '.cache/modelscope/hub/models/iic'
docker compose run --rm --volume "${ModelsSource}:/source:ro" model-import
docker compose restart subtitles

Путь — пример, не обещание наличия кэша на новой машине. Подставьте абсолютный путь к своему iic; на Windows это может быть C:\Models\iic. Импорт работает без сети, пишет в постоянный том моделей и отказывается перезаписывать существующие модели. Если кэша нет, локальное распознавание пока недоступно: этот выпуск не предлагает автоматическую загрузку моделей.

Для китайского по умолчанию нужна также Fun-ASR-Nano-2512. Добавьте её из полного локального кэша отдельно — базовые модели в томе не заменяются:

# macOS / Linux: каталог FunAudioLLM должен содержать Fun-ASR-Nano-2512/
docker compose run --rm --volume "$HOME/.cache/modelscope/hub/models/FunAudioLLM:/source:ro" model-import python import_models.py /source /models --nano
# Windows PowerShell
$NanoSource = Join-Path $HOME '.cache/modelscope/hub/models/FunAudioLLM'
docker compose run --rm --volume "${NanoSource}:/source:ro" model-import python import_models.py /source /models --nano

Внутри Nano нужны веса, конфигурация и подкаталог Qwen3-0.6B с конфигурацией и токенизатором. GET /health показывает выбранные recognition_models и доступные capabilities.asr_languages; отсутствие Nano не отключает английский.

Использование

  1. Откройте страницу с видео. Панель SubsAnywhere появится внутри страницы; крестик закрывает её, а значок расширения открывает снова. В разделе «Плеер» нажмите «Подключить к плееру» и разрешите запрошенный доступ. Для плеера на другом домене во фрейме может понадобиться дополнительное разрешение.
  2. Выберите плеер и оригинальную дорожку. Само открытие окна расширения не выполняет новое подключение. После смены плеера или его дорожек используйте «Перезапустить поиск субтитров».
  3. В разделе «Внешний вид» настройте оформление — подключённый плеер для этого не нужен. На видео перемещайте субтитры за значок ⠿.
  4. В «Настройках» → «Свой SRT» можно добавить файл. В «Ручной синхронизации» минус показывает реплики раньше, плюс — позже; скорость дорожки исправляет постепенно растущее расхождение.
  5. Для перевода выберите DeepSeek или OpenAI в «Настройках» → «Перевод через ИИ». Сохраните ключ, загрузите доступные вашему аккаунту текстовые модели, выберите одну и нажмите «Использовать для перевода». Полностью активен только один сервис. Нажатие на реплику открывает её полный перевод и список отдельных фраз; повторное нажатие или крестик закрывает подсказку.
  6. В «Внешнем виде» включите «Переводы над фразами»: переводённые фразы показываются прямо в субтитрах ячейками, русский перевод — мелко сверху, английский или пиньинь — основным текстом. Длинное значение сокращается многоточием; наведение или клик показывает его полностью. Пары распределяются по строкам; иероглифы остаются снизу, общий перевод реплики — над ячейками. Фон подстраивается под текст и исчезает в паузах. Субтитры и окно перевода удерживаются внутри плеера, в том числе после изменения его размера; сохранённая позиция не меняется. Если реплика не помещается по высоте, её можно прокрутить. Клик по ячейке открывает только перевод выбранного слова или выражения, без всей реплики и остальных слов. Режим сохраняется для страницы и не делает дополнительных AI-запросов. Пока перевод готовится или словарь пуст, остаётся обычная строка; для фраз, отсутствующих в словаре, перевод не придумывается.

Перевод не строго «по запросу после клика»: при полностью настроенном активном сервисе расширение заранее переводит текущую и несколько ближайших реплик. Это внешние, потенциально платные API-запросы. Полный SRT одним запросом не отправляется; подробности и фактические ограничения — в PRIVACY.md.

Ранее сохранённая база words.sqlite3 остаётся в пользовательских данных или Docker-томе; обновление её не удаляет. В этой версии расширение больше не сохраняет слова и предложения и не открывает панель повторения.

YouTube

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

Эта проверка может обратиться к YouTube, но не запускает распознавание. Для создания своих субтитров выберите язык речи: английский или китайский; при «Авто» создание по-прежнему использует китайский. Пока cookies не были явно импортированы, Docker работает без них; вход в YouTube в обычном Chrome не авторизует контейнер. После импорта cookies сохраняются в Docker-томе и подключаются обычными перезапусками. Если YouTube требует вход, см. необязательное подключение cookies.

«Создать свои субтитры» / «Создать заново» загружает аудио в FLAC без дополнительного сжатия с потерями и запускает распознавание на CPU. Уже сохранённые MP3 используются как есть, не удаляются и не маскируются под FLAC. Окно можно закрыть: задание продолжает сервер; при повторном открытии можно получить прогресс и результат. Процент и оценка времени относятся к обработке речи, а не к обещанному сроку завершения.

Перезапуск сервера не продолжает незавершённое распознавание: задание помечается прерванным, повторный запуск выполняется вручную. Уже сохранённые субтитры остаются. Новая успешная генерация заменяет серверный результат для того же видео; важные версии заранее копируйте.

Если сервер выключен, недоступны получение новых дорожек YouTube и распознавание. Встроенные дорожки, сохранённые SRT и настройки остаются доступны. Запустите docker compose up -d, затем повторите проверку сервера в окне расширения. Не удаляйте расширение и его данные для устранения сетевой ошибки.

Качество и ресурсы распознавания

Обычный режим (SUBSANYWHERE_ASR_MODEL=auto) использует Fun-ASR-Nano-2512 для китайского, SenseVoiceSmall для английского, с явно заданным языком и нормализацией текста. Приоритет китайского режима — более сложная модель даже ценой памяти и времени. Аудио декодируется последовательно блоками не более минуты; разрез по возможности проходит через тихую паузу. Исходные отсчёты не пропускаются. Это ограничивает рабочую память на длинных записях, но не делает распознавание безошибочным.

Нативный запуск: по умолчанию используется треть доступных CPU/RAM. На компьютере с 24 GiB памяти бюджет — 8 GiB. Число потоков округляется вниз, минимум один. Фоновая проверка останавливает процесс при достижении 90% бюджета памяти, оставляя запас серверу и декодеру. Это защита по периодическим измерениям, не жёсткая системная квота: кратковременные пики возможны, а один поток на слабом CPU может превышать выбранную долю. Настройка — SUBSANYWHERE_RESOURCE_FRACTION, например 0.25; применяется при запуске сервера. Уменьшение CPU замедляет работу; нехватку памяти нельзя исправить одним ожиданием.

Жёсткие ограничения Docker: с установленным Python 3 запустите на том компьютере, где работает локальный Docker (на Windows вместо python3 может потребоваться python):

python3 scripts/configure-resources.py
docker compose -f compose.yaml -f compose.resources.local.yaml up -d --build

По умолчанию скрипт рассчитывает треть CPU/RAM хоста и учитывает меньшие ресурсы Docker VM; --percent 25 задаёт другую долю. При выключенном Docker расчёт предварительный: повторите с работающим Docker перед применением. Ограничения применяются ко всему контейнеру, swap контейнера отключён. Для последующих запусков сохраняйте оба -f; обычный docker compose up использует фиксированные пределы базового файла. npm run docker:up выполняет расчёт и применяет оба файла. На новом компьютере расчёт нужно повторить.

Выбор модели: SUBSANYWHERE_ASR_MODEL=sensevoice возвращает лёгкую модель для обоих языков; nano принудительно выбирает Nano для обоих; без настройки используется auto. Нужен полный локальный каталог Nano, включая Qwen3-0.6B; произвольный путь задаётся SUBSANYWHERE_NANO_MODEL_DIR. В нативном режиме стандартный путь — ~/.cache/modelscope/hub/models/FunAudioLLM/Fun-ASR-Nano-2512, в Docker — /models/Fun-ASR-Nano-2512 после импорта с --nano. Распознавание не скачивает модели автоматически. Nano запускается на CPU в float32, без случайного выбора слов и без скрытого перехода на лёгкую модель при нехватке памяти. Бюджет ресурсов не увеличивается автоматически: при недостатке памяти задание завершится ошибкой, сохранив старые субтитры.

Nano выбрана основной для китайского по предпочтению качества перед экономией ресурсов, а не по доказанному уменьшению ошибок на ваших видео. На коротком контрольном образце выигрыша не было; редкие ошибки требуют проверки на более разнообразной речи. Её пословное выравнивание недоступно в проверенном checkpoint; таймкоды остаются основанными на VAD. Проверены короткие нативные прогоны SenseVoice на английском/китайском и Nano на китайском; это не оценка процента ошибок и не проверка Nano в Docker.

Ограничения

  • Поддерживаются текстовые дорожки обычного <video>, не надписи, впаянные в изображение; OCR и обход DRM не предусмотрены.
  • Доступность встроенных дорожек, iframe и полноэкранного режима зависит от сайта. Совместимость со всеми плеерами не заявляется.
  • YouTube может ограничить загрузку по сети, региону, учётной записи или частоте запросов. Cookies не гарантируют успех; используйте только доступные вам материалы.
  • Распознавание и пиньинь могут ошибаться. Таймкоды основаны на речевых сегментах; ограничение около 8 секунд и паузы около 0,4 секунды не дают пословной точности.
  • Подтверждение работы на Windows, Linux/amd64 и реальных сторонних плеерах — отдельные пункты приёмки, не следствие успешной сборки.

Обновление и разработка

Текущий рабочий режим на локальном Mac — без Docker. Сервер уже запускается через macOS LaunchAgent; данные перенесены с сохранением оригиналов. Пути, перезапуск, резервные копии и ограничения описаны в LOCAL-DEVELOPMENT.md. Команды Docker ниже относятся к контейнерному варианту, а не к текущей локальной разработке.

Обновляйте исходники в той же папке, выполните docker compose up -d --build, затем Reload в chrome://extensions, обновите страницу с видео и при необходимости подключитесь заново. Предварительно дождитесь завершения заданий и сделайте резервную копию. Переустановка расширения не нужна.

Нативный npm run local-server сохранён как необязательный путь для разработчика с самостоятельно настроенными зависимостями; он не нужен для Docker. Настройка и отличия хранения описаны в RELEASE.md.

Локальные автоматические проверки требуют Node.js и Python 3; это команды для запуска, не отчёт об их прохождении:

npm test
npm run check

About

Chrome-расширение: оригинальные субтитры и перевод слов по клику через DeepSeek прямо в видеоплеере.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages