Навигация по аудио и видеофайлам сетевого накопителя Synology для системы управления Crestron

В одном из предыдущих постов я написал, что существует возможность обойти ограничение API медиаплеера Dune HD TV-101 по навигации по папкам с файлами пользователя. Собственно способ позволяет использовать навигацию не привлекая самого медиаплеера. Дело в том, что практически любой сетевой накопитель имеет встроенный веб-сервер и интерпретатор языка PHP. Так почему бы не написать скрипт, который позволит контроллеру напрямую получать информацию о структуре папок и файлов прямо с сетевого накопителя?

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

  1. Создать сетевую папку Web.
  2. Включить службу Web Station.
  3. Зайти в настройки PHP, включить возможность настроить переменную open_basedir.
  4. Добавить  в open_basedir запись вида /volume1 (записи разделяются двоеточием, данная запись разрешает скриптам PHP чтение файлов из всех пользовательских папок в первом разделе).
  5. Разместить скрипт  в папке Web и проверить результат работы, набрав в адресной строке браузера, например, такой запрос: http://ds212j/nas_navigation_simple.php?dir=Video/ (предполагается, что у вас уже есть сетевая папка Video).

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

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

<?php

  // выбираем разделитель: если запрос от контроллера, то разделителем
  // будет "\r\n" а если от браузера, то "<br>"
  if($_SERVER["HTTP_USER_AGENT"]=="Crestron") $delimiter="\r\n";
    else $delimiter="<br>";

  // если в запросе указана новая папка, исследуем ее, иначе папку "Video/"
  if(isset($_GET["dir"])) $dir=$_GET["dir"];
  if(!isset($dir)) $dir="Video/";

  // защищаемся от возможности указать неправильный путь
  // ограничиваемся папками Music и Video
  if(!preg_match('/^(Music|Video)\/(\w+\/)*$/', $dir))
  {
    echo "Error: wrong directory", $delimiter;
    exit();
  }

  // создаем  полный путь в кодировке utf-8
  $basedir="/volume1/".$dir;
  $basedir=iconv("cp1251", "utf-8", $basedir);

  // создаем 2 массива - для списка папок и для списка файлов
  $folders=array();
  $files=array();

  // открываем папку
  $handle = opendir($basedir);

  // проходим по всем вложенным элементам выбранной папки
  while(false!==($entry=readdir($handle)))
  {
    // игнорируем ненужные элементы
    if($entry==".") continue;
    if($entry=="..") continue;
    if(strpos($entry, "@eaDir")!==false) continue;
    if(strpos($entry, ".event")!== false) continue;
    if(strpos($entry, "Thumbs.db")!== false) continue;

    // добавляем папки и файлы в соответствующие массивы
    if(is_dir($basedir.$entry)) array_push($folders, iconv("utf-8", "cp1251", $entry."/"));
      else array_push($files, iconv("utf-8", "cp1251", $entry));
  }

  // закрываем папку
  closedir($handle);

  // сортируем файлы и папки
  sort($folders);
  sort($files);

  // объединяем их в общий список и отдаем контроллеру / браузеру
  $list=array_merge($folders, $files);
  echo implode($list, $delimiter);

?>


  1. Александр

    со скриптами плохо дружу, у меня в настройках open_basedir написано следующее. что сюда нужно дописать, чтобы выполнить пункт 4?
    /etc.defaults:/usr/bin/php:/usr/syno/synoman:/etc:/var/run:/tmp:/var/spool/php:/volume1/@tmp/php:/var/services/web:/var/services/photo:/var/services/blog:/var/services/homes

    спасибо!

    • Эльдар Аблаев

      В настройке open_basedir прописаны все папки, из которых скрипты PHP имеют право читать файлы. Записи разделены двоеточием. Для чтения списка фильмов и музыки, размещенных на первом разделе, можно добавить записи вида /volume1/Video и /volume1/Music (пишите название ваших папок, если они отличаются), а можно вообще добавить единственную запись вида /volume1.

      Вот моя строка open_basedir (думаю, не стоит ее копировать на ваш накопитель, привожу просто для примера):
      /etc:/etc.defaults:/tmp:/usr/bin/php:/usr/syno/synoman:/var/packages/MailStation/target/roundcubemail:/var/run:/var/services/blog:/var/services/homes:/var/services/photo:/var/services/web:/var/spool/php:/volume1:/volume1/@tmp/php

  2. Привет!
    Эльдар, не могли бы подробнее про скрипт рассказать?

    • Эльдар Аблаев

      Привет! Как именно подробнее? Код выше снабжен подробными комментариями на русском языке. Скрипт выдает список папок и файлов в заданной папке в алфавитном порядке в пределах раздела 1 сетевого накопителя Synology. Папка, в которой нужно искать задается переменной dir в HTTP-запросе типа GET.

      Например, если в разделе 1 сетевого накопителя у вас есть папка Video, то с помощью запроса вида http://ds212j/nas_navigation_simple.php?dir=Video/ вы увидите список папок и файлов внутри папки Video. Можно сделать и более глубокие запросы, например http://ds212j/nas_navigation_simple.php?dir=Video/Clips/Madonna/.

      Скрипт принудительно ограничен папками Music и Video, если хотите, можете добавить нужные вам папки в аргументах вызова функции preg_match.

      В случае, если при запросе вы укажете HTTP-заголовок User-Agent: Crestron, вы получите список, разделенный символами переноса строки и возврата каретки (\x0D \x0A), иначе разделителем будет текст "<br>".

      Как сделать HTTP-запрос с помощью контроллера Crestron я возможно опишу в одной из будущих статей.

  3. Очень любопытно, опишите, пожалуйста, процесс со стороны Crestron –
    На сколько я понял, Dune нельзя передать команду «покажи папку \\server\folder»
    только конкретный файл, да и то, отдельные команды для проигрывания .mkv или .iso

    • Эльдар Аблаев

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

      Да, команды "покажи папку" в протоколе нет. Простой способ решить задачу - средствами того же скрипта PHP создать в каждой папке файл плейлиста M3U. Сложный способ - повесить на контроллер задачу отследить статус текущего трека и по его завершению начинать воспроизведение следующего.

Написать ответ к Александр


[ Ctrl + Enter ]