Как стать автором
Обновить

Сетевое вещание — работаем с кодировками

Время на прочтение7 мин
Количество просмотров2.3K
Подключившись к Корбине (нет, это не реклама), и ради интереса просматривая их сайт, я наткнулся на большое количество интернет-радиостанций, к коим попытался немедленно пристраститься. Разочарование мое было велико. Я не нашёл ни одного плеера, который бы нормально работал с кодировкой тэгов потока. Последней надеждой был VLC, но он оказался хуже всех — получил только общую информацию о потоке, но не стал получать передаваемую сервером информацию о текущей композиции.
Mplayer выдал мне в консоль следующее:
torkvemada@inquisitia-nout ~ $ mplayer 85.21.79.5:8185/listen.pls
MPlayer 1.0rc2-4.3.3 (C) 2000-2007 MPlayer Team
CPU: Intel(R) Atom(TM) CPU N270 @ 1.60GHz (Family: 6, Model: 28, Stepping: 2)
CPUflags: MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
Compiled with runtime CPU detection.
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing 85.21.79.5:8185/listen.pls.
Resolving 85.21.79.5 for AF_INET6...
Couldn't resolve name for AF_INET6: 85.21.79.5
Connecting to server 85.21.79.5[85.21.79.5]: 8185...
Cache size set to 320 KBytes

Playing 85.21.79.5:8185/.
Resolving 85.21.79.5 for AF_INET6...
Couldn't resolve name for AF_INET6: 85.21.79.5
Connecting to server 85.21.79.5[85.21.79.5]: 8185...
Name : 101.ru: Aquarium BG
Genre : N/A
Website: www.101.ru
Public : yes
Bitrate: 0kbit/s
Cache size set to 320 KBytes
Cache fill: 0.00% (0 bytes)
ICY Info: StreamTitle='ÀÊÂÀÐÈÓÌ - Íàóêè Þíîøåé - 0:00';StreamUrl='';
Cache fill: 15.00% (49152 bytes)
Audio file file format detected.
==========================================================================
Forced audio codec: mad
Opening audio decoder: [libmad] libmad mpeg audio decoder
AUDIO: 44100 Hz, 2 ch, s16le, 96.0 kbit/6.80% (ratio: 12000->176400)
Selected audio codec: [mad] afm: libmad (libMAD MPEG layer 1-2-3)
==========================================================================
AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...
A: 27.8 (27.8) of -0.0 (unknown) 3.7% 45%
ICY Info: StreamTitle='ÀÊÂÀÐÈÓÌ - Âåëèêèé Äâîðíèê - 0:00';StreamUrl='';
A: 212.2 (03:32.2) of -0.0 (unknown) 3.7% 45%
ICY Info: StreamTitle='ADVBEGIN - ADVBEGIN - 0:00';StreamUrl='';
A: 213.5 (03:33.5) of -0.0 (unknown) 3.7% 45%
ICY Info: StreamTitle='ADV_0001 - 0:00';StreamUrl='';
A: 243.6 (04:03.5) of -0.0 (unknown) 3.7% 45%
ICY Info: StreamTitle='ADVENG - ADVENG - 0:00';StreamUrl='';
A: 247.7 (04:07.6) of -0.0 (unknown) 3.7% 45%
ICY Info: StreamTitle='ÀÊÂÀÐÈÓÌ - Áëþç Ïðîñòîãî ×åëîâåêà - 0:00';StreamUrl='';
A: 348.7 (05:48.7) of -0.0 (unknown) 3.6% 45%
Exiting... (Quit)

