Написать пост

Конструктор плейлиста для IP-TV — конкурс пет-проектов

Аватарка пользователя Алексей Старовойтов

Сделал небольшое приложение, которое позволит сконструировать нужный для пользователя IP-TV плейлист в формате M3U.

Обложка поста Конструктор плейлиста для IP-TV — конкурс пет-проектов

Меня зовут Алексей, и я типичный программист, которого прёт от разработки.

Если интересно, какая боль меня посетила, или что послужило предпосылкой к идее, то читаем здесь.

Одним типичным, но прекрасным днём я купил домой большой современный телевизор. В процессе прочёсывания всех настроек и уголков интерфейса операционной системы я заметил, что если заморочиться с настройкой, то телевизор может показывать каналы, словно пользуешься пультом, как в детстве. Я был удивлён, поскольку думал, что смотреть телеканалы возможно только через напичканные рекламой приложения, бесплатно показывающие жалкий десяток каналов, а за остальное, дружок, плати ежемесячно. К тому же нужно проделать множество нажатий по пульту с момента включения телевизора, чтобы добраться до нужного канала в таком приложении. А нам с вами есть с чем сравнивать, не так ли? Ох, как быстро и просто включался канал на старом добром телевизоре в отчем доме ✨✨.

Такой расклад не может не вызвать разочарование. Поэтому я внимательно изучил функционал телевизора и выяснил, что для достижения желаемого мной UX ему просто нужно такое приложение, которое может дать эти самые каналы. Немного побороздив просторы интернета, я нашёл приложение, которое относится к таковым, позволяя настроить каналы с помощью ссылки на плейлист формата M3U. Я нашёл первый попавшийся бесплатный плейлист с типичными каналами, чтобы пощупать решение на деле. И вот я уже смотрю каналы. Работает. И очень привычно.

Такой расклад меня порадовал. Но сразу же возникло много «но»:

  • Содержимое плейлиста задаётся его автором.
  • Порядок каналов задаётся автором плейлиста.
  • Некоторые стримы каналов «протухли» и лежат мёртвым грузом в плейлисте.
  • Плейлист может не содержать нужных мне каналов.

Мне пришла идея реализовать приложение, которое позволит сконструировать нужный для пользователя IP-TV плейлист в формате M3U.

Мне нужно было от приложения следующее:

  • Задать каналы и их порядок в плейлисте. Канал — это имя, логотип и ссылки на стримы.
  • Сохранить заданный плейлист в БД, выбрав не протухшую ссылку на стрим либо использовав заглушку.
  • Сконструировать плейлист в формате M3U из плейлиста, сохранённого в БД.
  • Web API с 2 методами: для запуска пункта 2 (далее: метод refresh_channels) и для получения плейлиста в формате M3U (далее: метод ip_tv_playlist.m3u), чтобы телевизор мог его получить и обработать.

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

Если интересно, как выглядело использование приложения в первой юзабельной версии, то читаем здесь
  • Задать список желаемых каналов в файле init_data.json.
  • Запустить приложение (удобно через команду docker compose up –build).
  • Отправить POST-запрос на метод refresh_channels. Дождаться успеха.
  • На телевизоре в приложении (в моём случае Tvirl) указать ссылку на плейлист такую, чтобы попасть в метод ip_tv_playlist.m3u. Дождаться обработки плейлиста телевизором.
  • Возможны какие-то дополнительные действия со стороны ПО телевизора. В частности, мне ещё нужно в приложении Live Channels указать новоиспечённый список каналов.
  • Наслаждаться.

Попользовавшись своим чудом, я понял, что вручную искать рабочую ссылку на стрим — неблагодарное дело, поэтому решил внести корректировки в изначальную задумку:

  • Метод refresh_channels принимает список ссылок на IP-TV плейлисты и множество параметров фильтрации каналов:names_to_remove[] — регулярные выражения для удаления каналов по названию канала;groups_to_remove[] — регулярные выражения для удаления каналов по названию группы;source_urls_to_remove[] — регулярные выражения для удаления каналов по ссылке на источник канала;min_resolution_width — минимальная допустимая ширина разрешения канала;min_resolution_height — минимальная допустимая высота разрешения канала.
  • Возможность задать каналы и их порядок в плейлисте остаётся той же, но у канала появляется дополнительное поле namePattern, в котором мы можем задать регулярное выражение для поиска этого канала в переданных плейлистах.
  • Все каналы, которых не коснулась фильтрация, добавляются в конец заданного списка каналов.

Данная корректировка избавляет нас от ручного поиска рабочей ссылки на стрим для каждого желаемого канала, добавляет каналы, которые могут показаться интересными (кандидаты на добавление в заданный список каналов) или не интересными (причины добавления новой группы, имени или ссылки на источник в параметры фильтрации). Но мы должны вручную найти IP-TV плейлисты, из которых будет собираться наш, персонализированный. С этим неудобством я смирился, хотя можно было и это решить.

Если интересно, как выглядело использование приложения в итоговой версии, то читаем здесь
  1. Задать список желаемых каналов в файле init_data.json.
  2. Запустить приложение (удобно через команду docker compose up –build).
  3. Отправить POST-запрос на метод refresh_channels, указав ссылки на плейлисты и задав желаемые фильтры. Дождаться успеха. Проверка разрешения стрима занимает большую часть всего времени выполнения запроса.
  4. На телевизоре в приложении (в моём случае Tvirl) указать ссылку на плейлист такую, чтобы попасть в метод ip_tv_playlist.m3u. Дождаться обработки плейлиста телевизором.
  5. Возможны какие-то дополнительные действия со стороны ПО телевизора. В частности, мне ещё нужно в приложении Live Channels указать новоиспечённый список каналов.
  6. Наслаждаться.

В реализации приложения мне похвастаться нечем, потому что делал на скорость, между делом. Но была одна трудность, с которой я столкнулся. Ещё в то время, как я пробовал на деле первую юзабельную версию приложения, я заметил, что некоторые каналы, хоть и работают, показываются в очень низком разрешении (720p, 480p, а то и хуже). На 75” 4К телевизоре это выглядит ужасно, поэтому среди фильтров есть возможность задать минимальное разрешение стрима. В моём случае это 1920×1080. Но единственный нормальный способ проверить разрешение стрима, который я нашёл, это использовать программу ffprobe. Её можно «попросить» вернуть некоторую информацию о стриме, в том числе его разрешение. Но делается это далеко не моментально. Поэтому обработка 14-ти плейлистов, которые я задал, проходила так долго, что я не дождался и остановил процесс. В качестве решения этой трудности я просто распараллелил проверку разрешения стримов на несколько потоков, достигнув приемлимого времени ожидания обработки 14-ти плейлистов (~5 минут).

Довольный результатом, я решил, что было бы круто помочь таким же пользователям Smart TV, которые так же как я не видят ничего удобного в онлайн-кинотеатрах, дополнительно содержащих в себе телевидение. Можно было бы сделать веб-интерфейс, который бы проксировал прямое обращение к Web API, но фильтрацию по минимальному разрешению стрима, скорее всего, пришлось бы скрыть, раз это такая долгая операция. Или сделать платной возможностью и за счёт этого позволить нормальные вычислительные мощности сервера. Но до продолжения делания чего-либо по этому проекту руки не дошли, поэтому я отделался написанием README.md, с помощью которого можно самостоятельно запустить приложение локально и сконструировать себе персонализированный плейлист.

Ссылка на репозиторий проекта в GitHub:

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

POST-запрос на конструирование плейлиста в БД:

Если разложить по полочкам, то это POST-запрос на http://127.0.0.1:9090/refresh_channels со следующими Query-параметрами:

