1

Тема: DLNA-будильник

Здравствуйте! Прошу прощения если написал не в эту тему!
На официальном форуме есть следующий скрипт для запуска на телеке по расписанию медиа-ресурса

var
  MediaItem: THmsScriptMediaItem;
begin
  MediaItem := HmsFindMediaFolder(mfAudioInternetRadioItemID, 'Electronica\SkyHits Radio');
  if (MediaItem <> nil) and MediaItem.HasChildItems then
    HmsPlayToDevice(MediaItem.ChildItems[0], 'Название, IP-адрес или MAC-адрес устройства воспроизведения') 
end.

Я его подредактировал по себя что-бы запускал коллекцию видео

var
MediaItem: THmsScriptMediaItem;
begin
MediaItem := HmsFindMediaFolder(mfVideoCollectionsItemID, 'DNA');
if (MediaItem <> nil) and MediaItem.HasChildItems then
HmsPlayToDevice(MediaItem.ChildItems[0], '192.168.21.35')
end.

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

2

Re: DLNA-будильник

В окне редактирования скрипта можете нажать F8 и по шагам выполнять программу. Остановившись после

MediaItem := HmsFindMediaFolder(mfVideoCollectionsItemID, 'DNA');

скопировать и нажав Ctrl+F7 вставить в выражение название переменной - MediaItem. Посмотрите, значение должно быть отлично от нуля. Если оно равно 0, то значит он не нашёл папку со значением пути "DNA" в папке "Коллекции"  (mfVideoCollectionsItemID).
Обратите внимание, что DNA - это должно быть не название (хотя и может быть им тоже), а значение поля "Путь".
Проверил у себя сейчас, только не запуск видео из коллекции, а запуск видео из папки в подкасте "Youtube & Vimeo" (предварительно задав в поле "Путь" папок значения "YoutubeAndVimeo" и в нём папки с названием "КВН 2015" - "kvn", а также обновив подкаст, чтобы в папке "квн" были ссылки на видео).

  MediaItem := HmsFindMediaFolder(mfVideoItemsFolderID, 'Podcasts\YoutubeAndVimeo\kvn');
  if (MediaItem <> nil) and MediaItem.HasChildItems then
    HmsPlayToDevice(MediaItem.ChildItems[0], '192.168.1.20')

Запустил на телеке первый файл в коллекции.

А скрипт где вводили, в списке обработок? И как запускали?

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

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

3

Re: DLNA-будильник

Большое человеческое спасибо, действительно не указал поле "путь". После указания все заработало.
Единственное мне нужно, что бы воспроизведение на устройстве останавливалось в 2 часа дня, а затем и сам сервер останавливался и в 9 утра запускался. Попробовал это сделать через службы windows, но тогда при запуске службы не появляется устройство drm в списке. А как это реализовать обработкой ума не приложу?

4

Re: DLNA-будильник

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

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

5

Re: DLNA-будильник

Функции останова устройства и сервера не нашёл.
Есть мысль как остановить устройство: сделать короткое видео-заглушку. Которое бы просто показывала надпись, типа "Конец". И сделать в 2 часа дня ещё один запуск скрипта по расписанию, который бы запускал это видео-заглушку функцией HmsPlayToDevice, только с третьим параметром false (чтобы в плейлист не добавлял).

HmsPlayToDevice(MediaItem.ChildItems[0], '192.168.21.35', false)

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

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

Sony Bravia KDL-32CX523

6

Re: DLNA-будильник

Спасибо! Отличный вариант! В добавок сделал батник

taskkill /f /im hms.exe

и поставил его в планировщик.
Дезактивировал HMS как службу windows и поставил галку что бы запускался сервер вместе с программой, ну и добавил в планировщик на запуск.

7

Re: DLNA-будильник

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

var
  MediaItem: THmsScriptMediaItem;
begin
   MediaItem := HmsFindMediaFolder(mfVideoInternetTelevisionItemID, 'RTMP_server');
  if (MediaItem <> nil)  then
    HmsPlayToDevice(MediaItem, '192.168.1.107')  
end.

Скрипт работает, в "Устойство воспроизведения->Управление" виден текущий статус PLAYING.
Вопрос такой, можно ли модернизировать скрипт так , что бы он исполнялся только в случае, если статус другой (not PLAYING)
Тогда можно в расписании выставить правило на исполнение, скажем, раз в минуту, и получим автоматическое пере подключение к телевизору.
Может быть есть другое решение?
Спасибо.

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