Как видим, вся информация получается, но кодировку cp1251 mplayer распознать оказался не в состоянии. Как и все остальные плееры. Схожая ситуация, кстати, с высокой вероятностью повторилась бы в Windows, достаточно было бы только найти поток с UTF-8. Но у нас, к счастью, есть возможность исправить ситуацию. За час копания в исходниках mplayer и пару перекомпиляций (увы, мой атом оставляет желать лучшего в плане скорости компиляции) я набросал маленький патч, который позволит параметром командной строки указать, в какой же кодировке к нам приходит поток и выводит информацию в правильной кодировке. Патч использует iconv, поэтому при желании может быть приспособлен к абсолютно любому плееру, для показа как id3-тэгов, так и информации о потоке, в вашей linux-системе.
Всё дальнейшее руководство относится к APT-системам (Ubuntu, Debian, возможно, AltLinux etc.), но его легко повторить на произвольной системе.
Выполняем `apt-get source mplayer`, чтобы получить исходники mplayer.
Заходим в получившийся каталог (у меня это mplayer-1.0~rc2) и правим файлы:
  • cfg-common.h:
    Добавляем где-нибудь на 90-ой строке
    1. #ifdef USE_ICONV
    2.         {"tagcp", &tag_cp, CONF_TYPE_STRING,  0,  0,  0, NULL},
    3. #endif
  • libass/ass_mp.c:
    Добавляем на 36-ой строке:
    1. #ifdef USE_ICONV
    2. extern char* tag_cp;
    3. #else
    4. static char* tag_cp = 0;
    5. #endif
  • stream/stream.h:
    Добавляем на 302-ую строку:
    1. extern char * tag_cp;
  • stream/http.c:
    Добавляем на 30-ой строке:
    1. #ifdef USE_ICONV
    2. #include <iconv.h>
    3. char *tag_cp = 0;
    4. #endif

    И на 121 строке (после строчки "info[len] = 0;"):
    1. #ifdef USE_ICONV
    2.     iconv_t iconv_converter = (iconv_t)(-1);
    3.     char *outcp = "UTF-8";
    4.     char *incp = tag_cp;
    5.     if (tag_cp && (iconv_converter == (iconv_t)(-1)))
    6.     {
    7.             if ((iconv_converter = iconv_open (outcp, incp)) == (iconv_t)(-1))
    8.             {
    9.                     mp_msg(MSGT_DEMUXER, MSGL_ERR, "ICY: can't open iconv.);
    10.             }
    11.     }       
    12.     if (iconv_converter != (iconv_t)(-1))
    13.     {       
    14.             size_t tmp_conv_len = nlen * 4;
    15.             size_t conv_len = tmp_conv_len;
    16.             size_t tmp_len = nlen;
    17.             char *tmp_info = info;
    18.             char *converted_info = (char*)malloc(conv_len + 1);
    19.             if (!converted_info)
    20.                     mp_msg(MSGT_DEMUXER, MSGL_ERR, "ICY: can't allocate memory.);
    21.             char *tmp_conv_info = converted_info;
    22.             if ((conv_len = iconv(iconv_converter, &tmp_info, &tmp_len, &tmp_conv_info, &tmp_conv_len)) == (size_t)(-1))
    23.             {
    24.                    mp_msg(MSGT_DEMUXER, MSGL_WARN, "ICY: error while iconving info.);
    25.                     free(converted_info);
    26.                     (void)iconv_close(iconv_converter);
    27.             }       
    28.            else    
    29.             {       
    30.                     *tmp_conv_info='\0';
    31.                     free(info);
    32.                     info = converted_info;
    33.                     (void)iconv_close(iconv_converter);
    34.                     iconv_converter = (iconv_t)(-1);
    35.             }
    36.     }
    37. #endif /* USE_ICONV */


Теперь осталось собрать и установить. Набираем `debuild` и либо получаем ругань на недостающие пакеты (устанавливаем их и запускаем debuild снова), либо через некоторое время имеем несколько собранных деб-пакетов. Устанавливаем: `sudo dpkg -i ../mplayer_1.0~rc2-0ubuntu19+medibuntu1_i386.deb` и фиксируем, чтобы пакетный менеджер не вздумал переустановить пакет из репозитория: `sudo aptitude hold mplayer`.
Ленивые могут скачать:

Теперь указываем параметр `tagcp` и наслаждаемся:
torkvemada@inquisitia-nout ~ $ mplayer -tagcp cp1251 85.21.79.5:8185/listen.pls
MPlayer 1.0rc2-4.3.3 (C) 2000-2007 MPlayer Team
CPU: Intel(R) Atom(TM) CPU N270 @ 1.60GHz (Family: 6, Model: 28, Stepping: 2)
CPUflags: MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
Compiled with runtime CPU detection.
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing 85.21.79.5:8185/listen.pls.
Resolving 85.21.79.5 for AF_INET6...
Couldn't resolve name for AF_INET6: 85.21.79.5
Connecting to server 85.21.79.5[85.21.79.5]: 8185...
Cache size set to 320 KBytes

Playing 85.21.79.5:8185/.
Resolving 85.21.79.5 for AF_INET6...
Couldn't resolve name for AF_INET6: 85.21.79.5
Connecting to server 85.21.79.5[85.21.79.5]: 8185...
Name : 101.ru: Aquarium BG
Genre : N/A
Website: www.101.ru
Public : yes
Bitrate: 0kbit/s
Cache size set to 320 KBytes
Cache fill: 0.00% (0 bytes)
ICY Info: StreamTitle='АКВАРИУМ - Заповедная Песня - 0:00';StreamUrl='';
Cache fill: 15.00% (49152 bytes)
Audio file file format detected.
==========================================================================
Forced audio codec: mad
Opening audio decoder: [libmad] libmad mpeg audio decoder
AUDIO: 44100 Hz, 2 ch, s16le, 96.0 kbit/6.80% (ratio: 12000->176400)
Selected audio codec: [mad] afm: libmad (libMAD MPEG layer 1-2-3)
==========================================================================
AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...
A: 14.9 (14.8) of -0.0 (unknown) 6.6% 45%
ICY Info: StreamTitle='АКВАРИУМ - Песня №2 - 0:00';StreamUrl='';
A: 19.8 (19.8) of -0.0 (unknown) 6.5% 46%
Exiting... (Quit)
Теги:
Хабы:
+29
Комментарии47

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн