В чем суть?
У меня нет обычного зомбо-телевидения — я не смотрю эфирные каналы уже лет 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": "Не удаётся подключиться к ТВ-приставке.\r\nВозможные причины:\r\n·\tневерно введены IP-адрес ТВ-приставки и/или поле Ключ\r\n·\tотсутствует доступ по локальной сети между Вашим устройством и ТВ-приставкой\r\n" }, { "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’ом и не знаком я вовсе. Основная задача была — показать, как можно быстро и просто решить проблему, имея по немногу знаний из разных областей 🙂
ссылка на оригинал статьи http://habrahabr.ru/post/211911/
Добавить комментарий