1 (2018.10.12 14:26:21 отредактировано fctsu001)

Тема: Просмотр потока со спутникового ресивера через HMS

Озаботился недавно просмотром через HMS спутникового телевидения.
В домашней сети имеется спутниковый ресивер DreamBox DM800HD Pvr под ос Enigma. Просмотр стрима через vlc.

+ с чего всё началось

Для инициализации просмотра сервиса нужно зайти на url вида хттп://dreambox/web/stream.m3u?ref={servicereference}, где {servicereference} вида 1:0:16:841:15:70:1680000:0:0:0:
результатом будет адрес потока, у меня это хттп://dm800:8001/1:0:16:841:15:70:1680000:0:0:0:

Создал в разделе "Интернет телевидение" каналы:

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

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

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

Но есть проблемы, которые не знаю как решать, помогите, кто может. FAQ и другие ресурсы по настройке читал в режиме листания, если недосмотрел - просьба не пинать, просто поделиться ссылкой на инфу. http везде заменил на хттп, иначе форум не даёт отправить сообщение, слишком много ссылок.

1. Перед получением стрима необходимо переключить тюнер на нужный канал. При запросе стрима это автоматически не происходит. Команда переключения выглядит как url вида хттп://dm800/web/zap?sRef={servicereference}
или через telnet wget -q -O - хттп://dm800/web/zap?sRef={servicereference}
Как мне при запуске канала перед получением потока выполнить скрипт - дать команду переключения на канал?
2. При запуске стрима HD каналов периодически происходит обрыв в начале передачи (на 3-4 секунде), при просмотре через vlc просто перезапускаю и всё показывает. На HMS получается, что после повторного выбора опять крутит эти 3 секунды, сколько ни запускай, как можно заставить снова брать стрим, а не брать кэшированный фрагмент? Кстати такая проблема существует и с недокачанными торрентами, после докачки заново не транскодирует, продолжает брать ранее закэшированные данные, пересканирование каталогов и перезапуск сервера не помогает.
3. При прекращении просмотра транскодирование не прекращается, поток с устройства по прежнему берётся, транскодер работает. При попытке повторного просмотра прекращается предыдущее транскодирование.

В процессе решения проблемы были сформулированы следующие задачи:

1. Переключение тюнера на требуемый к просмотру канал перед запросом потока.
2. Автоматическое формирование списка просматриваемых каналов.
При решении первых двух задач выяснилось, что при запросе ресурса различными устройствами применяется один и тот же профиль транскодирования, установленный по умолчанию для транскодера.
Поэтому появилась 3-я задача:
3. Установить для всех каналов нужный устройствам профиль транскодирования.

Все эти задачи были успешно выполнены руками уважаемого WendyH при моём участии в качестве тестировщика.

Задачи выполнялись для конкретного случая (моя домашняя сеть, в которой, кроме спутникового ресивера имеется 2 DLNA телевизора - Sony, LG, сетевой проигрыватель WDTV Live и куча устройств на андроиде), но при решении задач скрипты делались так, что бы их мог использовать любой пользователь HMS, имеющий спутниковый ресивер под управлением Enigma 2.

Скрипты проверялись с версией HMS В. 2.33 от 12.09.2017.

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

Вторая и третья задача выполнены путём импорта в раздел медиа-ресурсов HMS "Интернет телевидение" папки с коллекцией фильмов.
          dm800 test.hdf

+ Установка задания обработки события воспроизведения сводится к импорту конфигурации обработки и установки её на событие:

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

+ Импорт папки с коллекцией:

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

Коллекция создаётся из каналов пользовательских пакетов на ресивере при входе на устройстве в импортированную папку.
Особенность: в самом HMS Вы ничего не увидите, если нужно увидеть ресурсы на HMS, надо выполнить скрипт руками.

+ Теперь немного о настройках:

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

После импорта динамической папки, остаётся отредактировать комментарии в папке.
В импортируемом файле они:
--piconsPath="\Home Media Server\HMS\Thumbnails\" --deviceAddr="dm800" --tvFileExt="mpg",

--piconsPath - адрес локальной папки с картинками-пиктограмами каналовна компьютере, где установлен HMS в пользовательском каталоге с данными HMS, при формировании адреса в его начало добавляется переменная окружения %LOCALAPPDATA%.
Если кому то не понятно, то после формирования ресурсов можно будет открыть папку для изменения и посмотреть путь до картинок. Картинки можно скачать в интернете или прямо со спутникового ресивера (если они там есть). Картинки (пиконы) в формате .png, я проверял на пиконах с размером 220x132.
--deviceAddr - сетевое имя (или IP-адрес) устройства.
--tvFileExt="mpg" - этот параметр сделан для указания типа файла, которое использует устройство, которому требуется особый профиль транскодирования (у меня это телевизор Sony).
Если Вам это нужно, то тип файла можно установить в настройках устройства - транскодер - Интернет-ТВ.
Для телевизора Sony выбирается профиль транскодирования "Фильмы - VLC - FFMPEG" для остальных устройств выбирается профиль без перекодирования "Интернет телевидение (входной поток)".
Попутно выяснил, как работает dual pipe транскодирование с vlc - mpeg, после распаковки контейнера распакованный поток отправляется в транскодер ffmpeg с параметрами, взятыми из установок для устройства в разделе транскодер - фильм.
Как оказалось, мой телевизор не переваривает входной поток выше 8 мбит, пришлось ограничить в настройках раздела фильм.

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

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

dm800 test.hdf 4.26 kb, скачивалось 550 раз, начиная с 2018.10.07

dvb-streem.png 33.13 kb, скачивалось 200 раз, начиная с 2018.09.26

EventProcessing.png 99.76 kb, скачивалось 209 раз, начиная с 2018.10.07

LoadCollectionFolder.png 71.67 kb, скачивалось 198 раз, начиная с 2018.10.07

SetChannel.jpg 283.8 kb, скачивалось 186 раз, начиная с 2018.10.07

SetDeviceName.png 74.99 kb, скачивалось 209 раз, начиная с 2018.10.07

Переключить тюнер на нужный канал.cfg 3.02 kb, скачивалось 551 раз, начиная с 2018.10.07

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

2

Re: Просмотр потока со спутникового ресивера через HMS

1. Как вариант, можно попробовать следующее.
В программе "Настройки" -> справа снизу кнопка "Обработка", там откроется список обработок.
Нажать "Добавить", выбрать язык внизу "C++Script" и вставить подобный скрипт:

{
  string servicereference = "";
  // Проверяем, это запустили на просмотр ссылку канала с тюнера?
  if (HmsRegExMatch('dm800:8001/(.*)', CurrentMediaItem[mpiFilePath], servicereference)) {
    // Если регулярка сработала, в servicereference у нас появится значение
    HmsDownloadURL('http://dm800/web/zap?sRef='+servicereference); // переключить тюнер на нужный канал
  }
}

Задать название, например, "Переключить тюнер на нужный канал" и сохранить. Теперь есть обработка, которая проверяет текущую ссылку и если она попадает под шаблон, то берёт значение, которое идёт после dm800:8001/ и заносит в переменную. И делается запрос на dm800/web/zap?sRef=...
После чего, нужно в настройках в категории "События" (слева, вторая снизу) в событии "После начала воспроизведения медиа-ресурса" выставить нашу обработку "Переключить тюнер на нужный канал".
Теперь при включении на просмотр, скрипт будет срабатывать и, возможно, делать нужный запрос.

3. Это так сделано специально. Медиа-сервер не знает точно, перестали его качать, на паузу поставили воспроизведение или просто связь прервалась на время. Поэтому транскодирование прекращается, как только сервер получил событие, которое явно говорит о том, что предыдущий поток явно уже никто не берёт.
Также в настройках в категории "Транскодер" есть пункт "Прекращение транскодирования, если временный файл не используется в течение 300 секунд", там можно это время изменить.

Sony Bravia KDL-32CX523

3 (2018.09.29 02:42:15 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

В общем сделал по инструкции.
Не работает.

Попробовал создать папки в разделе интернет телевидение. Там можно подцепить скрипт к каждой папке.
Добавляю скрипт HmsDownloadUrl('http://dm800/web/zap?sRef=1:0:19:4E89:14:70:1680000:0:0:0:'); в каждую папку.
В папке создаю канал.
Когда на сервере хожу по папкам, каналы переключаются. При двойном клике на канал, на компе идёт трансляция через vlc.
Когда на устройстве делаю то же самое, каналы не переключаются.

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

ЗЫ: После попыток посмотреть на устройстве, при входе в папку на сервере, тоже перестало переключаться. При запуске скрипта в редакторе - переключаются.
А нет возможности прицепить скрипты к запуску просмотра канала?

ЗЗЫ: разобрался с разрывами и удержанием потока. Был очень маленький буфер, поставил 50 мбайт и всё стало работать идеально.
Осталось научиться переключать каналы.

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

4

Re: Просмотр потока со спутникового ресивера через HMS

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

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

Попробуйте в скрипт мною предложенный выше добавить строки, с вызовом функции HmsLogMessage(3, '<Текст для отладки>').
Чтобы получился скрипт, примерно следующий, чтобы посмотреть, срабатывает ли и какие значения у него там в это время:

{
  HmsLogMessage(3, 'Событие начала воспроизведения! Имя: '+CurrentMediaItem[mpiTitle]+'  Ссылка: '+CurrentMediaItem[mpiFilePath]);
  string servicereference = "";
  // Проверяем, это запустили на просмотр ссылку канала с тюнера?
  if (HmsRegExMatch('dm800:8001/(.*)', CurrentMediaItem[mpiFilePath], servicereference)) {
    HmsLogMessage(3, 'Gotcha! servicereference: '+servicereference);
    // Если регулярка сработала, в servicereference у нас появится значение
    HmsDownloadURL('http://dm800/web/zap?sRef='+servicereference); // переключить тюнер на нужный канал
  }
}

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

Созданную обработку нужно куда нибудь добавлять?

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

https://hms.lostcut.net/misc.php?action=pun_attachment&amp;item=3303

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

event_perekl_kanal.png 61.99 kb, скачивалось 197 раз, начиная с 2018.09.29

Sony Bravia KDL-32CX523

5

Re: Просмотр потока со спутникового ресивера через HMS

WendyH пишет:

Если бы это была папка "Подкасты", а не "Интернет телевидение"

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

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

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

6

Re: Просмотр потока со спутникового ресивера через HMS

fctsu001 пишет:

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

Добавить ссылку на медиа-ресурс - как и везде, функцией HmsCreateMediaItem:

    THmsScriptMediaItem Item = HmsCreateMediaItem('ссылка', FolderItem.ItemID);
    Item[mpiTitle] = "Название";

Где во втором параметре передаётся ItemID родительской папки.

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

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

https://hms.lostcut.net/misc.php?action=pun_attachment&amp;item=3304

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

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

vars.png 44.78 kb, скачивалось 184 раза, начиная с 2018.09.29

Sony Bravia KDL-32CX523

7

Re: Просмотр потока со спутникового ресивера через HMS

Всё понял, буду пробовать.

Не понял. какую функцию использовать для загрузки url в строку.
Например, в браузере отправляю запрос хттп://dm800/web/getservices, получаю страничку:

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

<e2servicelist>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.tv_channal__tv_.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>TV Channal (TV)</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe00.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>КИНО</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe01.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Ночные каналы</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe02.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Познавательные</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe03.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>HD-каналы</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe04.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Музыка</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe05.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Спорт</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe06.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Разное</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Favourites (TV)</e2servicename>
</e2service>
<e2service>
<e2servicereference>
1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.information__tv_.tv" ORDER BY bouquet
</e2servicereference>
<e2servicename>Information (TV)</e2servicename>
</e2service>
</e2servicelist>

Как я понял, можно использовать string channels_list = HmsDownloadURL('http://dm800/web/getservices', const aHeaders: string = '', aAcceptCompressed: Boolean = False); Не понятен физический смысл 2-х параметров, я так понял, их можно убрать? И функция типа variant - это что за тип? Я в программировании как свинья в апельсинах.
потом строку парсить и создавать папки. Кстати, чем создать папки, чем отличается от канала или это свойство Item?
Примеры (имеющиеся скрипты) все на паскале, я там в синтаксисе путаюсь, неудобно.

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

8

Re: Просмотр потока со спутникового ресивера через HMS

Да, если спец HTTP заголовков не нужно, то последние два параметра в функции HmsDownloadURL можно опустить.
Второй параметр - там можно указать всякие Referer, User-Agent и прочие. Третий параметр, на самом деле, и для меня загадка.

fctsu001 пишет:

И функция типа variant - это что за тип?

Это значит любой тип. Т.е. переменная или параметр может содержать разные типы.
Если такой тип у возвращаемой функции, то нужно тоже проверять или смотреть, какие типы она может возвращать.
У функции HmsDownloadURL, как я понимаю, подразумевается, что возвращаться может string или nil (аналог null, но в паскале это указатель тупо равен числу ноль).
Никогда не встречал, чтобы HmsDownloadURL возвращало что-то, кроме string. Даже при ошибках - пустая строка.
С описанием скриптового языка или встроенных функций - беда, неоткуда почти информацию брать. Так что спрашивайте, по опыту подсказать могу.

fctsu001 пишет:

Кстати, чем создать папки, чем отличается от канала или это свойство Item?

Хоть у переменной Item тип THmsScriptMediaItem - это универсальный класс объекта, элемента базы данных HMS. Этот тип будет и у папки и у ссылки.
Только свойства некоторые будут разные. Например, у папки Item.IsFolder будет true, у ссылки, соответственно, нет.

Но папки создаются действительно по-другому. В отличии от функции HmsCreateMediaItem (которая создаёт именно ссылки, а не папки), для создания папки проще всего использовать функцию AddFolder другой папки (родительской).

Например, много где переменная FolderItem это текущая папка (Хоть подкаст, хоть папка группировки, в которую зашли).
Поэтому создание папки будет выглядеть вот так:

    THmsScriptMediaItem Folder = FolderItem.AddFolder('ссылка', true);
    Folder[mpiTitle] = 'Название папки';

Второй параметр функции AddFolder - указывает, создавать просто папку или подкаст (который является тоже папкой по-сути, но может обновляться в программе).
Если нужно создавать спец папки, такие как динамические или какие-то другие, то нужно указывать третий параметр - класс папки. Но это очень редко пригождается. Обычно третий параметр можно не указывать.

Sony Bravia KDL-32CX523

9

Re: Просмотр потока со спутникового ресивера через HMS

WendyH пишет:

Если нужно создавать спец папки, такие как динамические

Нужно создавать динамические. Более того, нужно создавать и добавлять скрипт создания каналов из списка, полученного по ссылке на пакет из списка пакетов. Т.е. этим и должен заниматься скрипт - создать папку со своими скриптами.

Соответственно интересует свойство структуры типа THmsScriptMediaItem, которое отвечает за скрипт.

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

И ещё вопрос, когда читал инструкцию по настройке контента, видел, что можно взять мышкой *.m3u файл и перетащить в папку "подкасты" или "интернет телевидение", и создастся канал. У меня не создаётся.

С дримбокса по запросу стрима приходит файл с адресом стрима streem.m3u с содержимым:

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

#EXTM3U
#EXTVLCOPT--http-reconnect=true
http://dm800:8001/1:0:16:44E:B:70:1680000:0:0:0:

хочется понять что в нём не нравится HMS и / или какого вида файл должен быть для создания каналов, я бы руками сделал m3u файл в нужном формате, что бы можно было разом все каналы пакета создать путём перетаскивания файла в нужную папку.

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

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

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

10

Re: Просмотр потока со спутникового ресивера через HMS

По поводу перетаскивания m3u8 - должно работать, но я тоже сталкивался, что не перетягивал. Как раз из-за того, что если первый раз этот файл засунешь в "Подкасты", то загружая или перетягивая мышкой этот же файл в папку "Интернет телевидение" он уже там не создаётся.
Такое странное поведение, как будто HMS на основе пути и имени файла генерит ID плейлиста и если он уже в другой папке, то загружать будет именно туда и только.
Т.е. пока из другого места этот плейлист не удалишь, в другую папку он уже его не загрузит.
Можно попробовать переименовать файл и заново попытаться загрузить.

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

Sony Bravia KDL-32CX523

11

Re: Просмотр потока со спутникового ресивера через HMS

Попробуйте сделать вот что.

1) Встать на папку "Интернет телевидение", нажать F2 - откроется окно свойств папки;
2) Ставим тип временно "Динамическая (скрипт)", при этом кнопка редактирования скрипта станет доступна, нажимаем её;
3) В открывшемся редакторе внизу выставляем язык в "C++Script" и вставляем следующий код:

