Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

AdFast v2 — ускоритель видеорекламы

Не блокирует рекламу — проматывает её. Реклама загружается и «показывается» (показ засчитывается площадке), но на скорости до 16x, без звука, закрытая аккуратной заглушкой, а кнопка «Пропустить» нажимается автоматически. После рекламы ваши скорость и звук возвращаются в точности как были.

Возможности

  • YouTube из коробки — детект по классам плеера, полный исторический набор селекторов кнопки скипа.
  • Любые сайты — добавляете домен в popup (право запрашивается точечно, только на этот домен), срабатывает универсальный детектор: Google IMA SDK, Video.js, JW Player + поиск кнопки по тексту «Skip/Пропустить».
  • Обучение — если универсальный детектор не справился, жмёте «Указать кнопку на этой странице», кликаете по кнопке скипа на рекламе — AdFast запоминает её селектор для этого домена навсегда.
  • Заглушка вместо стробоскопа — реклама на 16x выглядит как мельтешение кадров; AdFast закрывает её экраном «Проматываю рекламу…» со счётчиком.
  • Счётчик времени — popup показывает, сколько часов жизни вам вернулось и сколько реклам промотано.
  • Белый список каналов — «не трогать рекламу на этом канале», чтобы поддержать любимых авторов: один чекбокс на вкладке YouTube.
  • Самопочинка — селекторы обновляются раз в сутки из JSON на GitHub: когда YouTube в очередной раз сменит классы, починка — это коммит, а не релиз через модерацию.
  • Приватность — никакой аналитики и внешних запросов (кроме опционального GET за селекторами); права только на YouTube + добавленные вами сайты.

Сборка

Исходники лежат в src/ как ES-модули, браузер загружает собранную папку dist/. Бандл обязателен: MV3 не поддерживает type="module" для content scripts.

npm install
npm run build     # разовая сборка в dist/
npm run watch     # пересборка на лету во время разработки
npm run dist      # минифицированная сборка для раздачи
npm test          # smoke-тест ядра на заглушке DOM
npm run zip       # dist/ -> adfast.zip

Установка в Chrome / Edge / Brave

  1. npm install && npm run build
  2. Откройте chrome://extensions
  3. Включите Режим разработчика (справа вверху)
  4. Загрузить распакованное расширение → выберите папку dist
  5. Иконка »» в панели — все настройки там.

После правок в src/ держите включённым npm run watch и жмите «Обновить» на карточке расширения.

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

Хочу Делаю
Изменить скорость промотки Слайдер в popup (2–16x), применяется сразу, даже посреди рекламы
Добавить сайт Popup → «Сайты» → ввести vk.com → разрешить в системном диалоге
Сайт добавлен, но скип не работает Открыть страницу с рекламой → popup → «Указать кнопку на этой странице» → кликнуть по кнопке скипа
Поддержать канал рекламой На вкладке видео → popup → чекбокс «Не трогать рекламу на …»
Видеть рекламу вместо заглушки Снять галку «Заглушка вместо мелькающих кадров»
Выключить всё Тумблер в шапке popup

Самообновление селекторов (опционально)

  1. Создайте публичный репозиторий с файлом selectors.json (структура — объект BUILTIN_DB из src/shared/selector-db.js, поле version увеличивайте при каждом изменении).
  2. В src/shared/config.js впишите raw-ссылку в REMOTE_SELECTORS_URL: https://raw.githubusercontent.com/ВАШ_ЛОГИН/adfast-selectors/main/selectors.json
  3. Расширение проверяет файл при старте браузера и раз в сутки; кривой JSON игнорируется, при недоступности сети работает встроенный набор.

Портирование на Safari (macOS)

Код уже совместим (шим browser || chrome, коллбэк-стиль storage), нужна только нативная обёртка:

npm run build
xcrun safari-web-extension-converter /путь/к/adfast-extension/dist --macos-only
  1. В открывшемся Xcode-проекте — Run (⌘R). Для подписи хватит бесплатного Apple ID.
  2. Safari → Настройки → Дополнения → включить меню «Разработка».
  3. Меню Разработка → Разрешить неподписанные расширения (галка слетает при перезапуске Safari; с платным Developer-сертификатом не нужна).
  4. Safari → Настройки → Расширения → включить AdFast.

Нюансы Safari:

  • Требуется Safari 16.4+ (scripting.registerContentScripts для пользовательских сайтов).
  • Права на добавленные сайты Safari может дополнительно спросить своим баннером при первом заходе, либо выдайте вручную: Настройки → Расширения → AdFast → «Разрешить» для нужных сайтов.
  • Всё остальное — детект, ускорение, оверлей, picker, статистика — идентично Chrome: content script один и тот же.

Как это работает

Три контекста расширения общаются только через storage и короткий протокол сообщений:

┌─ popup ────────────────────────┐              ┌─ service worker ───────────────┐
│ settings · stats               │              │ sites      регистрация         │
│ sites · channel                │ sync-sites   │            content.js          │
│ trainer                        │ ──────────▶  │ selectors  fetch 1×/сутки      │
└───────────────┬────────────────┘              └───────────────┬────────────────┘
                │                                               │
                │ пишет настройки                               │ selectorDB
                ▼                                               ▼