hms.png 74.25 kb, скачивалось 306 раз, начиная с 2016.06.24

8

Re: DLNA-будильник

samvol79 пишет:

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

Решил попробовать и пришлось спуститься до уровня общения с устройством на их языке.

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

+ Воспроизведение на телеке с проверкой его статуса - PascalScript
///////////////////////////////////////////////////////////////////////////////
// Отправка AVTransport команды устройству
Function AVTransport(sServerAddr, sServiceType, sControlUrl, sCmd: String): String;
Var
  nPort: Integer = 80; sData, sVal, sHeaders, sPayload, sRetHeaders: String;
Begin
  If (HmsRegExMatch2('^(.*?):(\d+)', sServerAddr, sServerAddr, sVal)) Then
    nPort := StrToInt(sVal);
  
  sHeaders := '/\r\nUser-Agent: SEC_HHP_Flipps/1.0'#10#13+
              Format('SOAPACTION: "%s#%s"', [sServiceType, sCmd]);
  
  sPayload := '<?xml version="1.0" encoding="utf-8"?>'#10#13+
              '<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'#10#13+
              '  <s:Body>'#10#13+
              '      <u:' + sCmd + ' xmlns:u="' + sServiceType + '">'#10#13+
              '         <InstanceID>0</InstanceID>'#10#13+
              '      </u:' + sCmd + '>'#10#13+
              '   </s:Body>'#10#13+
              '</s:Envelope>';
  sData := HmsSendRequestEx(sServerAddr, sControlUrl, 'POST', 'text/xml; charset="utf-8"', 
                            sHeaders, sPayload, nPort, 0, sRetHeaders, true);
  Result := sRetHeaders + sData;
End;

///////////////////////////////////////////////////////////////////////////////
// Получение статуса устройства по его IP
Function GetDeviceStatus(sIP: String): String;
Var
  sStatus, sDMRurl, sData, sServiceType, sCtlUrl: String;
  DEVLIST: THmsScriptUPnPDeviceList; DEVICE: THmsScriptUPnPDevice;
  i, n: Integer;
Begin
  sStatus := 'UNKNOWN';
  DEVLIST := THmsScriptUPnPDeviceList.Create;
  Try
    For i := 0 To DEVLIST.Count-1 Do Begin
      DEVICE := DEVLIST[0];
      If (DEVICE.IpAddress <> sIP) Then Continue;
      sDMRurl := DEVICE.Properties[1];
      sData   := HmsRemoveLineBreaks(HmsDownloadURL(sDMRurl));
      HmsRegExMatch2('<serviceType>([^<]+AVTransport.*?)</serviceType>.*?<controlURL>(.*?)</controlURL>', sData, sServiceType, sCtlUrl);
      
      sData := AVTransport(DEVICE.HttpServerAddr, sServiceType, sCtlUrl, 'GetTransportInfo');
      HmsRegExMatch('<CurrentTransportState>(.*?)</CurrentTransportState>', sData, sStatus);
      break;
    End;
    
  Finally
    DEVLIST.Free;
  End;
  //Status - STOPPED|PAUSED_PLAYBACK|PAUSED_RECORDING|PLAYING|RECORDING|TRANSITIONING|NO_MEDIA_PRESENT
  Result := sStatus;
End;

///////////////////////////////////////////////////////////////////////////////
// Запуск воспроизведения, если статус устройства не 'PLAYING'
Procedure PlayIfNotPlaying(sDeviceIP, sFolderID, sFilePath: String);
Var
  Status: String; MediaItem: THmsScriptMediaItem;
Begin
  Status := GetDeviceStatus(sDeviceIP);
  If Status = 'PLAYING' Then Exit;
  
  MediaItem := HmsFindMediaFolder(sFolderID, sFilePath);
  If MediaItem <> nil Then
    HmsPlayToDevice(MediaItem, sDeviceIP)
  Else
    HmsLogMessage(2, "Не найден элемент базы данных, который нужно воспроизвести.");
End;

///////////////////////////////////////////////////////////////////////////////
//                     Г Л А В Н А Я   П Р О Ц Е Д У Р А                     //
///////////////////////////////////////////////////////////////////////////////
Begin

  PlayIfNotPlaying('192.168.1.107', mfVideoInternetTelevisionItemID, 'RTMP_server');  
  
End.
+ Воспроизведение на телеке с проверкой его статуса - С++Script
///////////////////////////////////////////////////////////////////////////////
// Отправка AVTransport команды устройству
string AVTransport(string sServerAddr, string sServiceType, string sControlUrl, string sCmd) {
  int nPort = 80; string sData, sVal, sHeaders, sPayload, sRetHeaders;
  
  if (HmsRegExMatch2('^(.*?):(\\d+)', sServerAddr, sServerAddr, sVal)) 
    nPort = StrToInt(sVal);
  
  sHeaders = '/\r\nUser-Agent: SEC_HHP_Flipps/1.0\r\n'+
             Format('SOAPACTION: "%s#%s"', [sServiceType, sCmd]);
  
  sPayload = '<?xml version="1.0" encoding="utf-8"?>\r\n'+
             '<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">\r\n'+
             '  <s:Body>\r\n'+
             '      <u:' + sCmd + ' xmlns:u="' + sServiceType + '">\r\n'+
             '         <InstanceID>0</InstanceID>\r\n'+
             '      </u:' + sCmd + '>\r\n'+
             '   </s:Body>\r\n'+
             '</s:Envelope>\r\n';
  sData = HmsSendRequestEx(sServerAddr, sControlUrl, 'POST', 'text/xml; charset="utf-8"', 
                           sHeaders, sPayload, nPort, 0, sRetHeaders, true);
  return sRetHeaders + sData;
}

///////////////////////////////////////////////////////////////////////////////
// Получение статуса устройства по его IP
string GetDeviceStatus(string sIP) {
  string sStatus, sDMRurl, sData, sServiceType, sCtlUrl;
  THmsScriptUPnPDeviceList DEVLIST; THmsScriptUPnPDevice DEVICE;
  int i, n;
  sStatus = 'UNKNOWN';
  DEVLIST = THmsScriptUPnPDeviceList.Create();
  try {
    for (i=0; i < DEVLIST.Count; i++) {
      DEVICE = DEVLIST[0];
      if (DEVICE.IpAddress != sIP) continue;
      sDMRurl = DEVICE.Properties[1];
      sData   = HmsRemoveLineBreaks(HmsDownloadURL(sDMRurl));
      HmsRegExMatch2('<serviceType>([^<]+AVTransport.*?)</serviceType>.*?<controlURL>(.*?)</controlURL>', sData, sServiceType, sCtlUrl);
      
      sData = AVTransport(DEVICE.HttpServerAddr, sServiceType, sCtlUrl, 'GetTransportInfo');
      HmsRegExMatch('<CurrentTransportState>(.*?)</CurrentTransportState>', sData, sStatus);
      break;
    }
    
  } finally { DEVLIST.Free; }
  //Status - STOPPED|PAUSED_PLAYBACK|PAUSED_RECORDING|PLAYING|RECORDING|TRANSITIONING|NO_MEDIA_PRESENT
  return sStatus;
}

///////////////////////////////////////////////////////////////////////////////
// Запуск воспроизведения, если статус устройства не 'PLAYING'
void PlayIfNotPlaying(string sDeviceIP, string sFolderID, string sFilePath) {
  string status; THmsScriptMediaItem MediaItem;
  
  status = GetDeviceStatus(sDeviceIP);
  if (status == 'PLAYING') exit;

  MediaItem = HmsFindMediaFolder(sFolderID, sFilePath);
  if (MediaItem != nil)
    HmsPlayToDevice(MediaItem, sDeviceIP);
  else
    HmsLogMessage(2, "Не найден элемент базы данных, который нужно воспроизвести.");
}

///////////////////////////////////////////////////////////////////////////////
//                     Г Л А В Н А Я   П Р О Ц Е Д У Р А                     //
///////////////////////////////////////////////////////////////////////////////
{
  
  PlayIfNotPlaying('192.168.1.107', mfVideoInternetTelevisionItemID, 'RTMP_server');  
  
}

Проверьте.

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

9

Re: DLNA-будильник

Большое спасибо за помощь.  Надо сегодня протестировать. Отпишусь.

10

Re: DLNA-будильник

Удалось протестировать скрипт. На самсунге 2012 года, дома,  работает  отлично. На работе,  Шарп 2015 года, тупит.
Картина следующая. При первом запуске
NO_MEDIA_PRESENT->TRANSCODING->PLAYING - начинается воспроизведение.
При следующем запуске скрипта сразу выводит статус  STOPPED.
Последующее исполнение  - снова проигрывает.
Похоже при передаче POST что-то его останавливает.  Может быть для Sharp  есть особенность в установках ?.  Кстати, HMS автоматически присваивает телеку профиль DLNA Toshiba . Буду копать дальше.
Еще  раз спасибо за помощь.