{
  Variant Folder = FolderItem.AddFolder('dm800', false, 32);
  Folder[200] = 1;           // mpiFolderType
  Folder[500] = "{}";        // mpiDynamicScript
  Folder[501] = 'C++Script'; // mpiDynamicSyntaxType
  ShowMessage('Папка создана!');
}

4) Запускаем его клавишей F9 или мышкой, нажав мышкой внизу "Выполнить скрипт".
5) Потом нажимаем "Отмена" и на вопрос о сохранении можно нажать "Нет". Нам не за чем сохранять этот код.
6) Возвращаем тип папки "Интернет телевидение" на "По-умолчанию" и нажимаем "Ок".
Теперь у нас в папке "Интернет телевидение" будет динамическая папка "dm800".
7) Встаём на папку "dm800" и нажимаем кнопку редактирования скрипта. Вставляем туда следующий скрипт:

+ открыть спойлер
{
  string sScript = // Скрипт динамической папки конкретного канала
  '{\r\n'+
  '  string sLink = HmsDownloadURL(mpFilePath); // получаем ссылку на поток\r\n'+
  '  THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  Item[mpiTitle] = mpTitle; // присваиваем название канала как у папки\r\n'+
  '  HmsDownloadURL("http://dm800/web/zap?sRef={ref}"); // переключаем на канал\r\n'+
  '}';
  
  FolderItem.DeleteChildItems();
  
  string xmlText = HmsDownloadURL('http://dm800/web/getallservices'); // Загружаем инфу о всех категориях и каналах

  TXMLDocument XML = TXMLDocument.Create();
  XML.LoadFromString(xmlText);
  
  for (int nCat=0; nCat < XML.Root.Count; nCat++) {
    TXMLItem CATEGORY = XML.Root[nCat];

    TXMLItem ChLIST = CATEGORY.Find('e2servicelist');
    if (ChLIST == nil) continue; // Если категория не содержит каналов, пропускаем

    string sRefCategory = Trim(CATEGORY.ChildValues['e2servicereference']);
    
    THmsScriptMediaItem FolderCat = FolderItem.AddFolder('http://dm800/web/getservices?sRef='+HmsHttpEncode(sRefCategory), false, 32);
    FolderCat[mpiTitle] = CATEGORY.ChildValues['e2servicename'];
    
    // Цикл создания списка каналов в папке категории
    for (int nChan=0; nChan < ChLIST.Count; nChan++) {
      TXMLItem CHANNEL = ChLIST.Items[nChan];
      
      string sRef = Trim(CHANNEL.ChildValues['e2servicereference']);
      
      THmsScriptMediaItem Item = FolderCat.AddFolder('http://dm800/web/stream.m3u?ref='+HmsHttpEncode(sRef), false, 32);
      Item[mpiTitle] = CHANNEL.ChildValues['e2servicename']; // Название канала
      Item[200] = 1;                                  // mpiFolderType 1 - "динамическая (скрипт)"
      Item[500] = ReplaceStr(sScript, '{ref}', sRef); // mpiDynamicScript
      Item[501] = 'C++Script';                        // mpiDynamicSyntaxType
    }
    
  }
  
  XML.Free();
}

и нажимаем "Ок".

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

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

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

Кстати, можно вместо всех предыдущих действий просто загрузить вот этот прикреплённый файл (на папке "Интернет телевидение" правой клавишей мышки и "Загрузить из файла").

P.S.: Такого ресивера у меня нет, делал в "слепую", так что проверяйте, возможно где-то накосячил.
Про /getallservices взял отсюда.

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

dm800.hdf 3.15 kb, скачивалось 519 раз, начиная с 2018.09.29

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

12

Re: Просмотр потока со спутникового ресивера через HMS

WendyH пишет:

По поводу перетаскивания m3u8

У меня m3u, может надо в m3u8 переименовать? Больше интересует плэйлист с несколькими каналами, что бы все каналы из одного плэйлиста загружались.

WendyH пишет:

http://dm800/web/stream.m3u?ref=

Я вообще хотел к папке цеплять скрипт на основе получения списка каналов из пакета:

http://dm800/web/getservices?sRef=1:7:1:0:0:0:0:0:0:0:FROM%20BOUQUET%20%22userbouquet.tv_channal__tv_.tv%22%20ORDER%20BY%20bouquet

Получаем:

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

<e2servicelist>
<e2service>
<e2servicereference>1:0:19:4E89:14:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Первый канал HD</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:19:4E8A:14:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Россия 1 HD</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:841:15:70:1680000:0:0:0:</e2servicereference>
<e2servicename>ТВЦ</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:523:D:70:1680000:0:0:0:</e2servicereference>
<e2servicename>НТВ</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3ED:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Россия К</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:19:89C:16:70:1680000:0:0:0:</e2servicereference>
<e2servicename><n/a></e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:520:D:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Канал Disney</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:451:B:70:1680000:0:0:0:</e2servicereference>
<e2servicename>СТС</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:44E:B:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Домашний</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:19:89F:16:70:1680000:0:0:0:</e2servicereference>
<e2servicename><n/a></e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3F1:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>ПЯТНИЦА</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:455:B:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Че</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3F0:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>ТВ-3</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:528:D:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Ю-ТВ</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3EC:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>РЕН ТВ</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:51F:D:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Звезда</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:524:D:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Телеканал 360</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:835:15:70:1680000:0:0:0:</e2servicereference>
<e2servicename>2X2</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:71C:12:70:1680000:0:0:0:</e2servicereference>
<e2servicename>THT4</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:840:15:70:1680000:0:0:0:</e2servicereference>
<e2servicename>AMC</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:198:4:70:1680000:0:0:0:</e2servicereference>
<e2servicename>НТВ Сериал</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3F2:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>МИР</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:71F:12:70:1680000:0:0:0:</e2servicereference>
<e2servicename>МИР 24</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:19:57F:E:70:1680000:0:0:0:</e2servicereference>
<e2servicename>МИР PREMIUM</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:44D:B:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Первый канал</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3E9:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Россия 1</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:527:D:70:1680000:0:0:0:</e2servicereference>
<e2servicename>ТНТ</e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:1:3F0:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename><n/a></e2servicename>
</e2service>
<e2service>
<e2servicereference>1:0:16:3EB:A:70:1680000:0:0:0:</e2servicereference>
<e2servicename>Пятый канал</e2servicename>
</e2service>
</e2servicelist>

Имеем servicereference для каждого канала и создаём на его основе сразу каналы, т.е. на устройстве зашли в папку пакета (букета) и получили сразу каналы в папке.

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

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

13 (2018.09.29 23:44:33 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

Загрузил из файла, всё сработало, но каналы создаются с таким путём:

#EXTM3U
#EXTVLCOPT--http-reconnect=true
http://dm800:8001/1:0:19:4E8A:14:70:1680000:0:0:0:

Соответственно, не показывает.

THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID);

чем порезать sLink? Можно тупо срезать начало, можно поискать http://
Руками если поправить, то работает. Может поэтому и m3u не вставляется?
И профиль транскодирования надо выбрать при создании, с профилем по умолчанию не работает. Надо "интернет телевидение (входной поток), но на соньке надо другой руками ставить.

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

14

Re: Просмотр потока со спутникового ресивера через HMS

А может вообще, попробовать оставить ссылку такую?

THmsScriptMediaItem Item = HmsCreateMediaItem(mpFilePath, FolderItem.ItemID);
Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования

Т.е. вообще без использования sLink и его получения по ссылке.
Насколько я знаю, VLC прекрасно переваривает полученные m3u8 плейлисты. Т.е. даже ссылки на плейлисты.

Ну или придётся вырезать из sLink нужный участок. Например, вот так:

HmsRegExMatch("^(http.*?)$", sLink, sLink, 1, PCRE_MULTILINE);

Т.е. участок кода может выглядеть так:

  string sScript = // Скрипт динамической папки конкретного канала
  '{\r\n'+
  '  string sLink = HmsDownloadURL(mpFilePath); // получаем ссылку на поток\r\n'+
  '  HmsRegExMatch("^(http.*?)$", sLink, sLink, 1, PCRE_MULTILINE);\r\n'+
  '  THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  Item[mpiTitle] = mpTitle; // присваиваем название канала как у папки\r\n'+
  '  Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования\r\n'+
  '  HmsDownloadURL("http://dm800/web/zap?sRef={ref}"); // переключаем на канал\r\n'+
  '}';
