В чем суть?
У меня нет обычного зомбо-телевидения — я не смотрю эфирные каналы уже лет 7, чему несказанно рад и вам советую. Для вечернего диванного времяпрепровождения после трудового дня дома имеется полный стек продуктов от яблочной компании — начиная с компьютера-лаптопа и заканчивая тв-приставкой (подключенной к обычному 34" телевизору по HDMI). Все это между собой прекрасно работает и дружит, а используя некоторые онлайн-сервисы я вообще могу смотреть любимые сериалы прямо из интернета и не качая торренты. Жилось-былось мне так вполне хорошо, но вот в России проводят Олимпиаду, а тут еще и тесть приехал — заядлый спортсмен. Хочется посмотреть Игры! И таким вот образом образовалась задача — обеспечить качественный показ спортивных передач (то есть не на экране мобильного телефона), которые идут на нескольких эфирных каналах и все это используя подручные средства. И чтобы не очень долго и сложно было реализовывать.
Здесь надо сделать небольшое лирическое отступление. Указанная выше технологическая платформа «из коробки» никак-никак не умеет воспроизводить эфирные каналы на телевизоре. С другой стороны пчелиный интернет-провайдер (к которому я подключен) предоставляет фирменное мобильное приложение где можно смотреть около 90 ТВ каналов бесплатно, просто введя логин/пароль от личного кабинета (что в последствии окажется совсем необязательным). Да, конечно, то самое мобильное приложение прекрасно умеет посредством проигрывания-через-воздух отображать картинку на телевизоре через тв-приставку (стандартная фишка яблочной компании), но здесь расстраивает одно большое НО — когда телефон/планшет уходит в спящий режим, воспроизведение останавливается. Вариант же тыкать пальцем в экран телефона каждую минуту, мягко сказать неудобен. С другой стороны при воспроизведении видеопотока через системные или некоторые другие приложения и выключении мобильника все ок. Собственно, возник вопрос «как же так?». В общем, разбираться с приложением я оставил провайдеру, а ниже опишу как довольно таки быстро решил эту проблему.
Изучение вопроса
Первое, что необходимо было понять — как стримится видеопоток, а вернее даже не как, а откуда. Я было полез на роутер, изучать при помощи tcpdump, что откуда и куда ходит, но меня постигла неудача. Не очень я хорошо знаком с синтаксисом tcpdump, да и то, что я обнаружил (при помощи команд вроде tcpdump -i br0 host <MOBILEIP>
не впечатлило — какие-то коннекты по https на адреса которые ругаются требованием аутентифицироваться (естественно, логин/пароль от личного кабинета не прокатил). Поэтому я подумал поковыряться в самом приложении, но не так, чтобы дизассемблером или чем-то крутым, а обычным текстовым редактором — вдруг найдутся какие-либо интересности. За основу я взял приложение под Андроид (его легко найти в любом поисковике) и взял я его по одной простой причине — когда-то я даже делал несложные программки под эту платформу и примерно знаю из чего состоит пакет и как оно работает.
Ковыряние приложения
Всем известно, что сам apk-файл это всего-лишь zip в котором находятся ресурсы и скомпилированное java-приложение. Разархивировав пакет, я получил что-то вроде такого:
Не найдя ничего интересного в файлах ресурсов я принялся изучать главный файл приложения — classes.dex. Когда-то я даже умел декомпилировать такие файлы и получать более-менее понятный java-код, но в данном случае хотелось сделать все быстро и успеть до показа любимых тестем соревнований. Поэтому недолго думая, я выполнил простую команду vi classes.dex
(почему я не запустил strings classes.dex
плюс grep
— не знаю, не пришло в голову). Идея была в том, что приложению нужно же где-то авторизовывать пользователя, тем самым я найду первую ниточку (адрес сервера), а потом одно за другое и клубок распутается. Поиск по ключевому слову http дал слишком много вариантов часть из которых была названиями классов. Поиск по имени провайдера — тоже. Тогда я остановился на доменном имени провайдера и нашел первую ниточку — адрес frontend.iptv.провайдер.ru. Потом нашлась еще куча всяких адресов по названиям которых можно было судить, что тут вот пользователь как-то аутентифицируется в системе, а вот там приложение получает какие-то настройки. Среди этого добра внимание привлекла следующая запись:
Оказалось, что по указанному адресу находится обычный json-файл (к сожалению, неформатированный) в котором и содержится вся необходимая информация и даже чуточку больше: название канала, логотип и искомый адрес для стриминга видеопотока. Используя простые онлайн-сервисы (ведь хотелось быстро) я превратил json в удобочитаемый вид.
{
"Settings": {
"UseSecureMDSToken": "true",
"IsAuthOn": "true",
"IsGeoIPOn": "true",
"IsFlurryOn": "true",
"IsRJDetectorOn": "false",
"GeoIPGrants": "RU,UA,BY,NL,DE",
"ProtectedChannels": "28976,28982",
"TokenLifetime": 28800,
"Link2Streams": "",
"Link2Logos": "https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/",
"DefaultLogo": "https://interface.iptv.beeline.ru/PHP/images/DefaultLogo.png",
"Link2Posters": "https://interface.iptv.beeline.ru/PHP/images/posters_program/",
"DefaultPoster": "https://interface.iptv.beeline.ru/PHP/images/DefaultPoster.jpg",
"MDSVODCategoryId_AllMovies": "138",
"MDSVODCategoryId_Series": "433",
"EULA": "https://interface.iptv.beeline.ru/EULA.html"
},
"ServiceEndpoints_http": {
"AuthSSOUri": "https://auth.iptv.beeline.ru/api/auth",
"DashboardDataUri": "http://78.107.197.133/OTTWebService/",
"MDSAuthServiceBaseUri": "http://frontend.iptv.beeline.ru/MDSAuthWS/",
"MDSVODServiceBaseUri": "http://frontend.iptv.beeline.ru/MdsVodWS/",
"MDSListingServiceBaseUri": "http://frontend.iptv.beeline.ru/MDSListingsWS/",
"MDSDVRServiceBaseUri": "http://frontend.iptv.beeline.ru/MDSDvrDataWS/",
"MDSSearchServiceBaseUri": "http://frontend.iptv.beeline.ru/MDSSearchWS/",
"MDSSubscriberDataUri": "http://frontend.iptv.beeline.ru/MDSSubscriberDataWS/",
"MDSRatingsUri": "http://frontend.iptv.beeline.ru/MDSDiscoveryTables/Ratings.xml",
"MDSVodLicenseServerUri": "http://frontend.iptv.beeline.ru/LicenseServerProxy/rightsmanager.asmx",
"MDSLiveLicenseServerUri": "http://frontend.iptv.beeline.ru/LicenseServer/rightsmanager.asmx"
},
"ServiceEndpoints_https": {
"AuthSSOUri": "https://auth.iptv.beeline.ru/api/auth",
"DashboardDataUri": "http://78.107.197.133/OTTWebService/",
"MDSAuthServiceBaseUri": "https://frontend.iptv.beeline.ru/MDSAuthWS/",
"MDSVODServiceBaseUri": "https://frontend.iptv.beeline.ru/MdsVodWS/",
"MDSListingServiceBaseUri": "https://frontend.iptv.beeline.ru/MDSListingsWS/",
"MDSDVRServiceBaseUri": "https://frontend.iptv.beeline.ru/MDSDvrDataWS/",
"MDSSearchServiceBaseUri": "https://frontend.iptv.beeline.ru/MDSSearchWS/",
"MDSSubscriberDataUri": "https://frontend.iptv.beeline.ru/MDSSubscriberDataWS/",
"MDSRatingsUri": "https://frontend.iptv.beeline.ru/MDSDiscoveryTables/Ratings.xml",
"MDSVodLicenseServerUri": "https://frontend.iptv.beeline.ru/LicenseServerProxy/rightsmanager.asmx",
"MDSLiveLicenseServerUri": "https://frontend.iptv.beeline.ru/LicenseServer/rightsmanager.asmx"
},
"Errors": [
{
"label": "001",
"header": "Ошибка авторизации",
"body": "Связка логин/пароль введены не верно"
},
{
"label": "002",
"header": "Ошибка авторизации",
"body": "Аккаунт заблокирован"
},
{
"label": "003",
"header": "Ошибка авторизации",
"body": "Устройство не может быть подключено, т.к. достигнут лимит подключаемых девайсов на аккаунте"
},
{
"label": "004",
"header": "Ошибка авторизации",
"body": "Внутренняя ошибка сервиса авторизации"
},
{
"label": "005",
"header": "Ограничение доступа",
"body": "Доступ к выбранному разделу приложения из вашей страны запрещён"
},
{
"label": "006",
"header": "Внимание",
"body": "Вы переключились на мобильную сеть доступа. Тарификация осуществляется в соответствии с вашим тарифом на Интернет."
},
{
"label": "007",
"header": "Ошибка",
"body": "Возникла внутренняя ошибка идентификации устройства. Код ошибки: %error-code%"
},
{
"label": "008",
"header": "Ошибка",
"body": "Возникла внутренняя ошибка в процессе подключения устройства. Код ошибки: %error-code%"
},
{
"label": "009",
"header": "Ошибка",
"body": "Возникла внутренняя ошибка в процессе подключения к Mediaroom. Код ошибки: %error-code%"
},
{
"label": "010",
"header": "Ошибка",
"body": "Неудаётся разрезолвить имя сервера. Код ошибки: %server-type%"
},
{
"label": "011",
"header": "Ошибка",
"body": "Сервер недоступен. Код ошибки: %server-type%"
},
{
"label": "012",
"header": "Ошибка подключения",
"body": "Не удаётся подключиться к ТВ-приставке.rnВозможные причины:rn·tневерно введены IP-адрес ТВ-приставки и/или поле Ключrn·tотсутствует доступ по локальной сети между Вашим устройством и ТВ-приставкойrn"
},
{
"label": "013",
"header": "Ошибка 400",
"body": "Неверный запрос"
},
{
"label": "014",
"header": "Ошибка 401",
"body": "Ошибка аутентификации"
},
{
"label": "015",
"header": "Ошибка 402",
"body": "У вас нет прав на просмотр запрашиваемого контента"
},
{
"label": "016",
"header": "Ошибка 403",
"body": "Доступ запрещён"
},
{
"label": "017",
"header": "Ошибка 403.4",
"body": "Доступ по незащищённому каналу запрещён"
},
{
"label": "018",
"header": "Ошибка 404",
"body": "Контент не найден"
},
{
"label": "019",
"header": "Ошибка 409",
"body": "Запрашиваемая телепрограмма уже запланирована"
},
{
"label": "020",
"header": "Ошибка 412",
"body": "Нет возможности записать запрашиваемую телепрограмму"
},
{
"label": "021",
"header": "Ошибка 412",
"body": "Запрашиваемая телепрограмма не является сериалом или нет возможности записать запрашиваемую телепрограмму"
},
{
"label": "022",
"header": "Ошибка 500",
"body": "Внутренняя ошибка сервера"
},
{
"label": "023",
"header": "Ошибка 500",
"body": "Не удаётся получить данные о состоянии жёсткого диска приставки"
},
{
"label": "024",
"header": "Внимание",
"body": "Настройки приложения были обновлены, контент перезагружен"
},
{
"label": "025",
"header": "Конфликт записи",
"body": "Данная передача не может быть записана, так как на это же время запланировано слишком много записей"
},
{
"label": "026",
"header": "Внимание",
"body": "Данный канал недоступен для просмотра на мобильных устройствах"
}
],
"Channels": [
{
"order": 1,
"name": "Первый",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Perviy/hls/hls_perviy/index.m3u8",
"logo": "logo_Perviy.png",
"StationId": 28629
},
{
"order": 2,
"name": "Россия 1",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-1/hls/hls_russia-1/index.m3u8",
"logo": "logo_Russia-1.png",
"StationId": 28976
},
{
"order": 3,
"name": "Россия 2",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-2/hls/hls_russia-2/index.m3u8",
"logo": "logo_Russia-2.png",
"StationId": 28983
},
{
"order": 4,
"name": "НТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_NTV/hls/hls_ntv/index.m3u8",
"logo": "logo_NTV.png",
"StationId": 28982
},
{
"order": 5,
"name": "5 канал",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_5-kanal/hls/hls_5-kanal/index.m3u8",
"logo": "logo_5-kanal.png",
"StationId": 29126
},
{
"order": 6,
"name": "Россия К",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-K/hls/hls_russia-k/index.m3u8",
"logo": "logo_Russia-K.png",
"StationId": 29135
},
{
"order": 7,
"name": "Россия 24",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-24/hls/hls_russia-24/index.m3u8",
"logo": "logo_Russia-24.png",
"StationId": 28770
},
{
"order": 8,
"name": "Карусель",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Karusel/hls/hls_karusel/index.m3u8",
"logo": "logo_Karusel.png",
"StationId": 28718
},
{
"order": 9,
"name": "Sony HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Sony_HD/hls/hls_sony_hd/index.m3u8",
"logo": "logo_Sony_HD.png",
"StationId": 28935
},
{
"order": 10,
"name": "AXN Sci-Fi",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Sony_Sci-Fi/hls/hls_sony_sci-fi/index.m3u8",
"logo": "logo_AXN_Sci-Fi.png",
"StationId": 29106
},
{
"order": 11,
"name": "Sony Turbo",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Sony_Turbo/hls/hls_sony_turbo/index.m3u8",
"logo": "logo_Sony_Turbo.png",
"StationId": 132454
},
{
"order": 12,
"name": "Diva",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Diva/hls/hls_diva/index.m3u8",
"logo": "logo_Diva.png",
"StationId": 29080
},
{
"order": 13,
"name": "MGM HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-MGMHD/hls/mgmhd/index.m3u8",
"logo": "logo_MGM_HD.png",
"StationId": 28934
},
{
"order": 14,
"name": "Русский Иллюзион",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_RusIlluzion/hls/hls_rusilluzion/index.m3u8",
"logo": "logo_RusIlluzion.png",
"StationId": 29054
},
{
"order": 15,
"name": "Еврокино",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Evrokino/hls/hls_evrokino/index.m3u8",
"logo": "logo_Evrokino.png",
"StationId": 28640
},
{
"order": 16,
"name": "Иллюзион+",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_IlluzionPlus/hls/hls_illuzionplus/index.m3u8",
"logo": "logo_IlluzionPlus.png",
"StationId": 29021
},
{
"order": 17,
"name": "МНОГО ТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Mnogo_TV/hls/hls_mnogo_tv/index.m3u8",
"logo": "logo_Mnogo-TV.png",
"StationId": 28645
},
{
"order": 18,
"name": "Комедия ТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Komediya_TV/hls/hls_komediya_tv/index.m3u8",
"logo": "logo_Komediya_TV.png",
"StationId": 28868
},
{
"order": 19,
"name": "Настоящее Страшное Телевидение",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_NastStrashTV/hls/hls_naststrashtv/index.m3u8",
"logo": "logo_NastStrashTV.png",
"StationId": 28606
},
{
"order": 20,
"name": "Nickelodeon HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-NikelodeonHD/hls/nikelodeonhd/index01.m3u8",
"logo": "logo_Nickelodeon_HD.png",
"StationId": 28647
},
{
"order": 21,
"name": "Nickelodeon",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Nickelodeon/hls/hls_nickelodeon/index.m3u8",
"logo": "logo_Nickelodeon.png",
"StationId": 29132
},
{
"order": 22,
"name": "Nick Jr.",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Nick_Jr/hls/hls_nick_jr/index.m3u8",
"logo": "logo_Nick_Jr.png",
"StationId": 28744
},
{
"order": 23,
"name": "Cartoon Network",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_CartoonNetwork/hls/hls_cartoonnetwork/index.m3u8",
"logo": "logo_CartoonNetwork.png",
"StationId": 28768
},
{
"order": 24,
"name": "Tiji",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_TiJi/hls/hls_tiji/index.m3u8",
"logo": "logo_TiJi.png",
"StationId": 28594
},
{
"order": 25,
"name": "GULLI",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Gulli/hls/hls_gulli/index.m3u8",
"logo": "logo_Gulli.png",
"StationId": 28730
},
{
"order": 26,
"name": "МультиМания",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_MultiManiya/hls/hls_multimaniya/index.m3u8",
"logo": "logo_MultiManiya.png",
"StationId": 28728
},
{
"order": 27,
"name": "Детский",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Detskiy/hls/hls_detskiy/index.m3u8",
"logo": "logo_Detskiy.png",
"StationId": 28784
},
{
"order": 28,
"name": "CNN",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_CNN/hls/hls_cnn/index.m3u8",
"logo": "logo_CNN.png",
"StationId": 28628
},
{
"order": 29,
"name": "Russia Today HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia_Today_HD/hls/hls_russia_today_hd/index.m3u8",
"logo": "logo_Russia_Today.png",
"StationId": 157994
},
{
"order": 30,
"name": "MTV Live HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-MTVNHD/hls/mtvnhd/index01.m3u8",
"logo": "logo_MTV_Live_HD.png",
"StationId": 28811
},
{
"order": 31,
"name": "MTV Dance",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_MTV_Dance/hls/hls_mtv_dance/index.m3u8",
"logo": "logo_MTV_Dance.png",
"StationId": 28734
},
{
"order": 32,
"name": "MTV Hits",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_MTV_Hits/hls/hls_mtv_hits/index.m3u8",
"logo": "logo_MTV_Hits.png",
"StationId": 28735
},
{
"order": 33,
"name": "MTV Rocks",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_MTV_Rocks/hls/hls_mtv_rocks/index.m3u8",
"logo": "logo_MTV_Rocks.png",
"StationId": 28732
},
{
"order": 34,
"name": "VH1 Classic",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_VH1_Classic/hls/hls_vh1_classic/index.m3u8",
"logo": "logo_VH1_Classic.png",
"StationId": 28733
},
{
"order": 35,
"name": "VH1 Europe",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_VH1_Europe/hls/hls_vh1_europe/index.m3u8",
"logo": "logo_VH1_Europe.png",
"StationId": 28965
},
{
"order": 36,
"name": "Music Box",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Music_Box/hls/hls_music_box/index.m3u8",
"logo": "logo_Music_Box.png",
"StationId": 29047
},
{
"order": 37,
"name": "Music Box Ru",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Music_Box_Ru/hls/hls_music_box_ru/index.m3u8",
"logo": "logo_Music-Box-Ru.png",
"StationId": 28605
},
{
"order": 38,
"name": "MCM Top",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_MCM_Top/hls/hls_mcm_top/index.m3u8",
"logo": "logo_MCM-Top.png",
"StationId": 28840
},
{
"order": 39,
"name": "Mezzo",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Mezzo/hls/hls_mezzo/index.m3u8",
"logo": "logo_Mezzo.png",
"StationId": 29089
},
{
"order": 40,
"name": "Mezzo HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-MezzoHD/hls/mezzohd/index01.m3u8",
"logo": "logo_Mezzo_HD.png",
"StationId": 28991
},
{
"order": 41,
"name": "RU.TV",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_RuTV/hls/hls_rutv/index.m3u8",
"logo": "logo_RuTV.png",
"StationId": 28787
},
{
"order": 42,
"name": "A-ONE",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_A-One/hls/hls_a-one/index.m3u8",
"logo": "logo_A-One.png",
"StationId": 29020
},
{
"order": 43,
"name": "24 Техно",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_24_Tehno/hls/hls_24_tehno/index.m3u8",
"logo": "logo_24_Tehno.png",
"StationId": 28789
},
{
"order": 44,
"name": "24 Док",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_24_Doc/hls/hls_24_doc/index.m3u8",
"logo": "logo_24_Doc.png",
"StationId": 29140
},
{
"order": 45,
"name": "365 Дней",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_365_Dney/hls/hls_365_dney/index.m3u8",
"logo": "logo_365_Dney.png",
"StationId": 29119
},
{
"order": 46,
"name": "Парк Развлечений",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Park_Razvlecheniy/hls/hls_park_razvlecheniy/index.m3u8",
"logo": "logo_Universal.png",
"StationId": 28727
},
{
"order": 47,
"name": "Авто Плюс",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Avto_Plus/hls/hls_Avto_Plus/index.m3u8",
"logo": "logo_Avto_Plus.png",
"StationId": 28880
},
{
"order": 48,
"name": "Боец",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Boets/hls/hls_boets/index.m3u8",
"logo": "logo_Boets.png",
"StationId": 28899
},
{
"order": 49,
"name": "Русский экстрим",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_RusExtreme/hls/hls_rusextreme/index.m3u8",
"logo": "logo_RusExtreme.png",
"StationId": 28870
},
{
"order": 50,
"name": "ТВЦ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_TVC/hls/hls_tvc/index.m3u8",
"logo": "logo_TVC.png",
"StationId": 29082
},
{
"order": 51,
"name": "Кухня",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Kuhnya/hls/hls_kuhnya/index.m3u8",
"logo": "logo_Kuhnya.png",
"StationId": 28596
},
{
"order": 52,
"name": "O2 ТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_O2TV/hls/hls_o2tv/index.m3u8",
"logo": "logo_O2_TV.png",
"StationId": 28803
},
{
"order": 53,
"name": "Мать и Дитя",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Mat_i_Ditya/hls/hls_mat_i_ditya/index.m3u8",
"logo": "logo_Mat_i_Ditya.png",
"StationId": 29052
},
{
"order": 54,
"name": "English club HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_English_Club_HD/hls/hls_english_club_hd/index.m3u8",
"logo": "logo_EnglishClub.png",
"StationId": 28885
},
{
"order": 55,
"name": "Радость моя",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Radost_moya/hls/hls_radost_moya/index.m3u8",
"logo": "logo_Radost_moya.png",
"StationId": 28729
},
{
"order": 56,
"name": "STV",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_STV/hls/hls_stv/index.m3u8",
"logo": "logo_STV.png",
"StationId": 28824
},
{
"order": 57,
"name": "Amazing Life",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Amazing_Life/hls/hls_amazing_life/index.m3u8",
"logo": "logo_Amazing_Life.png",
"StationId": 28836
},
{
"order": 58,
"name": "Style",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Style_TV/hls/hls_style_TV/index.m3u8",
"logo": "logo_Style.png",
"StationId": 28903
},
{
"order": 59,
"name": "Мир",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Mir/hls/hls_mir/index.m3u8",
"logo": "logo_Mir.png",
"StationId": 29024
},
{
"order": 60,
"name": "Про Бизнес ТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Pro_Biznes/hls/hls_ro_biznes/index.m3u8",
"logo": "logo_Business_TV.png",
"StationId": 28831
},
{
"order": 61,
"name": "Индия ТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Indiya_TV/hls/hls_indiya_tv/index.m3u8",
"logo": "logo_Indiya_TV.png",
"StationId": 28802
},
{
"order": 62,
"name": "ТДК",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_TDK/hls/hls_tdk/index.m3u8",
"logo": "logo_TDK.png",
"StationId": 28898
},
{
"order": 63,
"name": "Успех",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Uspex/hls/hls_uspex/index.m3u8",
"logo": "logo_Uspex.png",
"StationId": 28742
},
{
"order": 64,
"name": "ШАНТ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Shant/hls/hls_shant/index.m3u8",
"logo": "logo_Shant.png",
"StationId": 28814
},
{
"order": 65,
"name": "Europa Plus TV",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_EuropaPlus_TV/hls/hls_europaplus_tv/index.m3u8",
"logo": "logo_EuropaPlus_TV.png",
"StationId": 28739
},
{
"order": 66,
"name": "Fashion ONE HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-FashiononeHD/hls/fashiononehd/index.m3u8",
"logo": "logo_Fashion_ONE_HD.png",
"StationId": 28819
},
{
"order": 67,
"name": "Еда",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Eda/hls/hls_eda/index.m3u8",
"logo": "logo_Eda.png",
"StationId": 28633
},
{
"order": 68,
"name": "Euronews",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Euronews/hls/hls_euronews/index.m3u8",
"logo": "logo_Euronews.png",
"StationId": 28622
},
{
"order": 69,
"name": "HD Life",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-HDLife/hls/hdlife/index.m3u8",
"logo": "logo_HD_Life.png",
"StationId": 28808
},
{
"order": 70,
"name": "Deutsche Welle",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Deutsche_Welle/hls/hls_deutsche_welle/index.m3u8",
"logo": "logo_Deutsche_Welle.png",
"StationId": 28837
},
{
"order": 71,
"name": "BBC World",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_BBC/hls/hls_bbc/index.m3u8",
"logo": "logo_BBC_World.png",
"StationId": 28842
},
{
"order": 72,
"name": "Совершенно Секретно",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_SovSekretno/hls/hls_sovsekretno/index.m3u8",
"logo": "logo_SovSekretno.png",
"StationId": 29149
},
{
"order": 73,
"name": "Охотник и Рыболов HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-OhotnikHD/hls/ohotnik_irybolov-hd/index.m3u8",
"logo": "logo_Ohotnik_i_Ribolov_HD.png",
"StationId": 28673
},
{
"order": 74,
"name": "Охотник и Рыболов",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Ohotnik_i_Ribolov/hls/hls_ohotnik_i_ribolov/index.m3u8",
"logo": "logo_Ohotnik_i_Ribolov.png",
"StationId": 28741
},
{
"order": 75,
"name": "Телепутешествия HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO-TeleputeshestviaHD/hls/teleputeshestviahd/index.m3u8",
"logo": "logo_Teleputeshestviya_HD.png",
"StationId": 29062
},
{
"order": 76,
"name": "Загородный",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Zagorodniy/hls/hls_zagorodniy/index.m3u8",
"logo": "logo_Zagorodniy.png",
"StationId": 28750
},
{
"order": 77,
"name": "Драйв",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Drive/hls/hls_drive/index.m3u8",
"logo": "logo_Drive.png",
"StationId": 132453
},
{
"order": 78,
"name": "Усадьба",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Usadba/hls/hls_usadba/index.m3u8",
"logo": "logo_Usadba.png",
"StationId": 28821
},
{
"order": 79,
"name": "Психология 21",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Psihologiya_21/hls/hls_psihologiya_21/index.m3u8",
"logo": "logo_Psihologiya_21.png",
"StationId": 28743
},
{
"order": 80,
"name": "Домашние животные",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Domashnie_Jivotnie/hls/hls_domashnie_jivotnie/index.m3u8",
"logo": "logo_Domashnie_Jivotnie.png",
"StationId": 132450
},
{
"order": 81,
"name": "Zee TV",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Zee_TV/hls/hls_zee_tv/index.m3u8",
"logo": "logo_Zee_TV.png",
"StationId": 29147
},
{
"order": 82,
"name": "Кинолюкс",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Kinoluks/hls/hls_kinoluks/index.m3u8",
"logo": "logo_Kinoluks.png",
"StationId": 28896
},
{
"order": 83,
"name": "Universal",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Universal/hls/hls_universal/index.m3u8",
"logo": "logo_Universal.png",
"StationId": 28598
},
{
"order": 84,
"name": "Спорт 1 HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/Sport-1/hls/sport-1/index.m3u8",
"logo": "",
"StationId": 28780
},
{
"order": 85,
"name": "Discovery",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery/hls/hls_discovery/index.m3u8",
"logo": "",
"StationId": 29136
},
{
"order": 86,
"name": "Discovery HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_HD/hls/hls_discovery_hd/index.m3u8",
"logo": "",
"StationId": 29031
},
{
"order": 87,
"name": "Animal Planet",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Animal_Planet/hls/hls_animalplanet/index.m3u8",
"logo": "",
"StationId": 29130
},
{
"order": 88,
"name": "Animal Planet HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_AnimalPlanet_HD/hls/hls_animal_planet_hd/index.m3u8",
"logo": "",
"StationId": 29032
},
{
"order": 89,
"name": "TLC HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_TLC_HD/hls/hls_tlc_hd/index.m3u8",
"logo": "",
"StationId": 361518
},
{
"order": 90,
"name": "Discovery Science HD",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_SC_HD/hls/hls_discovery_science_hd/index.m3u8",
"logo": "",
"StationId": 361517
},
{
"order": 91,
"name": "Discovery Investigation",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_Invg/hls/hls_discovery_invg/index.m3u8",
"logo": "",
"StationId": 28954
},
{
"order": 92,
"name": "Discovery World",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_World/hls/hls_discovery_world/index.m3u8",
"logo": "",
"StationId": 28891
},
{
"order": 93,
"name": "France 24",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_France24/hls/hls_france24/index.m3u8",
"logo": "",
"StationId": 28569
},
{
"order": 94,
"name": "Билайн ТВ",
"stream": "http://wpc.970A.edgecastcdn.net/80970A/HALO_Beeline_TV/hls/hls_beeline_tv/index.m3u8",
"logo": "",
"StationId": 332106
}
],
"Serials": [
{
"name": "Сериалы/English Club",
"poster": "word_new.jpg",
"CategoryId": "434"
},
{
"name": "Сериалы/Апостол",
"poster": "walkingdeadthe_7713.jpg",
"CategoryId": "5762"
},
{
"name": "Сериалы/Бой с тенью",
"poster": "Boistenuseriya1_3853.jpg",
"CategoryId": "175477"
},
{
"name": "Сериалы/В июне 1941",
"poster": "Viune41goseriya_9705.jpg",
"CategoryId": "175517"
},
{
"name": "Сериалы/Инкассаторы",
"poster": "InkassCopy_3226.jpg",
"CategoryId": "167964"
},
{
"name": "Сериалы/Исаев",
"poster": "Isaevseriya10Co_4832.jpg",
"CategoryId": "1848"
},
{
"name": "Сериалы/Легенды о Круге",
"poster": "LegendiOKrugeCo_2291.jpg",
"CategoryId": "180911"
},
{
"name": "Сериалы/Легенды о Круге (HD)",
"poster": "LegendiOKrugeHD_2971.jpg",
"CategoryId": "180912"
},
{
"name": "Сериалы/Ликвидация",
"poster": "Likvidaciyaseri_7791.jpg",
"CategoryId": "5519"
},
{
"name": "Сериалы/Матч",
"poster": "MatchCopy_5800.jpg",
"CategoryId": "170784"
},
{
"name": "Сериалы/Матч (HD)",
"poster": "MatchHDCopy_1987.jpg",
"CategoryId": "170709"
},
{
"name": "Сериалы/Мессинг: Видевший сквозь время",
"poster": "Messingvidevshi_9853.jpg",
"CategoryId": "5362"
},
{
"name": "Сериалы/Офицеры",
"poster": "OficeriCopy_4835.jpg",
"CategoryId": "175539"
},
{
"name": "Сериалы/Партизаны",
"poster": "Partizaniseriya_2238.jpg",
"CategoryId": "4898"
},
{
"name": "Сериалы/Пелагия и белый бульдог",
"poster": "Pelagiyaibeliib_3020.jpg",
"CategoryId": "4512"
},
{
"name": "Сериалы/Пять невест",
"poster": "5NevestCopy_5988.jpg",
"CategoryId": "175626"
},
{
"name": "Сериалы/Столик в углу",
"poster": "BoothAtTheEndTh_3288.jpg",
"CategoryId": "5451"
},
{
"name": "Сериалы/Ходячие мертвецы",
"poster": "walkingdeadthe_7713.jpg",
"CategoryId": "4860"
},
{
"name": "Сериалы/Читающий мысли",
"poster": "ListenerThe_2089.jpg",
"CategoryId": "4996"
}
]
}
Гораздо более интересным оказалось то, что стриминг ведется не с собственных серверов провайдера, а через CDN EdgeCast. Что дает возможность абсолютно беспрепятственного воспроизведения не только через «моего» интернет-провайдера, а и вообще через любого (хотя это-то было понятно изначально, потому что мобильное приложение работало даже через 3G конкурирующего сотового оператора). И конечно же, в этом списке нашлись все интересующие меня каналы (как и более 90 других). Причем выяснилось, что плейлисты (по ссылке в файлах .m3u8) это матрёшка — каждый файл содержит ссылку на другие плейлисты, которые выбираются по размеру экрана и доступному пользователю каналу (на практике это выглядит как плохая картинка при просмотре через 3G и отличная через 100 Мбит дома, причем в зависимости от скорости подключения картинка изменяется динамически). Сам же видео-поток кодируются ключом (я не сильно знаком с форматом EXTM3U, но похоже, что так провайдер защищается от несанкционированного доступа к видео-потоку или записи изображения).
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=357952,RESOLUTION=320x240,CODECS="avc1.42e00a,mp4a.40.2"
02.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=203040,RESOLUTION=320x240,CODECS="avc1.42e00a,mp4a.40.2"
01.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1740128,RESOLUTION=720x576,CODECS="avc1.4d400a,mp4a.40.2"
05.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=765536,RESOLUTION=480x320,CODECS="avc1.42e00a,mp4a.40.2"
03.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=918944,RESOLUTION=640x480,CODECS="avc1.4d400a,mp4a.40.2"
04.m3u8
Здесь видно, что для видеопотока доступно 4 типа разрешения экрана для 5 типов пропускной способности.
Формат файла под-плейлиста имеет вид:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:159962
#EXT-X-KEY:METHOD=AES-128,URI="1391898000.key",IV=0x00000000000000000000000000000000
#EXTINF:10,
20140207T001353-01-159962.ts
#EXTINF:10,
20140207T001353-01-159963.ts
#EXT-X-KEY:METHOD=AES-128,URI="1391898060.key",IV=0x00000000000000000000000000000000
#EXTINF:10,
20140207T001353-01-159964.ts
Здесь видно, что канал кодируется ключом (см. документ HTTP Live Streaming пункт 3.3.3) и содержит несколько видеопотоков, зачем — дальше не разбирался.
Заключение
В общем-то на этом этапе уже можно было остановиться и просто открывать найденные ссылки в браузере мобильного телефона и пользоваться функцией вывода изображения через тв-приставку. В этом случае (когда поток воспроизводится по прямой ссылке) при переходе мобильника в спящий режим воспроизведение продолжается! Однако захотелось немного эстетики и еще чуточку упростить процесс. Потратив еще несколько минут в текстовом редакторе с удобной автозаменой у меня получилась веб-страничка, которую я закачал на веб-сервер домашнего NAS-устройства. Теперь при переходе по сссылке http://my.home/tv.html
открывается выбор канала для просмотра. А если страничку отправить себе по почте — то можно следить за любимыми командами отовсюду, где есть интернет.
<!DOCTYPE html>
<html lang="ru">
<head>
<title>My TV</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="ru-RU" />
<meta charset="utf-8" />
<style type="text/css">
body {
background: gray;
}
.channel {
float: left;
border: 1px solid;
//padding: 3px;
width: 100px;
height: 100px;
text-align: center;
}
.channel_logo {
float: left;
max-width: 80px;
max-height: 80px;
}
.channel_name {
font-size: 10px;
color: black;
font-family: verdana;
font-weight: bold;
}
</style>
</head>
<body>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Perviy/hls/hls_perviy/index.m3u8">
<span class="channel_name">Первый</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28629.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-1/hls/hls_russia-1/index.m3u8">
<span class="channel_name">Россия 1</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28976.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-2/hls/hls_russia-2/index.m3u8">
<span class="channel_name">Россия 2</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28983.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_NTV/hls/hls_ntv/index.m3u8">
<span class="channel_name">НТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28982.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_5-kanal/hls/hls_5-kanal/index.m3u8">
<span class="channel_name">5 канал</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29126.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-K/hls/hls_russia-k/index.m3u8">
<span class="channel_name">Россия К</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29135.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia-24/hls/hls_russia-24/index.m3u8">
<span class="channel_name">Россия 24</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28770.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Karusel/hls/hls_karusel/index.m3u8">
<span class="channel_name">Карусель</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28718.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Sony_HD/hls/hls_sony_hd/index.m3u8">
<span class="channel_name">Sony HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28935.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Sony_Sci-Fi/hls/hls_sony_sci-fi/index.m3u8">
<span class="channel_name">AXN Sci-Fi</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29106.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Sony_Turbo/hls/hls_sony_turbo/index.m3u8">
<span class="channel_name">Sony Turbo</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/132454.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Diva/hls/hls_diva/index.m3u8">
<span class="channel_name">Diva</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29080.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-MGMHD/hls/mgmhd/index.m3u8">
<span class="channel_name">MGM HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28934.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_RusIlluzion/hls/hls_rusilluzion/index.m3u8">
<span class="channel_name">Русский Иллюзион</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29054.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Evrokino/hls/hls_evrokino/index.m3u8">
<span class="channel_name">Еврокино</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28640.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_IlluzionPlus/hls/hls_illuzionplus/index.m3u8">
<span class="channel_name">Иллюзион+</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29021.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Mnogo_TV/hls/hls_mnogo_tv/index.m3u8">
<span class="channel_name">МНОГО ТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28645.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Komediya_TV/hls/hls_komediya_tv/index.m3u8">
<span class="channel_name">Комедия ТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28868.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_NastStrashTV/hls/hls_naststrashtv/index.m3u8">
<span class="channel_name">Настоящее Страшное Телевидение</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28606.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-NikelodeonHD/hls/nikelodeonhd/index01.m3u8">
<span class="channel_name">Nickelodeon HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28647.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Nickelodeon/hls/hls_nickelodeon/index.m3u8">
<span class="channel_name">Nickelodeon</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29132.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Nick_Jr/hls/hls_nick_jr/index.m3u8">
<span class="channel_name">Nick Jr.</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28744.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_CartoonNetwork/hls/hls_cartoonnetwork/index.m3u8">
<span class="channel_name">Cartoon Network</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28768.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_TiJi/hls/hls_tiji/index.m3u8">
<span class="channel_name">Tiji</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28594.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Gulli/hls/hls_gulli/index.m3u8">
<span class="channel_name">GULLI</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28730.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_MultiManiya/hls/hls_multimaniya/index.m3u8">
<span class="channel_name">МультиМания</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28728.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Detskiy/hls/hls_detskiy/index.m3u8">
<span class="channel_name">Детский</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28784.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_CNN/hls/hls_cnn/index.m3u8">
<span class="channel_name">CNN</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28628.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Russia_Today_HD/hls/hls_russia_today_hd/index.m3u8">
<span class="channel_name">Russia Today HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/157994.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-MTVNHD/hls/mtvnhd/index01.m3u8">
<span class="channel_name">MTV Live HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28811.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_MTV_Dance/hls/hls_mtv_dance/index.m3u8">
<span class="channel_name">MTV Dance</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28734.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_MTV_Hits/hls/hls_mtv_hits/index.m3u8">
<span class="channel_name">MTV Hits</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28735.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_MTV_Rocks/hls/hls_mtv_rocks/index.m3u8">
<span class="channel_name">MTV Rocks</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28732.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_VH1_Classic/hls/hls_vh1_classic/index.m3u8">
<span class="channel_name">VH1 Classic</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28733.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_VH1_Europe/hls/hls_vh1_europe/index.m3u8">
<span class="channel_name">VH1 Europe</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28965.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Music_Box/hls/hls_music_box/index.m3u8">
<span class="channel_name">Music Box</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29047.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Music_Box_Ru/hls/hls_music_box_ru/index.m3u8">
<span class="channel_name">Music Box Ru</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28605.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_MCM_Top/hls/hls_mcm_top/index.m3u8">
<span class="channel_name">MCM Top</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28840.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Mezzo/hls/hls_mezzo/index.m3u8">
<span class="channel_name">Mezzo</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29089.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-MezzoHD/hls/mezzohd/index01.m3u8"
<span class="channel_name">Mezzo HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28991.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_RuTV/hls/hls_rutv/index.m3u8">
<span class="channel_name">RU.TV</span>
<img class="channel_logo" src="">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_A-One/hls/hls_a-one/index.m3u8">
<span class="channel_name">A-ONE</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29020.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_24_Tehno/hls/hls_24_tehno/index.m3u8">
<span class="channel_name">24 Техно</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28789.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_24_Doc/hls/hls_24_doc/index.m3u8">
<span class="channel_name">24 Док</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29140.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_365_Dney/hls/hls_365_dney/index.m3u8">
<span class="channel_name">365 Дней</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29119.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Park_Razvlecheniy/hls/hls_park_razvlecheniy/index.m3u8">
<span class="channel_name">Парк Развлечений</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28727.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Avto_Plus/hls/hls_Avto_Plus/index.m3u8">
<span class="channel_name">Авто Плюс</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28880.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Boets/hls/hls_boets/index.m3u8">
<span class="channel_name">Боец</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28899.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_RusExtreme/hls/hls_rusextreme/index.m3u8">
<span class="channel_name">Русский экстрим</span>
<img class="channel_logo" src="http://habr.habrastorage.org/post_images/035/b8a/91e/035b8a91e931879a23590bb58749f0f1.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_TVC/hls/hls_tvc/index.m3u8">
<span class="channel_name">ТВЦ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29082.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Kuhnya/hls/hls_kuhnya/index.m3u8">
<span class="channel_name">Кухня</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28596.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_O2TV/hls/hls_o2tv/index.m3u8">
<span class="channel_name">O2 ТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28803.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Mat_i_Ditya/hls/hls_mat_i_ditya/index.m3u8">
<span class="channel_name">Мать и Дитя</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29052.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_English_Club_HD/hls/hls_english_club_hd/index.m3u8">
<span class="channel_name">English club HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28885.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Radost_moya/hls/hls_radost_moya/index.m3u8">
<span class="channel_name">Радость моя</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28729.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_STV/hls/hls_stv/index.m3u8">
<span class="channel_name">STV</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28824.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Amazing_Life/hls/hls_amazing_life/index.m3u8">
<span class="channel_name">Amazing Life</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28836.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Style_TV/hls/hls_style_TV/index.m3u8">
<span class="channel_name">Style</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28903.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Mir/hls/hls_mir/index.m3u8">
<span class="channel_name">Мир</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29024.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Pro_Biznes/hls/hls_ro_biznes/index.m3u8">
<span class="channel_name">Про Бизнес ТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28831.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Indiya_TV/hls/hls_indiya_tv/index.m3u8">
<span class="channel_name">Индия ТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28802.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_TDK/hls/hls_tdk/index.m3u8">
<span class="channel_name">ТДК</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28898.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Uspex/hls/hls_uspex/index.m3u8">
<span class="channel_name">Успех</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28742.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Shant/hls/hls_shant/index.m3u8">
<span class="channel_name">ШАНТ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28814.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_EuropaPlus_TV/hls/hls_europaplus_tv/index.m3u8">
<span class="channel_name">Europa Plus TV</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28739.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-FashiononeHD/hls/fashiononehd/index.m3u8">
<span class="channel_name">Fashion ONE HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28819.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Eda/hls/hls_eda/index.m3u8">
<span class="channel_name">Еда</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28633.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Euronews/hls/hls_euronews/index.m3u8">
<span class="channel_name">Euronews</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28622.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-HDLife/hls/hdlife/index.m3u8">
<span class="channel_name">HD Life</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28808.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Deutsche_Welle/hls/hls_deutsche_welle/index.m3u8">
<span class="channel_name">Deutsche Welle</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28837.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_BBC/hls/hls_bbc/index.m3u8">
<span class="channel_name">BBC World</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28842.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_SovSekretno/hls/hls_sovsekretno/index.m3u8">
<span class="channel_name">Совершенно Секретно</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29149.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-OhotnikHD/hls/ohotnik_irybolov-hd/index.m3u8">
<span class="channel_name">Охотник и Рыболов HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28673.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Ohotnik_i_Ribolov/hls/hls_ohotnik_i_ribolov/index.m3u8">
<span class="channel_name">Охотник и Рыболов</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28741.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO-TeleputeshestviaHD/hls/teleputeshestviahd/index.m3u8">
<span class="channel_name">Телепутешествия HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29062.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Zagorodniy/hls/hls_zagorodniy/index.m3u8">
<span class="channel_name">Загородный</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28750.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Drive/hls/hls_drive/index.m3u8">
<span class="channel_name">Драйв</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/132453.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Usadba/hls/hls_usadba/index.m3u8">
<span class="channel_name">Усадьба</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28821.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Psihologiya_21/hls/hls_psihologiya_21/index.m3u8">
<span class="channel_name">Психология 21</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28743.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Domashnie_Jivotnie/hls/hls_domashnie_jivotnie/index.m3u8">
<span class="channel_name">Домашние животные</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/132450.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Zee_TV/hls/hls_zee_tv/index.m3u8">
<span class="channel_name">Zee TV</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29147.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Kinoluks/hls/hls_kinoluks/index.m3u8">
<span class="channel_name">Кинолюкс</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28896.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Universal/hls/hls_universal/index.m3u8">
<span class="channel_name">Universal</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28598.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/Sport-1/hls/sport-1/index.m3u8">
<span class="channel_name">Спорт 1 HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28780.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery/hls/hls_discovery/index.m3u8">
<span class="channel_name">Discovery</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29136.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_HD/hls/hls_discovery_hd/index.m3u8">
<span class="channel_name">Discovery HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29031.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Animal_Planet/hls/hls_animalplanet/index.m3u8">
<span class="channel_name">Animal Planet</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29130.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_AnimalPlanet_HD/hls/hls_animal_planet_hd/index.m3u8">
<span class="channel_name">Animal Planet HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/29032.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_TLC_HD/hls/hls_tlc_hd/index.m3u8">
<span class="channel_name">TLC HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/361518.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_SC_HD/hls/hls_discovery_science_hd/index.m3u8">
<span class="channel_name">Discovery Science HD</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/361517.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_Invg/hls/hls_discovery_invg/index.m3u8">
<span class="channel_name">Discovery Investigation</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28954.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Discovery_World/hls/hls_discovery_world/index.m3u8">
<span class="channel_name">Discovery World</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28891.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_France24/hls/hls_france24/index.m3u8">
<span class="channel_name">France 24</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/28569.png">
</a>
</div>
<div class="channel">
<a href="http://wpc.970A.edgecastcdn.net/80970A/HALO_Beeline_TV/hls/hls_beeline_tv/index.m3u8">
<span class="channel_name">Билайн ТВ</span>
<img class="channel_logo" src="https://interface.iptv.beeline.ru/PHP/images/logos_224x158_id/332106.png">
</a>
</div>
</body>
</html>
PS
Делалось быстро, ради интереса и для себя, так что за куски кода прошу не судить — с html/css'ом и не знаком я вовсе. Основная задача была — показать, как можно быстро и просто решить проблему, имея по немногу знаний из разных областей :)
Автор: iLexey