playlist_urls[]: https://iptv-russia.org/list/iptv-playlist.m3u
playlist_urls[]: https://iptvlist.ru/ru.m3u
playlist_urls[]: https://iptvlist.ru/ru3.m3u
playlist_urls[]: https://raw.githubusercontent.com/iptv-org/iptv/master/streams/ru.m3u
playlist_urls[]: https://raw.githubusercontent.com/iptv-org/iptv/master/streams/ru_okkotv.m3u
playlist_urls[]: https://iptv-russia.org/list/cinematic.m3u
playlist_urls[]: https://iptv-russia.org/list/sport.m3u
playlist_urls[]: https://iptv-russia.org/list/sci-all.m3u
playlist_urls[]: https://iptv-russia.org/list/kids-all.m3u
names_to_remove[]: .*Белгород.*
names_to_remove[]: .*Reel life.*
names_to_remove[]: .*Luxury.*
names_to_remove[]: .*Meteonews.*
names_to_remove[]: .*10 канал.*
names_to_remove[]: .*H1.*
names_to_remove[]: .*НТК.*
names_to_remove[]: .*Bambarbia.*
names_to_remove[]: .*Башкортостан.*
names_to_remove[]: .*12 Канал.*
names_to_remove[]: .*Ростов-папа.*
names_to_remove[]: .*(Алладин|Aladdin|Аладдин).*
names_to_remove[]: .*1\+1.*
names_to_remove[]: .*2\+2.*
names_to_remove[]: .*TVM3.*
names_to_remove[]: .*360°? Новости.*
names_to_remove[]: .*Туган Тел.*
names_to_remove[]: .*Первый Тульский.*
names_to_remove[]: .*https:\/\/vk[.]com.*
names_to_remove[]: .*Leomax.*
names_to_remove[]: .*Fashion.*
names_to_remove[]: .*INTER.*
names_to_remove[]: .*K1.*
names_to_remove[]: .*MEGA.*
names_to_remove[]: .*PIXEL.*
names_to_remove[]: .*Київ.*
names_to_remove[]: .*Уніaн.*
names_to_remove[]: .*Армія.*
names_to_remove[]: .*Рада.*
names_to_remove[]: .*Прямий.*
names_to_remove[]: .*Галичина.*
names_to_remove[]: .*ATR.*
names_to_remove[]: .*Апостроф.*
names_to_remove[]: .*Ukraine.*
names_to_remove[]: ^UA .*
names_to_remove[]: .* UA$
groups_to_remove[]: Украинские
groups_to_remove[]: Для ForkPlayer
groups_to_remove[]: Для взрослых|18+|XXX|xxx
source_urls_to_remove[]: .*[.]png$
source_urls_to_remove[]: .*[.]mp4$
source_urls_to_remove[]: .*[.]flv$
source_urls_to_remove[]: .*[.]cdn[.]ngenix[.]net.*
source_urls_to_remove[]: .*cc26f3c1[.]cbilant[.]com.*
source_urls_to_remove[]: .*tv[.]streams[.]baikal-telecom[.]net.*
source_urls_to_remove[]: .*lb[.]wisp[.]cat.*
source_urls_to_remove[]: .*luxnet[.]ua.*
source_urls_to_remove[]: .*[.]ott[.].*
source_urls_to_remove[]: spacetv[.]in
source_urls_to_remove[]: .*178[.]33[.]37[.]66.*
source_urls_to_remove[]: .*a1mediagroep[.]eu.*
source_urls_to_remove[]: .*\/myott[.].*
source_urls_to_remove[]: .*\/149.5.17.34.*
source_urls_to_remove[]: .*\/194.87.237.169.*
min_resolution_width: 1920
min_resolution_height: 1080

После получения 200 OK плейлист для IP-TV можно получить по ссылке http://127.0.0.1:9090/ip_tv_playlist.m3u

Для телевизора нужно будет вместо 127.0.0.1 указать … ну вы поняли.

И напоследок: желаю всем меньше «печальных» каналов =)

Конструктор плейлиста для IP-TV — конкурс пет-проектов 1
Следите за новыми постами
Следите за новыми постами по любимым темам
811 открытий1К показов