Sony Bravia KDL-32CX523

15

Re: Просмотр потока со спутникового ресивера через HMS

Я поправил скрипт вот так:

  string sScript = // Скрипт динамической папки конкретного канала
  '{\r\n'+
  '  string sLink = "http://dm800:8001/{ref}";\r\n'+
  '  // string sLink = HmsDownloadURL(mpFilePath); // получаем ссылку на поток\r\n'+
  '  THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  Item[mpiTitle] = mpTitle; // присваиваем название канала как у папки\r\n'+
  '  HmsDownloadURL("http://dm800/web/zap?sRef={ref}"); // переключаем на канал\r\n'+
  '}';

Можно и без sLink, обойтись, конечно. Сейчас попробую профиль транскодирования воткнуть.

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

16

Re: Просмотр потока со спутникового ресивера через HMS

WendyH пишет:

Насколько я знаю, VLC прекрасно переваривает полученные m3u8 плейлисты.

Не факт, что HMS передаёт весь m3u, при запуске в информации о транскодировании в пути только первая строка (адреса нет).

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

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

Поскольку на соньке нужен другой профиль, через настройку устройств установил для неё в раздел интернет телевидения профиль ...VLC-FFMPEG, но используется профиль канала. Если очистить профиль канала, почему то берётся профиль Интернет телевидение (ремуксирование), если задать профиль с устройства, то он работает, но для динамических ресурсов это не сильно удобно.

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

