Автор статьи — польский программист Томек Рекавек, разрабатывает проект Jackrabbit Oak в рамках Apache Software Foundation для Adobe. Статья опубликована в личном блоге автора 24 февраля 2016 года.

Польское «Радио-3» (так называемая «Тройка») знаменито хорошей музыкой и интеллигентными ведущими. С другой стороны, оно страдает наличием громких и раздражающих рекламных блоков в трансляции, где обычно рекламируется какая-нибудь электроника или лекарство. Я слушаю «Тройку» почти постоянно на работе и дома, поэтому задался вопросом: как удалить рекламу? Кажется, мне удалось найти решение.

Цифровая обработка сигналов


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

Знаю, что данная область математики/информатики называется цифровой обработкой сигналов, но мне DSP всегда казалась магией. Что ж, отличная возможность узнать что-то новое. Я провёл день или два, пытаясь выяснить, какой механизм использовать для анализа аудиопотока. И в конце концов нашёл то что надо: это взаимная корреляция или кросс-корреляция (cross-correlation).

Octave


Обычно все ссылаются на реализацию MATLAB. Но MATLAB — дорогостоящее приложение, которое упрощает выполнение сложных математических операций, в том числе DSP. К счастью, есть бесплатная альтернатива под названием Octave. Кажется, в Octave несложно запустить взаимную корреляцию на двух аудиофайлах. Нужно лишь выполнить следующие команды:

pkg load signal
jingle = wavread('jingle.wav')(:,1);
audio = wavread ('audio.wav')(:,1);
[R, lag] = xcorr(jingle, audio);
plot(R);

Получится такой график:



Хорошо заметен пик, описывающий положение jingle.wav в audio.wav. Что меня удивило, так это простота метода: всю работу делает xcorr(), остальной код только для чтения файлов и отображения результата.

Я хотел реализовать тот же алгоритм на Java, и тогда у меня будет инструмент, который:

  1. считывает аудиопоток со стандартного входа (например, от ffmpeg),
  2. анализирует его в поиске джинглов,
  3. выводит тот же поток на stdout и/или отключает его.

Использование stdin и stdout позволит подключить новый анализатор к другим приложениям, отвечающим за аудиотрансляцию и воспроизведение результата.

Чтение звуковых файлов


Первым делом Java-программа должна прочитать джингл (сохранённый в виде файла .wav) в массив. В файле есть некоторая дополнительная информацию вроде заголовков, метаданных и прочего, но нам нужен только звук. Подходящий формат называется PCM, это просто список чисел, представляющих звуки. Преобразовать WAV в PCM может ffmpeg:

ffmpeg -i input.wav -f s16le -acodec pcm_s16le output.raw

Здесь каждый сэмпл сохраняется в виде 16-битного числа с обратным порядком байтов (little endian). В Java такое число называется short, а для автоматического преобразования входного потока в список значений short можно использовать класс ByteBuffer:

ByteBuffer buf = ByteBuffer.allocate(4);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.put(bytes);
short leftChannel = buf.readShort(); // stereo stream
short rightChannel = buf.readShort();

Реверс-инжиниринг xcorr


Чтобы реализовать функцию xcorr() на Java, я изучил исходный код Octave. Не изменяя конечный результат, я смог заменить вызов xcorr() следующими строчками — их нужно переписать на Java:

N    = length(audio);
M    = 2 ^ nextpow2(2 * N - 1);
pre  = fft(postpad(prepad(jingle(:), length(jingle) + N - 1), M));
post = fft(postpad(audio(:), M));
cor  = ifft(pre .* conj(post));
R    = real(cor(1:2 * N));

Выглядит страшновато, но большинство функций — тривиальные операции с массивами. В основе кросс-корреляции лежит применение быстрого преобразования Фурье на звуковом образце.

Быстрое преобразование Фурье


Как человек, который не имел опыта работы с DSP, я просто рассматриваю FFT как функцию, которая берёт массив с описанием звукового образца — и возвращает массив с комплексными числами, представляющими частоты. Такой минималистичный подход хорошо сработал: я запустил реализацию FFT из пакета JTransforms и получил те же результаты, что в Octave. Я думаю, здесь отчасти карго-культ, но блин, это работает!

Запуск xcorr на потоке


Алгоритм выше предполагает, что audio представляет собой массив, в котором мы ищем jingle. Это не совсем подходит для радиотрансляции, где у нас непрерывный поток звука. Чтобы запустить анализ, я создал циклический буфер чуть больше, чем продолжительность джингла, который нужно распознать. Входящий поток заполняет буфер, и как только он заполнен, запускается тест кросс-корреляции. Если ничего не найдено, то самая старая часть буфера отбрасывается — и снова ожидаем его заполнения.

Я немного поэкспериментировал с длиной буфера и получил наилучшие результаты с размером буфера в 1,5 раза больше размера джингла.

Объединяем всё вместе


Получить поток в формате PCM несложно. Это можно сделать с помощью вышеупомянутого ffmpeg. Команда ниже перенаправляет поток на стандартный вход java, а затем выводит Got jingle 0 или Got jingle 1, когда в потоке найден соответствующий образец.

ffmpeg -loglevel -8        -i http://stream3.polskieradio.pl:8904/\;stream        -f s16le -acodec pcm_s16le -   | java -jar target/analyzer-1.0.0-SNAPSHOT-jar-with-dependencies.jar     2     src/test/resources/commercial-start-44.1k.raw 500     src/test/resources/commercial-end-44.1k.raw 700

Автономная версия


Я также подготовил простую автономную версию анализатора, которая сама подключается к потоку «Тройки» (без внешнего ffmpeg) и воспроизводит результат с помощью javax.sound. Всё вмещается в один файл JAR и содержит базовый пользовательский интерфейс с кнопками Star и Stop. Его можно скачать здесь. Если не любите запускать на своей машине чужие JAR (что совершенно правильно), то все исходники лежат на GitHub.



Похоже, всё работает как надо :)

Дальнейшая работа


Конечная цель — отключить рекламу на уровне аппаратного усилителя, получая «реальный» FM-сигнал, а не некий интернет-поток. Об этом рассказано в следующей статье.

Обновление (июнь 2018)


Обсуждение на Hacker News
Обсуждение на Wykop
Обсуждение на Reddit

Комментарии (57)


  1. Alozar
    27.06.2018 18:22
    +1

    Вот бы ещё Adblock для телевизора сделали… хотя я знаю его, он называется torrent


    1. alexyr
      27.06.2018 18:47
      +4

      Только надо искать торренты с надписью «без рекламы», а то достали всякие казино вставлять!


      1. Alozar
        27.06.2018 18:47

        вы забыли про регистрацию и смс


      1. Lertmind
        27.06.2018 20:56
        +1

        У нормальных студий озвучки (в основном сериалы) есть только две вставки аудио рекламы и присутствует оригинальная дорожка. Вычищают эту рекламу редко и не сразу. Если бы была программа, которая сравнивает дорожки и вставляет кусок оригинала на место рекламы, это бы всё упростило. Только нужен поиск не по известных вставкам, а по отсутствую голоса в оригинале.
        Может уже есть готовое?


    1. AfrinSoft
      28.06.2018 10:12

      15 лет назад серийно выпускали телевизоры с функцией стоп-реклама. И это было в России.
      www.nkj.ru/archive/articles/2815
      moskva-televizor.ru/tv.php?buy=Rekord-37TTs-5173
      После выпуска первой же партии в 20 тысяч телевизоров, разошедшейся как горячие пирожки, завод вместе с кб и патентами был стремительно выкуплен офшорным инвестором и тут же обанкрочен. В данный момент на бывшей территории александровского завода расположен торгово-развлекательный центр.


      1. DMGarikk
        28.06.2018 11:25

        очень я сомневаюсь что это произошло из-за стоп-рекламы


        1. immaculate
          28.06.2018 12:41

          Кто знает… Вот похожая история, тоже, кстати, из статьи в Науке и Жизни:


          Причина в том, что акции двух основных российских производителей алюминиевой продукции — Самарского и Белокалитвенского металлургических комбинатов — выкуплены американской фирмой "ALKO". Значительная часть оборудования на предприятиях демонтирована, технологическая цепочка нарушена, квалифицированные кадры разошлись, и производство фактически прекратилось. Сейчас эти предприятия выпускают в основном фольгу, которая идет на изготовление пищевых банок и упаковок…

          https://www.nkj.ru/archive/articles/10700/


          1. DMGarikk
            28.06.2018 12:47

            ну одно дело металлургия, где серьезная конкуренция на фоне монопольной структуры рынка, а другое какието телевизоры, где дешевле было бы заплатить за удаление этой функции чем покупать и банкротить завод с оборудованием которое проще выкинуть на свалку чем продать даже на металлолом
            сдается мне что все эти старые советские заводы тупо не смогли перестроить производство в силу консерватизма, а как появилась возможность все это комуто сбагрить то этим и воспользовались… учитывая что конкурировать с китаем на этом рынке бесмысленно вообще, тут никакая антиреклама бы их не спасла


          1. Kanut79
            28.06.2018 13:27

            Как насчёт вот этого: www.telefairy.com?


            1. mickvav
              28.06.2018 17:30

              Оно не продается. Все ссылки на «Купить» — битые.


              1. Kanut79
                28.06.2018 20:19

                Она продаётся: www.fernsehfee.de/shop.html

                Вот только поскольку телевизор здеь смотрят всё меньше народа и всё больше переходят на video on demand и streаm, то долго они скорее всего не протянут.


      1. alsov
        28.06.2018 12:10

        лет 10 назад был у меня ТВ-тюнер, в софте которого была возможность выреза рекламы. очень классная штука. гасила звук и затеняла экран.
        алгоритм был простой и основан на том, что во время рекламы лого канала прячется.
        в базе была куча разных лого + возможность подпихнуть свой.
        а потом каналы лого начали делать полупрозрачными и перестали прятать…


        1. DMGarikk
          28.06.2018 12:49

          в некоторых блоков рекламы есть звуковая метка (для вставки региональных блоков), можно ориентироваться на нее… если ее отслеживать можно около 50% рекламы фильтровать


        1. dext63r
          28.06.2018 12:53

          Т.е. это уже было сильно раньше.
          Интересно.


      1. Javian
        28.06.2018 14:38

        Для этого во время показа рекламной информации с экрана убирают логотип канала. Именно этот «признак» рекламы используется нашим приспособлением.

        Сейчас не убирают логотип. В те времена был плагин для тюнеров Beholder
        Плагин BPP_LogoDetector сравнивает фрагмент телевизионного изображения с шаблоном загруженного логотипа канала и при исчезновении логотипа с экрана позволяет приглушить звук или, если в данный момент ведётся запись телепередачи, включить паузу. В результате, плагин позволяет сэкономить до 30% места при записи на диск, отсекая рекламные заставки, транслируемые без логотипа основного канала, а обычный просмотр сделать более комфортным.


  1. Neuromantix
    27.06.2018 19:28
    +4

    Хочу универсальный адблок в реалтайме по аудио и визуальным каналам.


    1. SandroSmith
      27.06.2018 20:08
      +3

      Black Mirror подсказывает, что это может быть плохой идеей


      1. Neuromantix
        27.06.2018 21:02
        +2

        Так с полным моим контролем, и полностью оффлайновый — никаких облаков и прочего. Обработка всего в носимой железке.


    1. Konachan700
      27.06.2018 21:06
      +4

      Очки антибезысходности. Вместо мусорной кучи дорисовывают жилище хоббитов, по луже во дворе плавают кораблики, на грязном месиве «газона» проходят гонки миниатюрных джипов, на серое небо накладываются красивые текстуры облаков, на месте промзоны рендерится море и острова… Эх, дождемся такого или нет…


      1. uu_69
        27.06.2018 21:30

        Диппочтой из Аргентины?)


      1. immaculate
        28.06.2018 03:41

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


        1. rustavelli
          28.06.2018 23:45

          Лужа на асфальте — это дефект дорожного покрытия. Их там в принципе никогда быть не должно. Так что с официальной точки зрения, лужа — это однозначно плохо.


          1. immaculate
            29.06.2018 05:21

            Собственно, ваш комментарий является отличной иллюстрацией к тезису. «Официальная точка зрения» мало чем отличается от коллективной галлюцинации, если начать анализировать.


      1. radtie
        28.06.2018 09:25

        Не Black Mirror единым:

        image


      1. ru1z
        28.06.2018 09:51

        Признаться, мне наушники помогают (особенно, если что-то интересное). Не знаю как это работает, но очень здорово переключают, особенно со скучно-рутинной действительности)


      1. mickvav
        28.06.2018 17:32

        Повидло!


  1. dim133
    27.06.2018 20:12

    Если рекламные блоки действительно громкие, можно попробовать ловить начало рекламы по увеличению мощности сигнала.


    1. port443
      27.06.2018 20:53

      Там даже не сколько громкость, сколько компрессия как правило резко выше. Можно по этому признаку пытаться ловить.


      1. vlreshet
        28.06.2018 00:13

        Плохо в этом разбираюсь, но разве для того чтобы узнать уровень компрессии не надо иметь исходный файл + перекодированный (сжатый) файл? Сжатый у нас есть — радио, а оригинал?


        1. port443
          28.06.2018 00:32
          +1

          Я имел ввиду компрессию звука. Как раз это, мне кажется, средствами DSP определить не сложно.


  1. huhen
    27.06.2018 20:37

    На части радиостанций(как минимум у которых расчет на региональную ретрансляцию) в начале и конце рекламного блока идет специальная DTMF метка.


    1. jukkagrao
      27.06.2018 21:58

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


      1. iig
        28.06.2018 08:31

        Я читал, что длина рекламного блока на ТВ стандартная, или кратная стандартной. Чтобы без проблем вставлять местную рекламу. На радио не так?


  1. Murimonai
    27.06.2018 21:42

    Эм, то есть получается играет-играет нормальная музыка, все хорошо и потом резко становится тихо минут эдак на пять? Вот так задумывалось? Может лучше было не вырезать поток, а тушить ему громкость раза в два?


    1. Thoth777
      28.06.2018 04:56

      можно записывать поток и воспроизводить его часть в момент рекламы


    1. Andy_Big
      28.06.2018 07:30
      +1

      В примере результата по ссылке как раз приглушается громкость.


    1. zigrus
      28.06.2018 10:11

      я бы в этот блокировщик добавил и несколько песен, которые раздражают не хуже рекламы.


    1. Germanets
      28.06.2018 17:06

      Можно подменять своим потоком на это время…


  1. zxweed
    28.06.2018 00:32
    +1

    вспоминается проект по подавлению тв-рекламы (чуваки заморочились и собрали базу актуального спама и сделали приставку, которая переключает каналы при поступлении сигнала по интернету) — так он разорился попросту из-за того, что «обычному человеку» (tm) на самом деле нравится смотреть рекламу, многие бы круглыми сутками совершенно добровольно смотрели рекламу стирального порошка типа «тогда мы идем к вам»


    1. DenMMM
      28.06.2018 07:42

      Просто на нашем ТВ реклама интереснее остального содержания. :)


      1. iig
        28.06.2018 08:48

        Вырезать рекламу — половина проблемы. Нужно ещё чем-то заполнить вырезанное место.


        1. PavelMSTU
          28.06.2018 20:03

          А сейчас пять минут английского языка.
          Повторяйте за диктором: «London is the capital of Great Britain… London is the capital of Great Britain...»


    1. zigrus
      28.06.2018 10:12

      у того проекта была проблема в позиционирование продукта
      там что про про слежку за тем что смотрит телезритель…


  1. mediamango
    28.06.2018 10:12

    интересно, а неужели по DTMF-меткам не проще это было сделать? или они не везде используются?


  1. Delsian
    28.06.2018 12:43

    Проблема не только в рекламе. Радиостанции еще берут на работу ведущих-имбецилов, и приходится переключаться на другую станцию, как только после музыки начинаются их дебильные комментарии и гы-гы-гы. Не представляю, как такое можно отфильтровать.


    1. dext63r
      28.06.2018 12:58

      Нахожу плейлисты «музыка с радио ***»
      Раньше в яндекс-радио подобная фишка была.
      Жалко что радио-каналы нажаловались и подобную возможность выпилили.


    1. cmd01
      28.06.2018 14:43

      Есть интернет радиостанции. Реклама отключается что то за 1 евро в месяц. Мне нравится 1.fm это не реклама… просто для примера .


  1. andersong
    28.06.2018 13:13

    Насколько я помню, был проект по резке рекламы на ТВ, основанный на определении отображения значка телеканала в углу экрана (во время рекламы он не выводится), но его тоже зарубили.


  1. besisland
    28.06.2018 13:50

    Если не ошибаюсь, когда стали появляться такие приспособления для телевизоров, телеканалы просто стали делать не две заставки-маркера (начало и конец рекламного блока), а иногда три (кусочек заставки в середине блока), иногда две, иногда четыре.


    1. DMGarikk
      28.06.2018 15:57

      эти маркеры нужны для того чтобы правильно работало оборудование которое делает врезку местной рекламы на федеральных каналах


  1. PavelMSTU
    28.06.2018 20:09

    Давайте начистоту. Без понтов, но профессионал-датасаентист + хороший прогер (можно даже в одном лице) решат проблему рекламы с +99% точностью и +85% полнотой…

    Вопрос: ПОЧЕМУ это до сих пор не сделали????


    1. iig
      28.06.2018 23:33

      Потому что это не решение. Заменить рекламные вставки курсами английского можно. Только пользы от таких курсов, нарезанных роботом фрагментами по 40 секунд, будет меньше чем от рекламы.


      1. vedenin1980
        29.06.2018 00:03

        Можно включать любимые видео клипы, или вообще записывать канал и показывать с замедлением, скажем 20 минут. Тогда будет возможность не только рекламу вырезать, но постаить на паузу и сходить чай сделать.

        P.S. На самом деле. есть подозрение. что мало кто хочет вырезать рекламу, так во время рекламных пауз занимается своими делами, то есть «вырезает ее и так в ручном режиме»


    1. Kanut79
      29.06.2018 09:31

      Потому что как показывает как минимум мой опыт это на самом деле мало кому нужно.
      Есть куча людей которым реклама просто не мешает настолько чтобы они начали об этом задумываться и/или были бы готовы платить деньги за какой-то инструмент по «выпиливанию рекламы».
      А для тех, кто готов потратить деньги чтобы от рекламы избавиться, есть просто другие варианты решения этой проблемы. Например платные источники контента, которые просто не используют рекламу.


  1. iig
    29.06.2018 00:11

    "включать любимые видео клипы"


    Так себе решение. Смотришь футбол, или фильм… и тут… та-да-бумсь!


    1. vedenin1980
      29.06.2018 00:27

      Имел в виду музыкальные. Ну или смешные ролики с ютуба. Можно в начале и конце поставить свою заставку, чтобы та-да-бумсь не было. Как будто реклама не делает этот та-да-бумсь, особенно если рекламу вставляют неожиданно и с вкрученным звуком.


      1. iig
        29.06.2018 09:44

        Если задача сводится к трансляции своего плейлиста, то она уже решена :))