1

Тема: Написать скрипт, который бы загружал плейлист m3u8

Была просьба сделать скрипт, который бы загружал плейлист m3u8, создавать ссылки из него и мог бы играть HLS поток из него.

Проще всего сделать это - сделать подкаст.

Т.к. у меня мечта, чтобы тут ещё люди появились, которые хотят научится делать подкасты или умеют, то я решил не просто сделать, а показать и объяснить как можно его создать.

Была цель: создать ссылки из указанного плейлиста, которые содержат ссылки на поток HLS и чтобы Домашний медиа-сервер мог их проиграть.

Ок.

Давайте создадим новый подкаст в программе:

+ открыть спойлер

https://hms.lostcut.net/img/help/create/addpodcast.png

В поле заголовок вписываем название, которое будет у нас отображаться, а в поле "Ссылка" впишем путь до нашего плейлиста.
Сразу запланируем, чтобы сделать возможность указывать как локальные папки (типа D:\playlist.m3u8), так и ссылки на плейлисты из интернета (адрес начинается на http://).

Нажав внизу вкладку "Скрипты", проставим:
1. "Режим чтения списка ресурсов" в значение "Специальный (скрипт)";
2. "Скрипт чтения списка ресурсов (Alt + 2)" в значение "Включен";
3. "Скрипт получения ссылки на ресурс (Alt + 4)" тоже в значение "Включен";

+ открыть спойлер

https://hms.lostcut.net/img/help/create/podcast_prepare.png

и нажмём ОК.

У нас добавиться базу новый подкаст. На нём мы нажмём опять правой клавишей мышки и выберем "Изменить название", тем самым мы откроем окно свойств подкаста.
Нажмём кнопку рядом с "Включен" в разделе "Скрипт чтения списка ресурсов (Alt + 2)" и попадём в окно редактирования скриптов.

Внизу выберем язык синтаксиса, который мы будем использовать. Ставьте такой, который вам по душе, но тут я буду показывать примеры на C++Script и PascalScript.

сразу зададим главную процедуру:

+ C++Script
///////////////////////////////////////////////////////////////////////////////
//                      Г Л А В Н А Я   П Р О Ц Е Д У Р А                    //
// ----------------------------------------------------------------------------
{

}
+ PascalScript
///////////////////////////////////////////////////////////////////////////////
//                      Г Л А В Н А Я   П Р О Ц Е Д У Р А                    //
// ----------------------------------------------------------------------------
Begin

End.

В ней напишем первую команду, которая будет очищать содержимое подкаста (ранее созданные ссылки):

FolderItem.DeleteChildItems(); // Удаляем созданные ранее ссылки

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

Также можно там увидеть, что тип переменной FolderItem - THmsScriptMediaItem.
Также в том же справочнике можно включить отображение классов и найти данный класс, посмотреть какие методы и свойства он имеет. Там то мы и увидим, что у данного класса есть метод DeleteChildItems, которые удаляет подчинённые элементы.

Вот и всё. Пользуясь справочником переменных и функций можно посмотреть какие функции мы можем использовать.

Далее привожу скрипт получения списка ресурсов - он у нас будет загружать плейлист, искать там ссылки и наименования и создавать эти ссылки:

+ C++Script
int gnTotal=0;
// ----------------------------------------------------------------------------
void LoadPlaylist() {
  string sData, sLink, sName, sImg; THmsScriptMediaItem Item;
  
  // Если ссылка плейлиста начинается на http, то скачиваем, если нет - загружаем как локальный файл
  if (LeftCopy(mpFilePath, 4)=='http') sData = HmsDownloadUrl(mpFilePath, '', true);  // Загрузка плейлиста из интернета
  else                                 sData = HmsStringFromFile(mpFilePath);         // Загрузка плейлиста с локального диска
  
  sData = HmsUtf8Decode(sData);   // Декодируем из UTF-8 кодировки

  // Создаём объект для поиска по регулярному выражению (в C++Script символ \ экранирует, поэтому двойной)
  TRegExpr RE = TRegExpr.Create('#EXTINF:(.*?)[\\r\\n]+(.*?)([\\r\\n]|$)');
  try {
    if (RE.Search(sData)) do {    // Запускаем поиск и создаём цикл, пока найдены совпадения
      sName = Trim(RE.Match(1));  // Получаем значение первой группировки регулярного выражения (первая строка после #EXTINF:)
      sLink = Trim(RE.Match(2));  // Получаем значение второй группировки регулярного выражения (вся вторая строка)
      
      // В наименовании берём только ту часть, которая идёт после последней запятой
      HmsRegExMatch('.*,(.*)', sName, sName);

      // Пытаемся получить ссылку на картинку из служебного тега tvg-logo, если нету - то своё значение 
      if (!HmsRegExMatch('tvg-logo="(.*?)"', RE.Match, sImg)) sImg = 'http://wonky.lostcut.net/TVimg/'+HmsPercentEncode(sName, '"A-Z", "a-z", "0-9", "-", ".", "_", "~", "\'"')+'.png';
      
      // Создаём ссылку
      Item = HmsCreateMediaItem(sLink, FolderItem.ItemID);
      Item[mpiTitle    ] = sName; // Наименование
      Item[mpiThumbnail] = sImg;  // Картинка
      gnTotal++;                  // Увеличиваем счетчик созданных ссылок

    } while (RE.SearchAgain());   // Повторяем цикл, пока найдены следующие совпадения

  } finally { RE.Free(); }        // Освобождаем объект из памяти, что бы ни случилось  

  HmsLogMessage(1, mpTitle+': создано ссылок '+IntToStr(gnTotal));
}

///////////////////////////////////////////////////////////////////////////////
//                      Г Л А В Н А Я   П Р О Ц Е Д У Р А                    //
// ----------------------------------------------------------------------------
{
  FolderItem.DeleteChildItems(); // Удаляем созданные ранее ссылки
  LoadPlaylist();                // Вызов процедуры загрузки плейлиста и создания из него ссылок
}
+ PascalScript
Var
  gnTotal: Integer=0; // Глобальная переменная счётчика созданных ссылок
// ----------------------------------------------------------------------------
Procedure LoadPlaylist();
Var
  sData, sLink, sName, sImg: String; Item: THmsScriptMediaItem; RegExp: TRegExpr;
Begin  
  // Если ссылка плейлиста начинается на http, то скачиваем, если нет - загружаем как локальный файл
  If LeftCopy(mpFilePath, 4)='http' Then sData := HmsDownloadUrl(mpFilePath, '', true) // Загрузка плейлиста из интернета
  Else                                   sData := HmsStringFromFile(mpFilePath);       // Загрузка плейлиста с локального диска
  
  sData := HmsUtf8Decode(sData); // Декодируем из UTF-8 кодировки

  // Создаём объект для поиска по регулярному выражению
  RegExp := TRegExpr.Create('#EXTINF:(.*?)[\r\n]+(.*?)([\r\n]|$)');
  Try
    If RegExp.Search(sData) Then Repeat Begin
      
      sName := Trim(RegExp.Match(1));  // Получаем значение первой группировки регулярного выражения (первая строка после #EXTINF:)
      sLink := Trim(RegExp.Match(2));  // Получаем значение второй группировки регулярного выражения (вся вторая строка)

      // В наименовании берём только ту часть, которая идёт после последней запятой
      HmsRegExMatch('.*,(.*)', sName, sName);
      
      // Пытаемся получить ссылку на картинку из служебного тега tvg-logo, если нету - то своё значение 
      If Not HmsRegExMatch('tvg-logo="(.*?)"', RegExp.Match, sImg) Then sImg := 'http://wonky.lostcut.net/TVimg/'+HmsPercentEncode(sName, '"A-Z", "a-z", "0-9", "-", ".", "_", "~", "''"')+'.png';
      
      // Создаём ссылку
      Item := HmsCreateMediaItem(sLink, FolderItem.ItemID);
      Item[mpiTitle    ] := sName;     // Наименование
      Item[mpiThumbnail] := sImg;      // Картинка
      Inc(gnTotal);                    // Увеличиваем счетчик созданных ссылок

     End Until Not RegExp.SearchAgain; // Повторяем цикл, пока будем находить по регулярке

  Finally
    RegExp.Free;     // Чтобы ни случилось - освобождаем объект из памяти
  End;

  // Вывод сообщения в лог окно программы
  HmsLogMessage(1, mpTitle+': создано ссылок '+IntToStr(gnTotal));
End;

///////////////////////////////////////////////////////////////////////////////
//                      Г Л А В Н А Я   П Р О Ц Е Д У Р А                    //
// ----------------------------------------------------------------------------
Begin
  FolderItem.DeleteChildItems(); // Удаляем созданные ранее ссылки
  LoadPlaylist();                // Вызов процедуры загрузки плейлиста и создания из него ссылок
End.

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

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

Но это ещё не всё. По-умолчанию, программа думает, что в поле "Ссылка" созданных элементов находится ссылка на видео файл. Но на самом деле там ссылка на HLS поток. Поэтому мы должны программе подсказать, как это воспроизвести.

На самом деле, профили транскодирования "Фильм (основной)" и его производные умеют понимать HLS поток. Только нужно указать, что бы программа использовала файл HLS потока как параметр входящего файла.
Сделать это не просто легко, а очень.
Достаточно  в скрипте получения ссылки присвоить встроенной переменной MediaResourceLink значение на ссылку потока, только в начале поставить пробел.

Скрипт получения ссылки на медиа-ресурс будет у нас такой:
C++Script:

{
  MediaResourceLink = ' '+mpFilePath;
}

PascalScript:

///////////////////////////////////////////////////////////////////////////////
//                      Г Л А В Н А Я   П Р О Ц Е Д У Р А                    //
// ----------------------------------------------------------------------------
Begin
  MediaResourceLink := ' '+mpFilePath;
End.

P.S.: Как выяснилось, необязательно ставить пробел перед значением ссылки для присвоения значения переменной MediaResourceLink в случае когда это ссылка на плейлист m3u8 потока HLS.
Скрипт, который просто присваивает значение mpFilePath как есть переменной MediaResourceLink равносилен отключению вообще использования скрипта получения ссылки. Так что тут можно экспериментировать и пробовать отключать этот скрипт.

Также, видимо, с разными устройствами немного по-разному ведут себя профили транскодирования с подобными потоками HLS. Например в прикреплённом подкасте выставлено использование профиля "Фильмы (основной) - FFMPEG" (которому нужен файл ffmpeg.exe в папке "Transcoders" программы).
Этот файл можно взять здесь.
ffmpeg-2.7-win32-static.7z
У меня на телевизоре Sony обычный профиль "Фильмы (основной)" умеет проигрывать файлы HLS, но, почему-то, очень долго думая перед стартом.

Профиль "Фильмы (основной) - FFMPEG" полностью повторяет встроенный профиль "Фильмы (основной)", только использует ffmpeg, вместо hmsmpeg.

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

Вот и всё. Теперь наш подкаст будет уметь воспроизводить ссылки на m3u8 плейлисты HLS потока.

Прикрепил рабочий созданный подкаст. Если что, задавайте вопросы.

Прикреплённые файлы сообщения

playlist_m3u8.zip 2.84 kb, скачивалось 962 раза, начиная с 2015.08.19

Sony Bravia KDL-32CX523
Спасибо сказали: lidars1

2

Re: Написать скрипт, который бы загружал плейлист m3u8

А можно ли вместо функции FolderItem.DeleteChildItems, которая удаляет все созданные ссылки, задать условие сверки с ранее созданными ссылками по их названиям. Т.Е. как я понял, элемент в подкасте создаётся на основании ссылки, где указывается его название и загружается скриншот. А задача такая, чтобы при добавлении новых ссылок, то чтобы удалялись старые ссылки названий которых нет в новом плейлисте, а которые совпадают по названиям, то чтобы сохранялись. Нужно придумать для подкаста Торрент ТВ (избран+фильмы) где удалена строчка FolderItem.DeleteChildItems и новые каналы  накладываются на старые и свойства файлов сохраняются. Но проблема, что остаются старые не рабочие каналы, которых уже нет в новом плейлисте.

LG 42LM640T
Профиль  Универсальный
Видишь суслика ? Нет ! И я нет ! А он есть !!!

3 (2015.08.17 22:31:19 отредактировано lidars)

Re: Написать скрипт, который бы загружал плейлист m3u8

Проверена работа данного скрипта в действии,
выявился следующий любопытный момент.

За эталон был принят скрипт RuDetective.tv.hdf, умеющий прекрасно работать с HLS потоками.

Пример работы эталонного скрипта на канале Россия HD

+ открыть спойлер

https://hms.lostcut.net/misc.php?action=pun_attachment&item=274

Эталон демонстрирует прекрасную работу, HLS поток в HD качестве с битрейтом 8 Mbits идет на телевизор,
вся статистика доступна, загрузка CPU HMS в пределах 11 %

Второй пример:

+ открыть спойлер

https://hms.lostcut.net/misc.php?action=pun_attachment&item=275

Ток же поток из того же источника, из  статистики доступно только размер временного файла,
загрузка CPU HMS уже в пределах 27 %

Прикреплённые файлы сообщения

HD-1-11-900.png 47.87 kb, скачивалось 408 раз, начиная с 2015.08.17

HD-2-27-900.png 35.35 kb, скачивалось 367 раз, начиная с 2015.08.17

4 (2015.08.17 22:42:22 отредактировано lidars)

Re: Написать скрипт, который бы загружал плейлист m3u8

Leshiy71 пишет:

А можно ли вместо функции FolderItem.DeleteChildItems, которая удаляет все созданные ссылки, задать условие сверки с ранее созданными ссылками по их названиям.

На мой взгляд, текущее условие загрузок новых ссылок из источника и удаление предыдущего списка правильное, это универсальный скрипт,
человек сам задает список ссылок, предполагается, что они все рабочие,
если делать проверку каждой загружаемой ссылки на работу, процесс загрузки может сильно затянуться,
тем более, что источник может вещать в разных форматах и протоколах.

Хотя, по желанию Автора, можно и добавить отдельный переключатель - проверка ссылки на работу,
но это будет очень медленно

5

Re: Написать скрипт, который бы загружал плейлист m3u8

Подправил скрипты в первом сообщении и обновил там подкаст.

Из-за того, что некрасиво брал название, если там встречается служебный тег.
Изменил регулярное выражение поиска двух подряд идущих строк, первая которая начинается на #EXTINF:, а вторая целиком, кончающаяся переводом строки или концом файла.

TRegExpr.Create('#EXTINF:(.*?)[\r\n]+(.*?)([\r\n]|$)');

А ниже в само название уже обрезаю с последней запятой.
Тогда, строки:

#EXTINF:-1 tvg-name="983? ,Первый канал HD
http://hlsstr03.svc.iptv.rt.ru/hls/CH_C06_1TVHD/bw3000000/variant.m3u8?version=2

в переменную sName из первой группировки сначала попадёт строка:
"-1 tvg-name="983? ,Первый канал HD"
а потом, после команды:

HmsRegExMatch('.*,(.*)', sName, sName);

в переменной sName будет уже - "Первый канал HD".


lidars пишет:

Проверена работа данного скрипта в действии,
выявился следующий любопытный момент.

За эталон был принят скрипт RuDetective.tv.hdf, умеющий прекрасно работать с HLS потоками.

Эталон демонстрирует прекрасную работу, HLS поток в HD качестве с битрейтом 8 Mbits идет на телевизор,
вся статистика доступна, загрузка CPU HMS в пределах 11 %

Ток же поток из того же источника, из  статистики доступно только размер временного файла,
загрузка CPU HMS уже в пределах 27 %

Интересно, что на моём телеке со стандартным профилем всё очень долго. А с установленным - практически мгновенно. Поэтому в выложенном подкасте стоит использование специального профиля.

Попробуйте поэкспериментировать, во-первых, вообще очистите профиль транскодирования у подкаста или включите другой. Во-вторых, отключите использование скрипта получения ссылки на медиаресурс (это равносильно в скрипте по Alt+4 убрать добавление пробела и сделать строку просто MediaResourceLink = mpFilePath;).

Видимо, под разные устройства немного по-разному профили ведут себя (из-за разных настроек). Поэтому нужно настраивать использование профилей конкретно под себя.

Sony Bravia KDL-32CX523
Спасибо сказали: lidars1

6

Re: Написать скрипт, который бы загружал плейлист m3u8

lidars пишет:

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

Leshiy71 говорит о случае, который бы был полезен конкретно в другом подкасте. Перенесу данный вопрос в отдельную тему.

Leshiy71 пишет:

А можно ли вместо функции FolderItem.DeleteChildItems, которая удаляет все созданные ссылки, задать условие сверки с ранее созданными ссылками по их названиям

Можно всё, если захотеть. Перенёс вопрос сюда.

Sony Bravia KDL-32CX523

7 (2015.08.18 20:45:05 отредактировано lidars)

Re: Написать скрипт, который бы загружал плейлист m3u8

Сейчас названия каналов вносятся правильно,
следующий шаг - добавление логотипов.

Тут есть два пути:
1 - Быстрый - если в загружаемом файле присутствуют служебные теги tvg-logo,
тогда логотип берем либо из локального пути, либо по удаленной ссылке,
пример в приложении.
2 - Медленный, поиск по названию канала.
Так как все названия каналов стандартизованы и хранятся в единой базе,
то при отсутствии тега tvg-logo берем логотип канала по названию с любого публичного сервера.

Приложение:
Пример листа Sample-zabava-hls.m3u с вариантами логотипов

Прикреплённые файлы сообщения

Sample-zabava-hls.m3u 682 b, скачивалось 852 раза, начиная с 2015.08.18

8

Re: Написать скрипт, который бы загружал плейлист m3u8

lidars пишет:

Сейчас названия каналов вносятся правильно,
следующий шаг - добавление логотипов.

Тут есть два пути:
1 - Быстрый - если в загружаемом файле присутствуют служебные теги tvg-logo,
тогда логотип берем либо из локального пути, либо по удаленной ссылке,
пример в приложении.

Не вопрос, достаточно добавить использование ещё одной переменной - sImg и в неё заносить значение ссылки на картинку.
Если есть значение тега tvg-logo, то берём оттуда. Если нет, то формируем ссылку по-умолчанию.

      if (!HmsRegExMatch('tvg-logo="(.*?)"', RE.Match, sImg)) sImg = 'http://wonky.lostcut.net/TVimg/'+sName+'.png';
lidars пишет:

2 - Медленный, поиск по названию канала.
Так как все названия каналов стандартизованы и хранятся в единой базе,
то при отсутствии тега tvg-logo берем логотип канала по названию с любого публичного сервера.

Не совсем понятно, что вы имеете в виду. Что за единая база? А то мы тут совместными усилиями с Leshiy71 базу логотипов  картинок с названиями каналов собрали, насколько нашли. Закинул я их в http://wonky.lostcut.net/TVimg/, где <Название канала>.png хранятся картинки. Если такого названия нет - от отдаётся общая картинка (телевизор на оранжевом фоне). Там с разных ресурсов понаграблено и из архивов. Но всё равно не все каналы. Всего сейчас 776 файлов.

Обновил код и подкаст в первом сообщении.

Sony Bravia KDL-32CX523
Спасибо сказали: lidars1

9 (2015.08.19 17:31:59 отредактировано lidars)

Re: Написать скрипт, который бы загружал плейлист m3u8

Проверена работа скрипта путем загрузки тестового плейлиста.

Большинство каналов определилось с картинками, но некоторые были без картинок.
Например, канал TV1000 Action.
Прикладываю официальную базу 3900 логотипов syslogo.tar, в которой данный канал находится под номером 1073.png

Требования к логотипам = формат 136х104х32 , расширение .png

На этом сайте собраны логотипы и названия всех каналов мира, в том числе и России.

http://www.lyngsat-logo.com/tvcountry/ru_1.html

Для стандартизации логотипов без ручной работы никак не обойтись, два варианта:
1 - брать готовую базу из официального пака syslogo.tar, но они там закодированы под номерами
для OS платформы Fusion, то есть нужно файл 1073.png сохранять в виде файла TV1000 Action.png

2 - в ручном режиме сохранять недостающие логотипы с сайта lyngsat-logo.com в требуемом формате.

10

Re: Написать скрипт, который бы загружал плейлист m3u8

Хмм.. Сейчас посмотрел и выяснил ещё кое-что. Оказывается некоторые картинки каналов не хотели отображаться нормально из-за присутствия некоторых символов в названии и опытным путём установил, что вместо:

sImg = 'http://wonky.lostcut.net/TVimg/'+sName+'.png';

лучше всего делать:

sImg = 'http://wonky.lostcut.net/TVimg/'+HmsPercentEncode(sName, '"A-Z", "a-z", "0-9", "-", ".", "_", "~", "\'"')+'.png';

Поправил в коде и подкасте.

lidars пишет:

Прикладываю официальную базу 3900 логотипов syslogo.tar, в которой данный канал находится под номером 1073.png

Очень ждём ссылку на файл.

Sony Bravia KDL-32CX523

11

Re: Написать скрипт, который бы загружал плейлист m3u8

Так, архив то получил. А теперь как связать то названия с ID? Есть где взять такую информацию?

Sony Bravia KDL-32CX523

12

Re: Написать скрипт, который бы загружал плейлист m3u8

WendyH пишет:

Так, архив то получил. А теперь как связать то названия с ID? Есть где взять такую информацию?

Это было бы слишком просто - такой информации нет.
Привязку кодов знают только разработчики OS платформы Fusion,
нам - простым пользователям, остается только визуальный просмотр и ручное переименование нужного логотипа.

Либо - второй вариант -
сохранять недостающие логотипы с сайта lyngsat-logo.com в формате 136х104х32 , расширение .png

Хотел сделать табличку, какие каналы в HMS без логотипов,
однако не обнаружил такого инструмента.
В итоговой таблице параметров канала ссылка на логотип отсутствует, как класс!

13

Re: Написать скрипт, который бы загружал плейлист m3u8

Ээ.. ну тогда всё. Вариант с архивом отпадает.
Вообще, я провив телевидения как такового, поэтому занимаютсь этими вопросами постольку поскольку, чтобы кто-то мог посмотреть как именно подобные вопросы мог решить. Поэтому у меня нет большого энтузиазма заниматься лого тв каналов и ими вообще.

Я уже где-то писал, что если у вас или кого-то будет большое желание чтобы в телевизионных подкастах отображались лого, то можете любыми своими силами найти эти картинки, сохранить в формате <имя канала>.png, запаковать и дать ссылку на архив. Я закину эти картинки на сервер и они начнут отображаться.
Врядли я сам буду их специально собирать.

Максимум - написать граббер, который обойдёт сайт где есть эти наименования и картинки и сохранит их.
Например, поиск по самому сайту lyngsat-logo.com делать толком не получится, там не заложен поиск ими самими, а загружать кучу страниц для поиска постоянно тоже не годится. Поэтому остаётся только просто написать скрипт, который обойдёт все страницы с российскими каналами, например, и сохранит логотипы.
В общем, скорее всего так и сделаю. Надеюсь не забанят на интенсивное сканирование.

Sony Bravia KDL-32CX523
Спасибо сказали: lidars1

14

Re: Написать скрипт, который бы загружал плейлист m3u8

Тогда еще такой вопрос - как сохранить загруженный лист вместе с настройками подкаста в виде файла .hdf

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

т.е. скрипт должен проходить по списку своего подкаста и сохранять их всех в одном файле  .hdf

15

Re: Написать скрипт, который бы загружал плейлист m3u8

lidars пишет:

Тогда еще такой вопрос - как сохранить загруженный лист вместе с настройками подкаста в виде файла .hdf

Да, HMS те ссылки, которые в подкасте, не сохраняет, считая что они должны создаваться подкастом. И это логично. Но то, что находится в папке - сохраняет, даже ссылки.
Но у папки скрипт немного в другом месте.

Можно добавить папку и добавить данный скрипт в "Скрипт создания подкаст-лент (Alt + 1)".
Вызывается на выполнение он только с программы, правой клавишей мышки и "Создать ленты подкастов".

Прикрепил пример.
Заметьте, когда загрузите пример в программу, увидите в папке уже ранее созданные ссылки. Т.е. их можно сохранять и загружать.

Прикреплённые файлы сообщения

playlist_m3u8_folder.zip 2.63 kb, скачивалось 805 раз, начиная с 2015.08.19

Sony Bravia KDL-32CX523
Спасибо сказали: lidars1

16

Re: Написать скрипт, который бы загружал плейлист m3u8

Да уж, жесть какая. Написал скрипт, который просканирует и загрузит все TV логотипы. В итоге - 13419 файлов. Но тут для нас какая беда, там все названия, даже русских каналов - на английском. А у нас в ссылках, в основном, русские названия присутствуют.

Даже не знаю, весь напрочь архив заливать на свой сервак или ну его..

Кому надо, архив вот: https://yadi.sk/d/OrAcxzryiYRaV

Sony Bravia KDL-32CX523

17 (2015.08.19 22:36:15 отредактировано lidars)

Re: Написать скрипт, который бы загружал плейлист m3u8

WendyH пишет:

Даже не знаю, весь напрочь архив заливать на свой сервак или ну его..

Посмотрел логотипы, вполне достойного качества, предложение такое=
сделать пакетную обработку для приведения к официальному размеру 136х104х32,
даже по хорошему в 2 прохода:
сначала сделать Trimm для удаления подложки
потом Resize до размера 136х104х32
и залить полученное на сервер,

в любом случае, все английские каналы должны определяться на раз,
пример = файл "TVA Sports HD.png" полностью соответствует названию канала "TVA Sports HD"

далее, по вопросу русских каналов, задача решается в 2 прохода, например, канал "24 Вести",
сначала ищем русский файл  "24 Вести", если файл не существует,
делаем транскрипцию в латиницу и ищем второй файл
"24 Vesti.png"

и он таки есть в нашей коллекции !
Бинго !

Добавил два примера логотипа одного канала:
"24 Vesti.png" - исходный файл
"24-Vesti-32b.png" - правильный файл логотипа в формате 136х104х32

Прикреплённые файлы сообщения

24 Vesti.png 6.04 kb, скачивалось 378 раз, начиная с 2015.08.19

24-Vesti-32b.png 20.74 kb, скачивалось 316 раз, начиная с 2015.08.19

18

Re: Написать скрипт, который бы загружал плейлист m3u8

У меня к вам много вопросов.
Что за "официальный размер"?

lidars пишет:

сделать Trimm для удаления подложки

Что за Trimm? Или это образно?
Удаление подложки - вы имеете ввиду убрать лишний белый фон? Как это сделать и как определить?
Какова подложка здесь: http://www.lyngsat-logo.com/logo/tv/num/1_hd_ru.png? А здесь http://www.lyngsat-logo.com/logo/tv/num/1music_ng.png?

lidars пишет:

потом Resize до размера 136х104х32
и залить полученное на сервер

В ваших примерах, может вы и не обращаете внимание, но моё внутреннее чувство эстетики страдает, когда я вижу растянутые картинки. Непропорциональное растяжение (просто указав размеры) искажаете логотип.

lidars пишет:

сначала ищем русский файл  "24 Вести", если файл не существует,
делаем транскрипцию в латиницу и ищем второй файл
"24 Vesti.png"

Кто ищет, скрипт в подкасте? Но он там ничего не ищёт, в смысле файлов. Он берёт только адрес картинки и в параметрах создаваемой ссылки на видео указывает его. Т.е. указывается ссылка картинки:

      // Создаём ссылку
      Item = HmsCreateMediaItem(sLink, FolderItem.ItemID);
      Item[mpiTitle    ] = sName; // Наименование
      Item[mpiThumbnail] = sImg;  // Картинка

И сама программа Домашний медиа-сервер умеет прекрасно передавать устройству картинку и масштабировать её. Да и устройства очень разные бывают, подозреваю что до единого стандарта там далеко.

Но согласен, все картинки должны быть в единой пропорции, оптимальной для отображения на устройствах. Сейчас картинки 132x99, это пропорция 4:3. Не знаю, нужно проверить, может пропорция 16:9 будет лучше отображаться или какая-то другая. И если менять размер - то пропорционально. И поверьте, в программе HMS можно указывать размеры практически любые, он сам, в зависимости от настроек устройства воспроизведения, отмасштабирует и передаст медиа-плееру. Лишь бы слишком маленькие (некачественные) не были.
Например, я могу проверить как отображаются на моём телевизоре Sony, но я не уверен, что это обязательно окажется таким-же оптимальным для других устройств, например Dune HD или DLNA плеере на мобильном. Хотя... Может там всё стандартизовано в плане отображения картинок папок и превью видео?

lidars пишет:

далее, по вопросу русских каналов, задача решается в 2 прохода, например, канал "24 Вести",
сначала ищем русский файл  "24 Вести", если файл не существует,
делаем транскрипцию в латиницу и ищем второй файл
"24 Vesti.png"

Дело в том, что специально для тех подкастов, где вообще негде взять картинку, как в подкасте загрузки плейлистов TTV Autoplaylist, было мною для удобства сделана папка с картинками и залита на мой сервер. И в тех подкастах, где нет информации о картинках, для простоты можно использовать ссылку на мою папку с указанием имени картинки. Имя картинки = имя канала. Это практически прямое обращение к файлу, который просто выложен на серваке.
У меня на сервере используется nginx и если я могу там в настройках указать, что при обращении к несуществующему файлу возвращать другой, то как сделать чтобы он ещё и транскрипцию сделал для ещё и по какой-то таблице замен символов - то это я без понятия. Если вы знаете как - можете подсказать. Но я сомневаюсь что там такое вообще возможно (только отдельный модуль писать и при сборке указывать).

Sony Bravia KDL-32CX523

19

Re: Написать скрипт, который бы загружал плейлист m3u8

Отвечаю по очереди:

Trim - удаление лишнего заднего фона.

Вариантов решения, как минимум 3:

1 - Запуск пакетной обработки в программе Photoshop

Открываете одну картинку, которую надо обрезать, идете в меню Window -> Actions, Создаете новый Action (Create New Action), автоматически начнется запись действий. Идете в Image -> Trim, ставите галочку Top Left Pixel Color, жмете ок. Останавливаете запись Action (кнопочка стоп).
Далее идете в File -> Automate -> Batch,
В поле Action — указываете только-что созданный вами Action
В поле Source — указываете Folder, жмете кнопку Choose, выбираете вашу папку с картинкам.
В поле Destination — указываете Save and Close
и нажимаете ОК.

2 - Запуск пакетного файла, например , на питоне (2.7, PIL):

from PIL import Image
import math
import sys

way = '1.png'
print sys.argv[1]
way = sys.argv[1]
image = Image.open(way)
width = image.size[0]
height = image.size[1]
alpha = image.getpixel((2,2))
left = width
right = 0
top = height
bottom = 0
print str(alpha)
for x in range(width):
    for y in range(height):
        rng = math.sqrt(math.pow(image.getpixel((x,y))[0]-alpha[0],2)+math.pow(image.getpixel((x,y))[1]-alpha[1],2)+math.pow(image.getpixel((x,y))[2]-alpha[2],2))
        #print str(rng)
        if rng > 89:                     
            if x<left:
                left = x
            if x>right:
                right = x
            if y<top:
                top = y
            if y>bottom:
                bottom = y
print str(left)+ ','+str(top)+'   '+str(right)+','+str(bottom)               

width = right-left
height = bottom-top
img = Image.new("RGBA", (width,height), (0,0,0,0))
for x in range(width):
    for y in range(height):
        img.putpixel((x,y),image.getpixel((x+left,y+top)))


img.save("test1.png", "PNG")

print "Done!"

В качестве параметра получает название файла, кропает, создает файл crop_имя.расширение.
Скормите этот скрипт bat файлу, который для всех файлов в папке его применит и будет результат

3 - Вариант обработки на сервере средствами PHP, более подробно здесь:
http://php.net/manual/ru/book.imagick.php

Это ответ на первый вопрос - как привести все логотипы к единому виду.

20

Re: Написать скрипт, который бы загружал плейлист m3u8

Извиняюсь, что вставлю свои "5 копеек"... А оно того стоит?
Я понимаю если канал на HMS не запустился, а с сайта идет - вот тут проблема. Канал не растянулся на весь экран - проблема.
А лого не высветилось канала - да эстетика и все такое... но так заморачиваться...
Еще раз прошу прощения за то что влез :rolleyes:

21

Re: Написать скрипт, который бы загружал плейлист m3u8

Еще один вариант официальных логотипов,
для OS платформы Fusion,
в комплекте:
логотипы каналов разрешением 136x104 в количестве 3437 штук в едином стиле
рассортированные по странам
(Названия стран и соответствия названиям файлов лежат в файле logosdb в 2х вариантах)

Залить на форум не получилось. выкладываю ссылкой: http://my-files.ru/2gw0h9

22 (2015.08.20 14:53:11 отредактировано lidars)

Re: Написать скрипт, который бы загружал плейлист m3u8

mch пишет:

А оно того стоит?

Конечный продукт - который хотелось бы получить, благодаря Автору,
это универсальный скрипт,
который позволяет импортировать произвольное количество плейлистов
в один сборный пакет,
с возможностью выбора лучшего источника,
передача на ТВ, включая логотип канала и программу передач ...

как-то так это видится, многое из которого уже реализовано Автором в отдельных и разных скриптах.
И унификация (стандартизация) на основе официальных данных,
в таком деле большое подспорье ...

23

Re: Написать скрипт, который бы загружал плейлист m3u8

lidars пишет:

Отвечаю по очереди:

Trim - удаление лишнего заднего фона.

Вариантов решения, как минимум 3:

1 - Запуск пакетной обработки в программе Photoshop
2 - Запуск пакетного файла, например , на питоне (2.7, PIL):
3 - Вариант обработки на сервере средствами PHP, более подробно здесь:
http://php.net/manual/ru/book.imagick.php

Это ответ на первый вопрос - как привести все логотипы к единому виду.

1 - И что у вас не получилось?
2 - немного странноватый скрипт, но за строчку

rng = math.sqrt(math.pow(image.getpixel((x,y))[0]-alpha[0],2)+math.pow(image.getpixel((x,y))[1]-alpha[1],2)+math.pow(image.getpixel((x,y))[2]-alpha[2],2))

спасибо
Запускать bat-ник с вызовом питоновского скрипта зачем? когда всё можно следать там же.
Это единственный вариант, который меня заинтересовал.
3 - Не серверное это дело, кучу файлов обрабатывать. Я знаю что такое ImageMagick и по той ссылке его описание.
Вы бы мне ещё ссылку на справочник по языку Phyton бы дали, типа "там более подробнее".

По поводу архива платформы Fusion. Вы видели те названия в файле logosdb.csv? Они соответствуют названиям каналов? Даже в транскрипции? Что мне с ним делать?

Я вам готов помочь. Как и любому. Всё, что касается кодинга по HMS.
У меня такое ощущение, что вы хотите, чтобы я подготовил вам набор картинок.
Обычно, чтобы немного отрезвить некоторых, я отвечаю: это совсем недорого вам обойдётся. 10000 рублей - и я вам подготовлю картинки в лучшем виде.
Или просто могу помочь подсказать в реализации какой-то идеи.

Да, второй вариант меня настолько заинтересовал, что я всё-таки разобрался и сделал скрипт. Долго не мог понять, почему getpixel возвращал int, но в итоге всё сделал. Определяется размер изображения, crop-ается, увеличивается пропорционально до ближайшей нужной ширины или высоты, добавляется фон по той стороне, где нужно добавить до нужного размера.
Вот crop_resize.py, можете разобраться и он всё за вас сделает.

from PIL import Image
import math
import sys
import os

InDir  = "D:\\tvimg"
OutDir = "D:\\tvimg_new"
newWidth  = 136
newHeight = 104
count  = 0;

def crop_resize( filename ):
  fileIn = os.path.abspath(os.path.join(InDir , filename))
  fileOut= os.path.abspath(os.path.join(OutDir, filename))
  try:
    image  = Image.open(fileIn)
    image  = image.convert('RGB')
    alpha  = image.getpixel((2,2))
    width, height = image.size
    left   = width
    right  = 0
    top    = height
    bottom = 0

    for x in range(width):
        for y in range(height):
            rng = math.sqrt(math.pow(image.getpixel((x,y))[0]-alpha[0],2)+math.pow(image.getpixel((x,y))[1]-alpha[1],2)+math.pow(image.getpixel((x,y))[2]-alpha[2],2))
            if rng > 89:                      
                if x<left:
                    left = x
                if x>right:
                    right = x
                if y<top:
                    top = y
                if y>bottom:
                    bottom = y

    image = image.crop((left, top, right+1, bottom+1))

    width, height = image.size

    kw = float(newWidth ) / width
    kh = float(newHeight) / height

    k = kw if kw < kh else kh # lowest coefficient

    width  = int(width  * k);
    height = int(height * k);

    image = image.resize((width, height), Image.ANTIALIAS)

    wr = (newWidth  - width )/2 if newWidth  > width  else 0
    hr = (newHeight - height)/2 if newHeight > height else 0

    newImage = Image.new("RGB", (newWidth, newHeight), alpha)
    newImage.paste(image, (wr, hr))

    newImage.save(fileOut, "PNG")

    width, height = newImage.size

    print filename+": " + str(width)+ 'x'+str(height)

  finally:
    return;

for filename in os.listdir(InDir):
    crop_resize( filename )
    count += 1
    if count > 3:
        break

print "Done!"

Если вам очень нужно, то можете подготовить картинки для каналов в виде <название канала>.png и кинуть мне ссылку на архив. Я залью его на свой сервер, чтобы можно было к ним обращаться по имени канала. Мне будет не сложно. Но, желательно, не 13000 файлов.

Sony Bravia KDL-32CX523

24

Re: Написать скрипт, который бы загружал плейлист m3u8

Логика работы OS платформы Fusion следующая:
например, название канала "НТВ-ПЛЮС Футбол"
причем название канала может быть написано в произвольном регистре,
например "нтв-плюс фУТБОЛ".
Так как платформа Fusion международная,
для выбора правильного логотипа делается так:
переводим все русские названия каналов сначала в нижний регистр, на выходе:
нтв-плюс футбол
затем делаем транскрипции в латиницу
ntv-plus futbol
затем удаляем все пробелы и дефисы из названия
ntvplusfutbol

Бинго!
OS платформы Fusion показывает иконку 2143.png

Данная запись показана в строчке logosdb.csv:

Russia;ntvplusfutbol;2143;

Но если работа с логотипами сложна, можно просто перекопировать, например,
еще логотипы, правда, все разномастные, с этого ресурса:

http://logo.fight-show.ru/logos/

Логотипы, это конечно, вторично, просто хотелось бы сразу сделать правильно,
чтобы можно было гордится готовым продуктом, качеством и тщательностью изготовления.

В чем преимущество подхода Fusion -
она не заставляет делать идентичное написание названия канала именно "НТВ-ПЛЮС Футбол" !

Это самое простое решение - искать иконку "НТВ-ПЛЮС Футбол", но оно не самое универсальное ...
а если название канала "нтв-плюс фУТБОЛ" - логотипа уже не будет ?

Решение, в любом случае, за Автором ...

25

Re: Написать скрипт, который бы загружал плейлист m3u8

IMHO

Идея с универсальным решением сама по себе занятная. Но давайте проанализируем, сколько неопределенных переменных должно быть учтено для этого.

1. Иконки каналов (графические параметры).
В HMS->настройки профиля устройства есть такие параметры:

+ открыть спойлер

http://i62.tinypic.com/35irdbl.jpg

И конвертнет он любой входной формат в эти цифры. Конечно, сглаженный логотип с прозрачным фоном, идеально выглядящий на любом устройстве - это круто, но будет ли это везде работать? "Переварит" ли конкретный рендерер биты прозрачности в логотипе и не превратится ли этот логотип в мешанину пикселей? Гарантии 100% совместимости нет.
2. Связка: файл логотипа - название канала.
Ну нет единого стандарта пока, увы. И, если с западными каналами еще более-менее можно синтаксически выкручиваться, то как решит транслитерировать тот или иной сайт - одному богу известно, я уже молчу про иврит, арабский, иероглифы и прочее. Напрашивается по сути БД, которую нужно постоянно актуализировать ради идеи универсальности.

И все это ради иконок в списке каналов. Не могу не согласиться с WendyH - любой каприз за ваши деньги :) Если этот функционал реально востребован - ну пусть народ "проголосует" рублем, ибо для реализации и главное поддержки такого великолепия усилия исполнителя выходят далеко за рамки альтруизма.

26

Re: Написать скрипт, который бы загружал плейлист m3u8

lidars пишет:

Логика работы OS платформы Fusion следующая:
например, название канала "НТВ-ПЛЮС Футбол"

Вы только один пример посмотрели?

Sony Bravia KDL-32CX523

27

Re: Написать скрипт, который бы загружал плейлист m3u8

Я привел только один пример,
сама OS платформы Fusion рассчитана на 10 000 записей о телеканалах в формате 136х104х32,
так как она изначально международная,
в файле конкретно для региона Россия приведены записи 180 каналов,

можно не заниматься этими логотипами, я просто высказываю свою точку зрения ...

28

Re: Написать скрипт, который бы загружал плейлист m3u8

lidars пишет:

Я привел только один пример,
сама OS платформы Fusion рассчитана на 10 000 записей о телеканалах в формате 136х104х32,
так как она изначально международная,
в файле конкретно для региона Россия приведены записи 180 каналов,

можно не заниматься этими логотипами, я просто высказываю свою точку зрения ...

Я перестал вас понимать.
Вы даёте для примера

#EXTM3U
#EXTINF:-1 group-title="Zabava" tvg-logo="https://avatars.yandex.net/get-tv-channel-logos/142288078526943840/small" tvg-name="8",Техно 24
http://hlsstr04.svc.iptv.rt.ru/hls/CH_24TEHNO/bw1500000/variant.m3u8?version=2
#EXTINF:-1,5 канал
http://hlsstr04.svc.iptv.rt.ru/hls/CH_5TV/variant.m3u8?version=2
#EXTINF:-1,8 канал
http://hlsstr01.svc.iptv.rt.ru/hls/CH_8CHANNEL/variant.m3u8?version=2
#EXTINF:-1 tvg-name="983? ,Первый канал HD
http://hlsstr03.svc.iptv.rt.ru/hls/CH_C06_1TVHD/bw3000000/variant.m3u8?version=2
#EXTINF:-1,Россия HD
http://hlsstr04.svc.iptv.rt.ru/hls/CH_C05_RUSSIA1HD/bw3000000/variant.m3u8?version=2
#EXTINF:-1 group-title="Zabava" tvg-logo="c:/TV-Playlists/24 Док.png" tvg-name="5",24 Док
http://hlsstr04.svc.iptv.rt.ru/hls/CH_24DOC/variant.m3u8?version=2
#EXTINF:-1 group-title="Zabava" tvg-logo="c:/TV-Playlists/2х2.png" tvg-name="7",2х2
http://hlsstr04.svc.iptv.rt.ru/hls/CH_2X2/variant.m3u8?version=2

И просите, чтобы картинки на каналы подхватывались, если нет tvg-logo тега. По какому критерию формировать ссылки на картинки? (в программе Домашний медиа-сервер просто указывается  ссылка на картинку). Какая должна быть эта ссылка?
Почему именно такие вы хотите видеть размером и прочие вопросы вы оставляете не отвеченными. Что вы хотите я не понял.

Sony Bravia KDL-32CX523

29

Re: Написать скрипт, который бы загружал плейлист m3u8

WendyH пишет:

Да уж, жесть какая. Написал скрипт, который просканирует и загрузит все TV логотипы. В итоге - 13419 файлов. Но тут для нас какая беда, там все названия, даже русских каналов - на английском. А у нас в ссылках, в основном, русские названия присутствуют.

Даже не знаю, весь напрочь архив заливать на свой сервак или ну его..

Кому надо, архив вот: https://yadi.sk/d/OrAcxzryiYRaV

По поводу логотипов - это был просто развернутый ответ на вопрос -
что делать с английскими названиями файлов логотипов, только и всего.

Я просто попытался сказать, что может быть, имеет смысл немного усложнить алгоритм поиска картинок,
и предложил целых три варианта, вместо одного явного:
для примера - канал "24 Вести"
1 - сначала ищем русский файл  "24 Вести",
если файл не существует,
2 - делаем транскрипцию в латиницу и ищем второй файл
"24 Vesti.png"
если файл не существует,
3 - используем базу Fusion и ищем файл 24vesti

Вероятность найти логотип увеличивается в 3 раза,
это было просто предложение ...

30

Re: Написать скрипт, который бы загружал плейлист m3u8

По вопросу о официальных размерах логотипов

Я не являюсь разработчиком OS платформы Fusion,
поэтому не могу обьяснить, почему они утвердили в качестве стандарта
логотип телеканалов в формате 136х104х32 PNG.

Разработкой решений для Smart TV и Fusion занимается консорциум из нескольких крупнейших производителей,
вот их официальный сайты:

http://smarttv-alliance.org

Сайты разработчиков:

http://yourappontv.com
http://operasoftware.com/products/tv/tv-store

Тема на официальном форуме разработчика Fusion:

http://supportforum.philips.com/ru/showthread.php?436