17 (2018.10.01 10:57:40 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

Добавил в скорипт:

       if (Trim(CHANNEL.ChildValues['e2servicename']) == '<n/a>') continue;

перед

      string sRef = Trim(CHANNEL.ChildValues['e2servicereference']);

- убрал недоступные сервисы (остаются на ресивере при пересканировании спутника).

Вопросы:

THmsScriptMediaItem Item = FolderCat.AddFolder('http://dm800/web/stream.m3u?ref='+HmsHttpEncode(sRef), false, 32);

Создаёт папку, не понял, что и с какими параметрами вызвать, что бы создать вместо папки канал со ссылкой 'http://dm800:8001/'+sRef.
Пробовал вызвать так:

THmsScriptMediaItem Item = HmsCreateMediaItem('http://dm800:8001/'+sRef);

, ничего не создаётся.

ЗЫ: где найти информацию про объекты? У FolderCat есть свойство AddItem ? Но тут нужна помощь, объектно ориентированное программирование - тёмный лес для меня.

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

18

Re: Просмотр потока со спутникового ресивера через HMS

fctsu001 пишет:

не понял, что и с какими параметрами вызвать, что бы создать вместо папки канал со ссылкой 'http://dm800:8001/'+sRef.
Пробовал вызвать так:

THmsScriptMediaItem Item = HmsCreateMediaItem('http://dm800:8001/'+sRef);

, ничего не создаётся.

Всё правильно, чтобы создать не папку, а ссылку, нужно вызывать HmsCreateMediaItem. Только во втором параметре указать ItemID той папки, в которой она будет создана.
Например:

THmsScriptMediaItem Item = HmsCreateMediaItem('http://dm800:8001/'+sRef, FolderCat.ItemID);

чтобы создать в папке категории. Или:

THmsScriptMediaItem Item = HmsCreateMediaItem('http://dm800:8001/'+sRef, FolderItem.ItemID);

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

fctsu001 пишет:

где найти информацию про объекты? У FolderCat есть свойство AddItem ? Но тут нужна помощь, объектно ориентированное программирование - тёмный лес для меня.

Свойства зависят от того, какого класса объект. FolderCat - класс THmsScriptMediaItem.
Все доступные свойства у класса можно посмотреть в справочнике в редакторе (выдвигается панель справа).
А при использовании дополнения HMSEditor Addon, при наборе в редакторе переменной и нажав точку - вылезет подсказка с доступными методами и свойствами.

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

19 (2018.10.01 13:25:57 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

WendyH пишет:
THmsScriptMediaItem Item = HmsCreateMediaItem('http://dm800:8001/'+sRef, FolderCat.ItemID);

Да, всё сработало, каналы создались, самое приятное - сохраняется порядок сортировки в категории на тюнере.

WendyH пишет:

Все доступные свойства у класса можно посмотреть в справочнике в редакторе (выдвигается панель справа).

Что то я не понял, как, есть только списки переменных и функций, может я не туда смотрю?

WendyH пишет:

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

Я до сих пор не поставил, наверное зря, дома озабочусь, на удалёнке не хочу ставить. Этого мне и не хватало, перебирал разные варианты, пробовал FolderCat.FolderId, при проверке редактор ругался на то, что не нашёл FolderId.

Теперь получился вполне рабочий вариант.

Теперь вопросы:
Можно ли в скрипте обработки, например, по событию, получить список текущих заданий транскодирования?
Как взять из этого списка параметр "Исходный файл" для каждого задания?
Можно ли принудительно завершить задание транскодирования?

Ну и - хочется допилить полученный вариант для общего пользования.
Вы сделали dm800.hdf для конкретного случая. А можно при импорте файла в HMS запросить адрес и имя ресурса?
Я вот думаю, как средствами HMS просканировать сеть на предмет наличия устройств под управлением для начала только Enigma2, ну и создать сразу каналы.

ЗЫ: и как засунуть в .hdf скрипт переключения каналов и повесить его на событие открытия ресурса?

ЗЗЫ:
Вот, что получилось. Переключение каналов на событии.

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

{
//  string sScript = // Скрипт динамической папки конкретного канала
//  '{\r\n'+
//  '  // string sLink = "http://dm800:8001/{ref}";\r\n'+
//  '  // string sLink = HmsDownloadURL(mpFilePath); // получаем ссылку на поток\r\n'+
//  '  // THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID); // Создаём ссылку\r\n'+
//  '  THmsScriptMediaItem Item = HmsCreateMediaItem("http://dm800:8001/{ref}", FolderItem.ItemID); // Создаём ссылку\r\n'+
//  '  Item[mpiTitle] = mpTitle; // присваиваем название канала как у папки\r\n'+
//  '  Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования\r\n'+
//  '  HmsDownloadURL("http://dm800/web/zap?sRef={ref}"); // переключаем на канал\r\n'+
//  '}';
 
  FolderItem.DeleteChildItems();
 
  string DevWebAddress = 'http://dm800';
  string xmlText = HmsDownloadURL(DevWebAddress+'/web/getallservices'); // Загружаем инфу о всех категориях и каналах
  //string xmlText = HmsStringFromFile('D:\\allservices.xml'); // local test

  TXMLDocument XML = TXMLDocument.Create();
  XML.LoadFromString(xmlText);
 
  for (int nCat=0; nCat < XML.Root.Count; nCat++) {
    TXMLItem CATEGORY = XML.Root[nCat];

    TXMLItem ChLIST = CATEGORY.Find('e2servicelist');
    if (ChLIST == nil) continue; // Если категория не содержит каналов, пропускаем

    string sRefCategory = Trim(CATEGORY.ChildValues['e2servicereference']);
   
    THmsScriptMediaItem FolderCat = FolderItem.AddFolder(DevWebAddress+'/web/getservices?sRef='+HmsHttpEncode(sRefCategory), false, 32);
    FolderCat[mpiTitle] = CATEGORY.ChildValues['e2servicename'];
   
    // Цикл создания списка каналов в папке категории
    for (int nChan=0; nChan < ChLIST.Count; nChan++) {
      TXMLItem CHANNEL = ChLIST.Items[nChan];
     
      if (Trim(CHANNEL.ChildValues['e2servicename']) == '<n/a>') continue;
      string sRef = Trim(CHANNEL.ChildValues['e2servicereference']);
     
    //  THmsScriptMediaItem Item = FolderCat.AddFolder(DevWebAddress+'/web/stream.m3u?ref='+HmsHttpEncode(sRef), false, 32); // Добавляем что?
      THmsScriptMediaItem Item = HMSCreateMediaItem(DevWebAddress+':8001/'+sRef, FolderCat.ItemId); // Добавляем ссылку (канал)
    // 
      Item[mpiTitle] = CHANNEL.ChildValues['e2servicename']; // Название канала
      Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования
    //  Item[200] = 1;                                  // mpiFolderType 1 - "динамическая (скрипт)"
    //  Item[500] = ReplaceStr(sScript, '{ref}', sRef); // mpiDynamicScript
    //  Item[501] = 'C++Script';                        // mpiDynamicSyntaxType
    }
   
  }
 
  XML.Free();
}

А к запуску конкретного канала ни как не прикрутить скрипт?

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

20

Re: Просмотр потока со спутникового ресивера через HMS

Переделал обработку по событию "после начала воспроизведения медиа-ресурса"

{
  string DevWebAddress = 'http://dm800';
  string servicereference = '';
  // Проверяем, что это запустили на просмотр ссылку канала с тюнера.
  if (HmsRegExMatch(ReplaceStr(DevWebAddress,'http://','')+':8001/(.*)', CurrentMediaItem[mpiFilePath], servicereference)) {
    // Если регулярка сработала, в servicereference у нас появится значение
    string CurrentService = '';
    HmsRegExMatch('<e2servicereference>(.*)</e2servicereference>', HmsDownloadURL(DevWebAddress + '/web/subservices'), CurrentService, 1, 0);
    if (servicereference == CurrentService) else {
       HmsLogMessage(3, 'Gotcha! : '+CurrentMediaItem[mpiTitle]);
       HmsDownloadURL(DevWebAddress + '/web/zap?sRef='+servicereference); // переключить тюнер на нужный канал
    }
  }
}
BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

21

Re: Просмотр потока со спутникового ресивера через HMS

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

#define DevAddress 'dm800' // Имя устройства в сети или его IP-адрес.
{
  string serviceReference = "";
  // Проверяем, это запустили на просмотр ссылку канала с тюнера?
  if (HmsRegExMatch(DevAddress+':8001/(.*)', CurrentMediaItem[mpiFilePath], serviceReference)) {
    string currentChannel = "";
    string xmlSubservices = HmsDownloadURL('http://'+DevAddress+'/web/subservices');
    HmsRegExMatch('<e2servicereference>(.*?)</e2servicereference>', xmlSubservices, currentChannel);
    // Проверяем и переключаем только если текущий канал не тот, что нужен
    if (serviceReference != currentChannel)
      HmsDownloadURL('http://'+DevAddress+'/web/zap?sRef='+serviceReference); // переключить тюнер на нужный канал
  }
}

Теперь давайте сделаем универсальный dm800.hdf для возможности указать имя девайса.
Предлагаю брать его из поля "Путь" динамической папки.
Т.е. в скрипте это будет переменная mpFilePath.
Покажите, какой у вас сейчас код динамической папки, что именно хочется ещё реализовать и получается ли? Допилим.

Sony Bravia KDL-32CX523

22

Re: Просмотр потока со спутникового ресивера через HMS

fctsu001 пишет:

Теперь вопросы:
Можно ли в скрипте обработки, например, по событию, получить список текущих заданий транскодирования?
Как взять из этого списка параметр "Исходный файл" для каждого задания?
Можно ли принудительно завершить задание транскодирования?

Нет, я такого не знаю. Можно получить список устройств, которая HMS знает. Как медиа-серверы в сети, так и медиа-рендереры (DMR).
Хотя...
Есть идея.
Можно получить список устройств, который HMS знает.
Например, получить список устройств воспроизведения. И по каждому устройству - получить его статус: проигрывает файл, пауза, неактивен.
То, что отображает окно, когда внизу программы на вкладке "Устройства воспроизведения (DMR)" щелкнуть два раза на устройстве - можно посмотреть даже позицию файла, если там запущен просмотр.

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

{
  // Получаем список устройств по указанному типу - MediaRenderer
  THmsScriptUPnPDeviceList DeviceList = THmsScriptUPnPDeviceList.Create(udtDeviceMediaRenderer);
  
  for (int i=0; i < DeviceList.Count; i++) {
    THmsScriptUPnPDevice Device = DeviceList.Items[i];
    string urlDescr = Device.Properties[udpDescriptionURL];
    string img      = Device.Properties[udpDeviceIconURL ];
    string name     = Device.Properties[udpFriendlyName  ];
    string ip       = Device.Properties[udpIpAddress     ];
    string MAC      = Device.Properties[udpMacAddress    ];
    
    HmsLogMessage(1, 'DEVICE: Name='+name+' MAC-адрес: '+MAC+' Страница описания: '+urlDescr);
  }
  DeviceList.Free();
}

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

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

У объекта Device есть ServiceList, но с этим свойством вообще не получилось работать.

Получить сервис в скрипте получилось только через функцию
THmsScriptUPnPService Service = Device.FindService(udtServiceAvTransport);

Но вот использовать внутренние функции по выполнению команд InvokeUPnPAction, InvokeUPnPActionWithResultValues, InvokeUPnPActionWithResponseItem не получилось совсем.
Пришлось вспомнить свои знания по поводу стандарта DLNA и попытаться отправить запрос непосредственно устройству через сеть, с помощью правил SOAP.

В итоге я получил примерно такой код, который выводит информацию о всех устройствах воспроизведения и показывает текущий статус (играет, пауза или нет файла), а также, если есть, информацию о том, какой файл сейчас воспроизводится. Можно достать ещё всякую инфу.

+ открыть спойлер
{
  // Получаем список устройств по указанному типу - MediaRenderer
  THmsScriptUPnPDeviceList DeviceList = THmsScriptUPnPDeviceList.Create(udtDeviceMediaRenderer);
  string text='';
  for (int i=0; i < DeviceList.Count; i++) {
    THmsScriptUPnPDevice Device = DeviceList.Items[i];
    string urlDescr = Device.Properties[udpDescriptionURL];
    string img      = Device.Properties[udpDeviceIconURL ];
    string name     = Device.Properties[udpFriendlyName  ];
    string ip       = Device.Properties[udpIpAddress     ];
    string MAC      = Device.Properties[udpMacAddress    ];

    // Получаем сервис AvTransport (управление устройством)
    THmsScriptUPnPService Service = Device.FindService(udtServiceAvTransport);
    
    string coltrol =  Service.ControlURL;
    string SCP     =  Service.SCPDURL;
    string type    =  Service.ServiceType;

    // Подготовка переменных
    int nPort=80; string sVal, state, headers, data, content, action, file, duration, itemID, path;
    if (HmsRegExMatch(':(\\d+)', Device.HttpServerAddr, sVal)) nPort = StrToInt(sVal);
    // Шаблон HTTP заголовков для стандарта SOAP (DLNA)
    headers = 'http://hms.org\r\nSOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#{action}"';
    
    // Получение текущего статуса устройства (NO_MEDIA_PRESENT|STOPPED|TRANSITIONING|PLAYING|PAUSED_PLAYBACK)
    action  = 'GetTransportInfo';
    content = Service.BuildActionContent(action, ['InstanceID', '0']);
    data = HmsSendRequest(ip, Service.ControlURL, 'POST', 'text/xml; charset="utf-8"', ReplaceStr(headers, '{action}', action), content, nPort);
    HmsRegExMatch('<CurrentTransportState>(.*?)</CurrentTransportState>', data, state);
    
    // Получение информации о текущем медиа
    action  = 'GetMediaInfo';
    content = Service.BuildActionContent(action, ['InstanceID', '0']);
    data = HmsSendRequest(ip, Service.ControlURL, 'POST', 'text/xml; charset="utf-8"', ReplaceStr(headers, '{action}', action), content, nPort);
    data = HmsHtmlToText(HmsUtf8Decode(data));
    HmsRegExMatch('title>(.*?)</'    , data, file);
    HmsRegExMatch('duration="(.*?)"' , data, duration);
    HmsRegExMatch('<item id="(.*?)"' , data, itemID);
    HmsRegExMatch(':video/.*?>(.*?)<', data, path);
    
    text += Format('Name: %s IP: %s\nState: %s\nFile: %s\nDuration: %s\nPath: %s\r\n\r\n', [name, ip, state, file, duration, path]);
  }
  ShowMessage(text); // Выводим сообщение
  DeviceList.Free();
}
Sony Bravia KDL-32CX523
Спасибо сказали: fctsu0011

23 (2018.10.03 18:53:46 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

WendyH: пишет:

Предлагаю брать его из поля "Путь" динамической папки.
Т.е. в скрипте это будет переменная mpFilePath.

Да, надо так и делать, только с путём в папке надо разобраться. ( PS: столкнулся с проблемой - а в обработки по событию откуда брать DevAddress? Мы же по нему определяем, что запущен нужный ресурс? Если меняем адрес в динамической папке, то и в обработке надо менять.)
Как сейчас, не совсем удобно. Я пока не разбирался, что там в сети происходит, но, судя по всему, адрес dm800 получается по WINS (по крайней мере на роутере я статическую запись в DNS не создавал, а в DNS серевера не помню, лет 5 назад настраивал).
По такому адресу обращение к ресурсу происходит чуть медленнее, по IP чуть быстрее. Кроме того, при запуске тестового транскодирования в задании транскодирования в окне CMD vlc не находит путь http://dm800, а по IP находит. Поэтому, лучше, что бы папка называлась именем устройства, а путь был с IP-адресом.
Сейчас в динамической папке путь и название совпадают. Можно в скрипте инициализации сделать resolve по имени и внести в путь IP адрес. ? Можно сделать вычисление IP адреса?

WendyH пишет:
    THmsScriptUPnPDevice Device = DeviceList.Items[i];
    string urlDescr = Device.Properties[udpDescriptionURL];
    string img      = Device.Properties[udpDeviceIconURL ];
    string name     = Device.Properties[udpFriendlyName  ];
    string ip       = Device.Properties[udpIpAddress     ];
    string MAC      = Device.Properties[udpMacAddress    ];

Это я видел, нужен параметр устройства PreTranscodingProfile, сам найти не смог.

WendyH пишет:

Покажите, какой у вас сейчас код динамической папки, что именно хочется ещё реализовать и получается ли?

Текущий скрипт в динамической папке, (скопировал с работающего сервера).

+ открыть спойлер
{
/*  string sScript = // Скрипт динамической папки конкретного канала
  '{\r\n'+
  '  // string sLink = "http://dm800:8001/{ref}";\r\n'+
  '  // string sLink = HmsDownloadURL(mpFilePath); // получаем ссылку на поток\r\n'+
  '  // THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  THmsScriptMediaItem Item = HmsCreateMediaItem("http://dm800:8001/{ref}", FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  Item[mpiTitle] = mpTitle; // присваиваем название канала как у папки\r\n'+
  '  Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования\r\n'+
  '  HmsDownloadURL("http://dm800/web/zap?sRef={ref}"); // переключаем на канал\r\n'+
  '}';
*/  
  FolderItem.DeleteChildItems();
  
  string DevWebAddress = 'http://192.168.34.100';
  string xmlText = HmsDownloadURL(DevWebAddress+'/web/getallservices'); // Загружаем инфу о всех категориях и каналах
  //string xmlText = HmsStringFromFile('D:\\allservices.xml'); // local test

  TXMLDocument XML = TXMLDocument.Create();
  XML.LoadFromString(xmlText);
  
  for (int nCat=0; nCat < XML.Root.Count; nCat++) {
    TXMLItem CATEGORY = XML.Root[nCat];

    TXMLItem ChLIST = CATEGORY.Find('e2servicelist');
    if (ChLIST == nil) continue; // Если категория не содержит каналов, пропускаем
    string sRefCategory = Trim(CATEGORY.ChildValues['e2servicereference']);
    
    THmsScriptMediaItem FolderCat = FolderItem.AddFolder(DevWebAddress+'/web/getservices?sRef='+HmsHttpEncode(sRefCategory), false, 32);
    FolderCat[mpiTitle] = CATEGORY.ChildValues['e2servicename'];
    
    // Цикл создания списка каналов в папке категории
    for (int nChan=0; nChan < ChLIST.Count; nChan++) {
      TXMLItem CHANNEL = ChLIST.Items[nChan];
      
      if (Trim(CHANNEL.ChildValues['e2servicename']) == '<n/a>') continue;
      string sRef = Trim(CHANNEL.ChildValues['e2servicereference']);
      
    //  THmsScriptMediaItem Item = FolderCat.AddFolder(DevWebAddress+'/web/stream.m3u?ref='+HmsHttpEncode(sRef), false, 32); // Добавляем что?
      THmsScriptMediaItem Item = HMSCreateMediaItem(DevWebAddress+':8001/'+sRef, FolderCat.ItemId); // Добавляем ссылку (канал)
    //  
      Item[mpiTitle] = CHANNEL.ChildValues['e2servicename']; // Название канала
    //  Item[mpiTranscodingProfile] = cfgPreTranscodingProfile; // Устанавливаем принудительно профиль транскодирования
      Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования
    //  Item[200] = 1;                                  // mpiFolderType 1 - "динамическая (скрипт)"
    //  Item[500] = ReplaceStr(sScript, '{ref}', sRef); // mpiDynamicScript
    //  Item[501] = 'C++Script';                        // mpiDynamicSyntaxType
    }
    
  }
  
  XML.Free();
}

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

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

24

Re: Просмотр потока со спутникового ресивера через HMS

Я был не прав. Проверил, действительно, ссылки в динамической папке всегда транскодятся с профилем "Фильмы (основной)" и никак настройки устройств на это не влияют. Какой-то недостаток программы. Это косяк.
Что примечательно, если не использовать динамическую папку, то ссылки в папке "Интернет телевидение" начинают транскодироваться с профилем, указанным в настройках устройства.

Поэтому выход один, fctsu001 вы правы, принудительно устанавливать профиль транскодирования в коде.
Осталось определить с какого устройства зашли.
Но и тут облом.
Я так и не смог определить точное название или какие-либо данные устройства программно, точнее связать текущее устройство с тем, что может выдать THmsScriptUPnPDeviceList DeviceList = THmsScriptUPnPDeviceList.Create(udtDeviceMediaRenderer).

Даже не нашёл хоть как можно связать совсем непонятную функцию HmsClientID() хоть с чем-то. Какой-то ид можно получить, но что с ним делать - непонятно.

В итоге, вижу пока только один выход: определить можно косвенно.
Хоть cfgPreTranscodingProfile в динамической папке всегда пустой, но такие переменные как
cfgTranscodingFileFormat - формат файла ("MPEG (DVD)", "MPEGTS"...)
cfgTranscodingVideoMimeType - MIME-тип файлов видео ("video/mpeg", "video/mp4"...)
cfgTranscodingScreenWidth - ширина кадра
cfgTranscodingTvsetFileExt - расширение файлов интернет-телевидения ("mp4", "mpeg")
cfgTranscodingTvsetFileFormat - формат файлов интернет-телевидения ("MPEG (DVD)", "MPEGTS"...)
всё-таки содержат значения из настроек устройства в разделе "Транскодер".

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

  THmsScriptMediaItem Item = HMSCreateMediaItem(DevWebAddress+':8001/'+sRef, FolderCat.ItemId); // Добавляем ссылку (канал)
  Item[mpiTitle] = CHANNEL.ChildValues['e2servicename']; // Название канала
  if (cfgTranscodingTvsetFileFormat =="MPEG (DVD)")
    Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования
  else
    Item[mpiTranscodingProfile] = "Интернет-телевидение"; // Устанавливаем принудительно профиль транскодирования

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

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

25 (2018.10.05 17:40:34 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

Куда делся автор программы? Как я понимаю, он проект закрыл?

Прикрутил вывод в лог cfgTranscodingTvsetFileFormat и cfgTranscodingTvsetFileExt при переключении каналов, но сейчас сонька не доступна. upd: формат файла одинаковый на устройствах, MPEG(DVD) расширение .ts.
В настройках устройства .mpg.
От профиля транскодирования не зависит (тестирую на 2- профилях, ИТ (входной поток) и Фильмы VLC-FFMPEG), профиль меняется исключительно с устройства. Изменение профиля в настройках устройства не помогает.

А исходники не доступны?

Туда же ставил вывод инфо по устройствам - инфо по устройствам выдаётся, но инфа по медиа - не той, что запрашивается, а той, что под текущим указателем в плеере, там список ранее добавленных. upd: информация берётся с плеера, в момент начала воспроизведения нет информации о воспроизводимом ресурсе, поскольку воспрооизведение не началось. Поставил запуск информации об устройствах по кнопке и выяснил это. При воспроизведении формат файла MPEG(DVD), расшитение .ts, но при этом для соньки VLC транскодирует. По большому счёту, совершенно не важно, какое там расширение и контейнер, лишь бы кодек был нужный.

Самое интересное, что при тестовом транскодировании каналы не переключаются, т.е. нет события. Так же, при тестовом транскодировании не применяются профили, установленные с устройства (через DLNA интерфейс).

Залез в скрипт запуска транскодера vlc-ffmpeg и добавил в параметры запуска vlc --ffmpeg-fast --sout-ffmpeg-hurry-up --high-priority --postproc-q=0 к тем, что там уже есть, перестал рваться поток при запуске просмотра на соньке. Изменений в качестве не заметил, но источник был не очень - кино шло.
upd: изменения не сохранились. Ещё раз внёс изменения. Показывает со сменой кадра раз в 2 секунды. Откатил. Не помогло.

Сейчас остался текущий вопрос, как сделать так, что бы в скрипт обработки по событию писался тот же адрес устройства, что и в динамическую папку?
И, можно ли по имени устройства определить его IP, что бы использовать его?

Импортировал moonwalk2, всё работает.
Прикрутил переключение каналов к Запуск_в_VLC

PS прицепил пиконы каналов.
Пытался найти ресурс, с которого можно скачать отдельно каждый, но не нашёл, нашёл только архивы с пиконами.
Пиконы в виде файлов вида: 1_0_19_4E89_14_70_1680000_0_0_0.png

        Item[Thumbnail] = 'H:\\Media\\Workdata\\Setup\\HomeServerDLNA\\picons\\36E_220 х132_0\\' + LeftCopy(ReplaceStr( sRef,':','_'),Length(sRef)-1)+'.png';

Ещё один предмет для размышления, организовать стандартный путь до пиконов, или сделать возможность ввести его при импорте?

Варианты:

  • хранить пиконы по пути каталогов исполняемого файла. Минус - нет доступа пользователя.
    хранить путь др пиконов в реестре windows, искал раздел HMS - не нашёл, создавать?
    хранить в AppData ("%localappdata%\home media server\hms\thumbnails"), но тогда их нужно туда импортировать как то.

Есть ещё варианты?
upd: решил хранить в AppData

Пока получилось так:

+ открыть спойлер
#define DevAddresFile '\\Home Media Server\\HMS\\ReceiverNetName.conf'
#define TumbnailsStorePath '\\Home Media Server\\HMS\\Thumbnails\\'
{
  /*  string sScript = // Скрипт динамической папки конкретного канала
  '{\r\n'+
  '  // string sLink = "http://dm800:8001/{ref}";\r\n'+
  '  // string sLink = HmsDownloadURL(mpFilePath); // получаем ссылку на поток\r\n'+
  '  // THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  THmsScriptMediaItem Item = HmsCreateMediaItem("http://dm800:8001/{ref}", FolderItem.ItemID); // Создаём ссылку\r\n'+
  '  Item[mpiTitle] = mpTitle; // присваиваем название канала как у папки\r\n'+
  '  Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования\r\n'+
  '  HmsDownloadURL("http://dm800/web/zap?sRef={ref}"); // переключаем на канал\r\n'+
  '}';
  */  
  
  FolderItem.DeleteChildItems();
  string DevAddress  = HmsStringFromFile(SpecialFolderPath(0x1C) + DevAddresFile); //0x1C (CSIDL_LOCAL_APPDATA) - локальная папка данных 
  if(DevAddress != '') {
  CurrentMediaItem[mpiFilePath] = DevAddress;
  
  string xmlText = HmsDownloadURL('http://' + DevAddress + '/web/getallservices'); // Загружаем инфу о всех категориях и каналах
  //string xmlText = HmsStringFromFile('D:\\allservices.xml'); // local test
  
  TXMLDocument XML = TXMLDocument.Create();
  XML.LoadFromString(xmlText);
  
  for (int nCat=0; nCat < XML.Root.Count; nCat++) {
    TXMLItem CATEGORY = XML.Root[nCat];
    
    TXMLItem ChLIST = CATEGORY.Find('e2servicelist');
    if (ChLIST == nil) continue; // Если категория не содержит каналов, пропускаем
      string sRefCategory = Trim(CATEGORY.ChildValues['e2servicereference']);
    
    THmsScriptMediaItem FolderCat = FolderItem.AddFolder('http://' + DevAddress + '/web/getservices?sRef='+HmsHttpEncode(sRefCategory), false, 32);
    FolderCat[mpiTitle] = CATEGORY.ChildValues['e2servicename'];
    
    // Цикл создания списка каналов в папке категории
    for (int nChan=0; nChan < ChLIST.Count; nChan++) {
      TXMLItem CHANNEL = ChLIST.Items[nChan];
      
      if (Trim(CHANNEL.ChildValues['e2servicename']) == '<n/a>') continue;
      string sRef = Trim(CHANNEL.ChildValues['e2servicereference']);
      
      //  THmsScriptMediaItem Item = FolderCat.AddFolder('http://' + DevAddress + '/web/stream.m3u?ref='+HmsHttpEncode(sRef), false, 32); // Добавляем что?
      THmsScriptMediaItem Item = HMSCreateMediaItem('http://' + DevAddress + ':8001/'+sRef, FolderCat.ItemId); // Добавляем ссылку (канал)
      //  
      Item[mpiTitle] = CHANNEL.ChildValues['e2servicename']; // Название канала
      //  Item.ThumbnailExists= true;
      Item[mpiThumbnail] = SpecialFolderPath(0x1C) + TumbnailsStorePath + LeftCopy(ReplaceStr( sRef,':','_'),Length(sRef)-1)+'.png';
      
    //  Item[mpiTranscodingProfile] = cfgPreTranscodingProfile; // Устанавливаем принудительно профиль транскодирования
      Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Устанавливаем принудительно профиль транскодирования
    //  Item[200] = 1;                                  // mpiFolderType 1 - "динамическая (скрипт)"
    //  Item[500] = ReplaceStr(sScript, '{ref}', sRef); // mpiDynamicScript
    //  Item[501] = 'C++Script';                        // mpiDynamicSyntaxType
    }
    
  }
  
  XML.Free();
  }
}

Обработка на запуск воспроизведения:

+ открыть спойлер
#define DevAddresFile '\\Home Media Server\\HMS\\ReceiverNetName.conf'
{
  string DevAddress  = HmsStringFromFile(SpecialFolderPath(0x1C) + DevAddresFile); //0x1C (CSIDL_LOCAL_APPDATA) - локальная папка данных 
  if(DevAddress != '') {
    string serviceReference = "";
    // Проверяем, это запустили на просмотр ссылку канала с тюнера?
    if (HmsRegExMatch(DevAddress+':8001/(.*)', CurrentMediaItem[mpiFilePath], serviceReference)) {
      string currentChannel = "";
      string xmlSubservices = HmsDownloadURL('http://'+DevAddress+'/web/subservices');
      HmsRegExMatch('<e2servicereference>(.*?)</e2servicereference>', xmlSubservices, currentChannel);
      // Проверяем и переключаем только если текущий канал не тот, что нужен
      if (serviceReference != currentChannel) {
        HmsLogMessage(3, 'Gotcha! : '+CurrentMediaItem[mpiTitle] + ' |' + cfgTranscodingTvsetFileFormat + '.' + cfgTranscodingTvsetFileExt);
        HmsDownloadURL('http://'+DevAddress+'/web/zap?sRef='+serviceReference); // переключить тюнер на нужный канал
      }  
    }
  }
}

Есть предложение привести все имена переменных и констант к "принятому" виду, ну и текст тоже.
Осталось придумать что то с установкой профиля транскодирования для конкретного устройства.
С учётом того, что все современные устройства могут переваривать спутниковый поток без транскодирования, некая универсальность остаётся. Для устройств, которые это не могут, пока один выход - устанавливать профиль транскодирования руками для каждого ресурса.
Кстати, в интерфейсе HMS можно установить профиль на всю папку, а можно ли сделать так с устройства?

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s

26 (2018.10.05 20:51:35 отредактировано WendyH)

Re: Просмотр потока со спутникового ресивера через HMS

fctsu001 пишет:

Куда делся автор программы? Как я понимаю, он проект закрыл?

Неизвестно.

fctsu001 пишет:

А исходники не доступны?

Нет. Это бесплатная версия для стран СНГ, для запада у него платная http://www.wildmediaserver.com.
Та версия обновлялась в этом году (в отличии от HMS). Пусть нумерация версий не смущает, она всегда была разной (там и тут).

fctsu001 пишет:

Сейчас остался текущий вопрос, как сделать так, что бы в скрипт обработки по событию писался тот же адрес устройства, что и в динамическую папку?

Только в самом скрипте обработки каким-то образом определять, что это обрабатывается ссылка, относящаяся к нашему устройству (ресиверу) - и из этой ссылки брать сохранённое значение адреса или имени устройства. Дополнительные значения можно сохранять в поля свойств при создании ссылки.

  THmsScriptMediaItem Item = HMSCreateMediaItem(DevWebAddress+':8001/'+sRef, FolderCat.ItemId); // Добавляем ссылку (канал)
  Item[mpiTitle] = CHANNEL.ChildValues['e2servicename']; // Название канала
  Item[12345] = 'DreamBox'; // magic word

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

{
  // Проверяем, это запустили на просмотр ссылку канала с тюнера?
  if (CurrentMediaItem[12345]=='DreamBox') {
    string ref     = "";
    string devAddr = "";
    // Получаем значения адреса (или имени) устройства и serviceReference
    HmsRegExMatch2('http://(.*?):?\\d*/(.*)', CurrentMediaItem[mpiFilePath], devAddr, ref);
    string currentChannel = "";
    string xmlSubservices = HmsDownloadURL('http://'+devAddr+'/web/subservices');
    HmsRegExMatch('<e2servicereference>(.*?)</e2servicereference>', xmlSubservices, currentChannel);
    // Проверяем и переключаем только если текущий канал не тот, что нужен
    if (ref != currentChannel)
      HmsDownloadURL('http://'+devAddr+'/web/zap?sRef='+ref); // переключить тюнер на нужный канал
  }
}

Там в регулярке, порт после двоеточия заменил на \d* - это значит любые цифры. Т.е. любой порт.

fctsu001 пишет:

И, можно ли по имени устройства определить его IP, что бы использовать его?

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

fctsu001 пишет:

Ещё один предмет для размышления, организовать стандартный путь до пиконов, или сделать возможность ввести его при импорте?

Забудьте про возможность ввести при импорте. Это невозможно, точнее программа не умеет спрашивать.

fctsu001 пишет:

Варианты:

  • хранить пиконы по пути каталогов исполняемого файла. Минус - нет доступа пользователя.
    хранить путь др пиконов в реестре windows, искал раздел HMS - не нашёл, создавать?
    хранить в AppData ("%localappdata%\home media server\hms\thumbnails"), но тогда их нужно туда импортировать как то.

Есть ещё варианты?
upd: решил хранить в AppData

Мне трудно давать советы по пиконам, не имея устройства, чтобы экспериментировать. Я бы просто комментарий динамической папки вставил ключи, типа:
--piconsPath="%localappdata%\picons"
с возможностью указать там любой путь, кому какой вздумается.
А в коде папки брать это значение из переменной mpComment:

  piconsPath = "";
  HmsRegExMatch('--piconsPath="(.*?)"', mpComment, piconsPath);
fctsu001 пишет:

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

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

  HmsLogMessage(3, mpTitle+': cfgTranscodingTvsetFileFormat='+cfgTranscodingTvsetFileFormat);
  HmsLogMessage(3, mpTitle+': cfgTranscodingTvsetMimeType='+cfgTranscodingTvsetMimeType);

При этом заранее изменив для устройства "Anroid, UPnP/1.1, MiniUPnPc/2.0" в настройках расширение и MIME-тип для Интернет-ТВ. Чтобы посмотреть и убедится, что заходя с телефона (VLC for Android) увидеть, будут ли значения из настроек устройства.
И видел, что они были именно другие. Т.е. те, которые я установил. Теперь можно было в коде сделать проверку и принудительно установить своеобразный профиль для создаваемых ссылок.
Потом не знаю что сделал и опять у меня эти значения потом содержали всё те же значения по-умолчанию.
Хотя вот сейчас опять проверил - получилось. Т.е. профиль транскодирования устанавливается разный для разных устройств.
Вот такой скрипт сейчас примерно сделал:

+ открыть спойлер
{
  string piconsPath = ""; // Путь к пиконам
  string devAddr    = ""; // Имя или IP адрес устройства
  string tvFileExt  = ""; // Расширение файла в разделе "Интернет-ТВ" в настройках устройства (для телевизоров Sony)
  
  // Получаем значения настроек из ключей в комментарии
  HmsRegExMatch('--piconsPath="(.*?)"', mpComment, piconsPath);
  HmsRegExMatch('--deviceAddr="(.*?)"', mpComment, devAddr   );
  HmsRegExMatch( '--tvFileExt="(.*?)"', mpComment, tvFileExt );
  
  HmsLogMessage(3, mpTitle+': cfgTranscodingTvsetFileExt=' +cfgTranscodingTvsetFileExt ); // debug
  HmsLogMessage(3, mpTitle+': cfgTranscodingTvsetMimeType='+cfgTranscodingTvsetMimeType);

  FolderItem.DeleteChildItems();
  
  string xmlText = HmsDownloadURL('http://' + devAddr + '/web/getallservices'); // Загружаем инфу о всех категориях и каналах
  //string xmlText = HmsStringFromFile('D:\\allservices.xml'); // local test
  
  TXMLDocument XML = TXMLDocument.Create();
  XML.LoadFromString(xmlText);
  
  for (int nCat=0; nCat < XML.Root.Count; nCat++) {
    TXMLItem CATEGORY = XML.Root[nCat];
    
    TXMLItem ChLIST = CATEGORY.Find('e2servicelist');
    if (ChLIST == nil) continue; // Если категория не содержит каналов, пропускаем
    
    string refCategory = Trim(CATEGORY.ChildValues['e2servicereference']);
    
    THmsScriptMediaItem FolderCat = FolderItem.AddFolder('http://' + devAddr + '/web/getservices?sRef='+HmsHttpEncode(refCategory), false, 32);
    FolderCat[mpiTitle] = CATEGORY.ChildValues['e2servicename'];
    
    // Цикл создания списка каналов в папке категории
    for (int nChan=0; nChan < ChLIST.Count; nChan++) {
      TXMLItem CHANNEL = ChLIST.Items[nChan];
      
      if (Trim(CHANNEL.ChildValues['e2servicename']) == '<n/a>') continue;
      string ref = Trim(CHANNEL.ChildValues['e2servicereference']);
      
      THmsScriptMediaItem Item = HMSCreateMediaItem('http://' + devAddr + ':8001/'+ref, FolderCat.ItemId); // Добавляем ссылку (канал)
      Item[mpiTitle    ] = CHANNEL.ChildValues['e2servicename']; // Название канала
      Item[mpiThumbnail] = piconsPath + LeftCopy(ReplaceStr(ref,':','_'),Length(ref)-1)+'.png';
      Item[12345       ] = 'DreamBox';
      // Устанавливаем принудительно профиль транскодирования
      if (cfgTranscodingTvsetFileFormat == tvFileExt) 
        Item[mpiTranscodingProfile] = "Интернет-телевидение";                 // для телевизоров Sony
      else
        Item[mpiTranscodingProfile] = "Интернет-телевидение (Входной поток)"; // Для всех остальных
    }
    
  }
  XML.Free();
}

Ври этом в комментарии папки такая строка: --piconsPath="%localappdata%\picons" --deviceAddr="DM800" --tvFileExt="ts"
Код обработки события я приводил выше для такого варианта.

fctsu001 пишет:

Кстати, в интерфейсе HMS можно установить профиль на всю папку, а можно ли сделать так с устройства?

Нет.

P.S. Отредактировал скрипт. Там закралась ошибка. Вместо cfgTranscodingTvsetFileFormat нужно использовать cfgTranscodingTvsetFileExt (если мы говорим про расширение файлов типа ts, mpg или avi. А если как было, то нужно проверять на "MPEG (DVD)", "MPEGTS".
Поправил.

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

dm800 test.hdf 4.15 kb, скачивалось 513 раз, начиная с 2018.10.05

Переключить тюнер на нужный канал.cfg 2.81 kb, скачивалось 523 раза, начиная с 2018.10.05

Sony Bravia KDL-32CX523

27 (2018.10.09 10:24:52 отредактировано fctsu001)

Re: Просмотр потока со спутникового ресивера через HMS

Ещё одна хотелка нарисовалась. При обновлении содержимого пользовательских пакетов на ресивере, содержимое в HMS не обновляется. Можно руками выполнить скрипт на сервере, тогда всё содержимое удаляется и устройства запрашивают обновление заново. А можно приделать "кнопку" обновить с устройства, что бы по запросу выполнялся скрипт основной папки?

BRAVIA KDL-40EX700, webos@LG-42LF650V, WDTVLive, Enigma@DM800, Enigma@GI-S8120, Android@LT-43T600F, Philps 46pdl8908s