┌─ storage ──────────────────────────────────────────────────────────────────────┐
│ sync    настройки · сайты · каналы · обученные селекторы                       │
│ local   статистика · кеш селекторов                                            │
└───────────────────────────────────────┬────────────────────────────────────────┘
                                        │ onChanged — без перезагрузки вкладки
                                        ▼
┌─ content script (вкладка) ─────────────────────────────────────────────────────┐
│ page      guard от двойной инъекции, hostname, isYouTube                       │
│ store     настройки · белый список · обученный селектор · база селекторов      │
│ adapters  youtube · generic — «идёт ли реклама» и «где кнопка скипа»           │
│ core      engine (тик 250 мс) · stats                                          │
│ ui        overlay · picker · toast                                             │
└────────────────────────────────────────────────────────────────────────────────┘

прямые сообщения popup ↔ content: page-info · start-picker · forget-trained

Общего состояния между контекстами нет: popup пишет в storage, content script подхватывает через storage.onChanged — поэтому настройки применяются посреди рекламы.

Внутри вкладки:

тик каждые 250 мс
├─ рекламы нет, была → вернуть скорость и звук пользователя, записать статистику
├─ реклама началась  → запомнить скорость/звук → 16x + mute + оверлей
└─ реклама идёт      → удерживать скорость (плеер может сбрасывать)
                       → кнопка скипа появилась? клик через 300–900 мс
                         полной цепочкой pointer/mouse-событий

Канал из белого списка → полный no-op. Обученная кнопка видна → считается признаком рекламы на кастомных сайтах.

Ограничения

  • Server-side ad insertion (Twitch-стримы, ТВ-стриминги) и DRM-платформы (Netflix и т.п.) — не поддерживаются принципиально: реклама там вшита в поток на сервере, на клиенте нечего ускорять.
  • Прямые эфиры — ускорять нечего, вы на краю буфера.
  • YouTube периодически меняет классы плеера; при настроенном самообновлении чинится без вашего участия, иначе — правкой BUILTIN_DB в src/shared/selector-db.js.
  • Проект для личного использования: модерация Chrome Web Store и App Store к таким расширениям враждебна, реалистичная дистрибуция — исходники/self-hosting.

Структура проекта

adfast-extension/
├── src/
│   ├── shared/                  общее для всех трёх контекстов
│   │   ├── api.js               шим browser || chrome
│   │   ├── config.js            REMOTE_SELECTORS_URL и периодичность обновления
│   │   ├── defaults.js          модель данных: что лежит в sync, что в local
│   │   ├── messages.js          константы протокола popup ↔ content ↔ background
│   │   ├── selector-db.js       встроенная база селекторов + её валидация
│   │   ├── site-pattern.js      домен ↔ origin-паттерн `*://*.host/*`
│   │   └── storage.js           промис-обёртки над storage.sync/local
│   │
│   ├── content/                 живёт во вкладке
│   │   ├── index.js             точка входа: guard → store → engine
│   │   ├── page.js              hostname, isYouTube, защита от двойной инъекции
│   │   ├── dom.js               видимость, поиск видео, «человеческий» клик
│   │   ├── store.js             настройки/белый список/обучение/база, live
│   │   ├── messages.js          ответы на page-info, start-picker, forget-trained
│   │   ├── adapters/            «идёт ли реклама» и «где кнопка скипа»
│   │   │   ├── youtube.js         точный детект по классам плеера + канал
│   │   │   ├── generic.js         эвристики плееров, IMA, обученный селектор
│   │   │   └── index.js           выбор адаптера под площадку
│   │   ├── core/
│   │   │   ├── engine.js          тик 250 мс: enterAd → удержание → exitAd
│   │   │   └── stats.js           экономия сессии → storage.local
│   │   └── ui/
│   │       ├── overlay.js         заглушка поверх плеера
│   │       ├── picker.js          режим «укажи кнопку Пропустить»
│   │       ├── selector-builder.js устойчивый CSS-селектор для элемента
│   │       └── toast.js           уведомления picker'а
│   │
│   ├── background/              service worker
│   │   ├── index.js               подписки на сообщения, install/startup, alarm
│   │   ├── sites.js               регистрация content.js на сайтах пользователя
│   │   └── selectors.js           суточный fetch базы селекторов
│   │
│   └── popup/                   интерфейс настроек
│       ├── index.js               инициализация секций
│       ├── dom.js                 $, bindCheckbox, formatDuration
│       ├── tab-context.js         один запрос page-info на весь popup
│       └── sections/              settings · stats · channel · sites · trainer
│
├── public/                      копируется в dist/ как есть
│   ├── manifest.json            MV3-манифест
│   ├── popup.html · popup.css
│   └── icons/                   16/48/128
│
├── tests/content.smoke.mjs      прогон ядра на заглушке DOM
├── build.mjs                    esbuild: src/ → dist/{content,background,popup}.js
├── LICENSE                      MIT
├── README.md                    этот файл
└── TZ.md                        полное техническое задание

Правило зависимостей: shared/ не знает ни о ком, content/core работает через adapters, а не через DOM конкретной площадки, ui/ ничего не решает про рекламу. Добавить новую площадку = написать один файл в adapters/ с двумя методами.

Лицензия

MIT — берите код куда угодно, сохраняя копирайт.

Лицензия относится только к коду. Ответственность за то, как расширение используется на конкретных площадках (правила и условия YouTube и других сайтов), лежит на пользователе; авторы гарантий не дают — см. текст лицензии.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages