Умная ретрансляция [wget > fifo > ices0 > icecast]

    Давайте поговорим немного про умную ретрансляцию mp3 потоков?
    Возникла необходимость сделать качественный mp3 relay с четырех нестабильных источников (которые транслируют одно и то же), в основном для себя.
    Возьмем, к примеру, KissFM. Есть 4 источника, которые периодически отваливаются (три потока звука одинаково хорошие и один похуже).

    На данный момент реализация такая:
    #!/bin/sh

    #убиваем активные процессы, если есть. kisswget это symlink wget, чтоб не убить лишнего в случае чего
    pkill ices
    pkill kisswget

    #убиваем fifo (в общем-то можно и не убивать, но я решил перестраховаться)
    rm /home/random2/ices/kiss

    #создаем fifo
    mkfifo /home/random2/ices/kiss
    #запускаем ices, у которого источником стоит /home/random2/ices/kiss, он же отдает stream серверу icecast
    ices -c /home/random2/ices/ices.conf

    #самая интересная и спорная часть: тащим поток с помощью wget (kisswget) в /home/random2/ices/kiss
    #этот способ позволяет "переключить" исходный поток в случае обрыва связи, или ответа 403/404, например

    while :
    do
    /home/random2/ices/kisswget httр://195.138.217.65:8000/kissfm -O /home/random2/ices/kiss
    /home/random2/ices/kisswget httр://media.wnet.ua:8000/kissfm -O /home/random2/ices/kiss
    /home/random2/ices/kisswget httр://217.20.164.164:8000/kissfm -O /home/random2/ices/kiss
    done


    Недостатки, которые я вижу на данный момент:
    • wget
    • тут нет четвертого потока (тот, что похуже качеством). Хочется чтобы в случае если первые три потока не доступны и играет четвертый, при «появлении» одного из первых трех wget автоматически переключался на него. При этом не хочется сложных велосипедов.
    • не прикручен current song title, в данной реализации вижу только отдельный скрипт для него, который будет брать откуда-то инфу и подсовывать её icecast как metadata

    Небольшая справка: «FIFO» (first in, first out) представляет собой специальный тип файла, который позволяет оперировать с ним двум независимым процессам. Один процесс открывает fifo-файл для записи, а другой для чтения, после чего данные «плывут» через него. В *nix системах создается командой mkfifo.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 28

      +1
      Вот наговнокодил немного:

      <?
      $ctx 
      stream_context_create(array('http' => array('timeout' => 10)));
      $kiss_site=file_get_contents('http://kissfm.ua/',,$ctx);
      $kiss_div1=split("<div class="onAirString">",$kiss_site);
      $kiss_div2=split("</div>",$kiss_div1[1]);
      $kiss_div2=preg_replace(array(=>"/- - -/",1=>"/сейчас в эфире/"),"",$kiss_div2);
      $update=file_get_contents('http://random:7777@random.net.ua:8000/admin/metadata.xsl?song='.trim(urlencode($kiss_div2[])).'&mount=%2Fkissfm&mode=updinfo',,$ctx);

      $procs=shell_exec('ps aux | grep kisswget');
      $procs=explode("n",$procs);
      foreach ( 
      $procs as $procs_) if (strstr($procs_,'/home/random2/ices/kiss')) $procs_kiss[]=$procs_;

      if (
      count($procs_kiss) > 1)
      {
          
      $ans=shell_exec('/usr/bin/pkill kisswget');
          die(
      'more then one kisswget');
      }
      if (!
      strstr($procs_kiss[],"91.202.72.22:8000")) die('nothing todo');

      $links=array(
      'http://195.138.217.65:8000/kissfm',
      'http://media.wnet.ua:8000/kissfm',
      'http://217.20.164.164:8000/kissfm'
      );

      foreach (
      $links as $links_)
      {
          @
      $f=file_get_contents($links_,,$ctx,-1,1);
          if (
      strpos($http_response_header[],'200'))
          {
              
      $ans=shell_exec('/usr/bin/pkill kisswget');
              die();
          } 
      }
      ?>
        +2
        парсер — лох.
        в некоторых местах посъедал цифру «0»
        +1
        А не судьба для ретрансляции использовать icecast?
          0
          хочется постоянной точки монтирования.
            0
            Насколько я помню Icecast такое позволяет ;)
              0
              ага, relay это и делает, недостато тока один — не умеет wma(mms://)
          +1
          Достаточно одного icecast и fallback mount-point'ов в конфиге. Icecast автоматически переключается на fallback маунты, если вышестоящие не работают.
            0
            Получается я велосипед изобрел.
            Но в случае с fallback-mount получается 4 разных mount points. Да и люди пишут что для relay оно не очень.
              0
              Что не очень-то? Fallback как fallback. Вообще, отваливается интернет-канал у вас, я так понимаю? В этом случае самое оптимальное — большой пребуффер.
                0
                fallback-mount
                This optional value specifies a mountpoint that clients are automatically moved to if the source shuts down or is not streaming at the time a listener connects. Only one can be listed in each mount and should refer to another mountpoint on the same server that is streaming in the same streaming format.
                If clients cannot fallback to another mountpoint, due to a missing fallback-mount or it states a mountpoint that is just not available, then those clients will be disconnected. If clients are falling back to a mountpoint and the fallback-mount is not actively streaming but defines a fallback-mount itself then those clients may be moved there instead. This multi-level fallback allows clients to cascade several mountpoints.

                A fallback mount can also state a file that is located in webroot. This is useful for playing a pre-recorded file in the case of a stream going down. It will repeat until either the listener disconnects or a stream comes back available and takes the listeners back. As per usual, the file format should match the stream format, failing to do so may cause problems with playback.

                Note that the fallback file is not timed so be careful if you intend to relay this. They are fine on slave streams but don't use them on master streams, if you do then the relay will consume stream data at a faster rate and the listeners on the relay would eventually get kicked off.
                  0
                  отваливается не канал, периодически отваливаются источники — не очень у kissfm с трансляцией.
                  собственно ради этого я и задался вопросом, как сделать себе максимально прозрачную стабильную ретрансляцию.
                    0
                    Ретранслируй прямо с радио!
                      0
                      Если бы оно вещало в моём городе :(
                      А сервер вообще в Киеве стоит в датацентре. Оно не на столько критично чтоб туда fm-тюнер тулить.
                  +1
                  В настройках маунтпоинта добавь

                  <on-demand>0</on-demand>
                  <relay-shoutcast-metadata>1</relay-shoutcast-metadata>


                  и твой релей будет показывать «current song»
                    0
                    некоторые источники отдают не правильную current song, поэтому я её с сайта решил парсить.
                    0
                    У нас в сети сделан сервер для ретрансляции радио (около 200 штук на on-demand), часто ставлю по 2-3 источника. Проблем не замечал, так что фаллбеки можно смело использовать :)
                      0
                      покажите конфиг, пожалуйста
                        0
                        если можно :)
                          0
                          Ну а почему нет :)

                          Сначала делаем первый релей:

                               <relay>
                                 <server>radio.sibrave.ru</server>
                                 <port>8000</port>
                                 <mount>/record.mp3</mount>
                                 <local-mount>/radio_record</local-mount>
                                 <on-demand>1</on-demand>
                                 <relay-shoutcast-metadata>1</relay-shoutcast-metadata>
                               </relay>
                          

                          И точку монтирования:

                              <mount>
                                 <mount-name>/radio_record</mount-name>
                                 <fallback-mount>/radio_record_1</fallback-mount>
                                 <fallback-override>1</fallback-override>
                              </mount>
                          


                          А это второй релей, на который пойдет переключение, если первый умер.
                          fallback-mount (выше) = local-mount для него:

                              <relay>
                                 <server>radio.global.by</server>
                                 <port>8888</port>
                                 <mount>/radio_record</mount>
                                 <local-mount>/radio_record_1</local-mount>
                                 <on-demand>1</on-demand>
                                 <relay-shoutcast-metadata>1</relay-shoutcast-metadata>
                               </relay>
                          


                          Если потребуется еще один источник, опять добавляем конструкцию mount для перехода и еще один релей.
                            0
                            если отвалится /record.mp3 юзверей кинет на /radio_record тоесть mount сменится, а мне надо постоянный (
                              0
                              Сейчас проверил (винампом), в свойствах потока адрес не менялся.
                                0
                                да, зря шаманил :)
                                  0
                                  таки да, всё работает.
                                  но:
                                  1. на странице статистики icecast висят всё fallback-маунты. ну хрен бы с ними
                                  2. когда поднимается первый поток из списка, icecast всё равно продолжает вещать как ни в чем не бывало с текущего.
                                  3. начинается что-то ненормально если лежат три потока и работает только четвертый. и пытаешся подключиться к icecast по адресу первого потока.
                                    0
                                    1. Как вариант, делать свою страничку статистики.
                                    2. Это да. Хотя если трансляция on-demand, при отключении и подключении клиента по идее должен вернуться на первый.
                                    3. С четырьмя не пробовал, а что там происходит такое?
                                      0
                                      3. не играет. в логах пишет что пытается пройти по списку маунтов.
                                      винамп «переспрашивает» раньше чем появляется поток (я так думаю)
                    0
                    За трюк с симлинком и pkill-ом спасибо! Для некоторых одноразовых задач лень было создавать файлы.pid и приходилось идти на риск грохнуть что-нибудь не то. А тут так просто ;)
                      0
                      Я больше от mkfifo прусь :)
                      0
                      Может немножко не в тему, но все же…

                      Достаточно стабильный поток KissFM из г. Николаева с битрейтом 256, авось пригодится (:

                      http://live.amron.com.ua:8000/KISS_FM_Nikolaev

                      Only users with full accounts can post comments. Log in, please.