В одном из предыдущих постов я написал, что существует возможность обойти ограничение API медиаплеера Dune HD TV-101 по навигации по папкам с файлами пользователя. Собственно способ позволяет использовать навигацию не привлекая самого медиаплеера. Дело в том, что практически любой сетевой накопитель имеет встроенный веб-сервер и интерпретатор языка PHP. Так почему бы не написать скрипт, который позволит контроллеру напрямую получать информацию о структуре папок и файлов прямо с сетевого накопителя?
Для работы такого скрипта необходимо выполнить несколько простых настроек сетевого накопителя. Я привожу настройки для накопителей Synology, для других накопителей нужно будет выполнить аналогичные:
- Создать сетевую папку Web.
- Включить службу Web Station.
- Зайти в настройки PHP, включить возможность настроить переменную open_basedir.
- Добавить в open_basedir запись вида /volume1 (записи разделяются двоеточием, данная запись разрешает скриптам PHP чтение файлов из всех пользовательских папок в первом разделе).
- Разместить скрипт в папке 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); ?>
со скриптами плохо дружу, у меня в настройках 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
Привет!
Эльдар, не могли бы подробнее про скрипт рассказать?
Привет! Как именно подробнее? Код выше снабжен подробными комментариями на русском языке. Скрипт выдает список папок и файлов в заданной папке в алфавитном порядке в пределах раздела 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 я возможно опишу в одной из будущих статей.
Очень любопытно, опишите, пожалуйста, процесс со стороны Crestron –
На сколько я понял, Dune нельзя передать команду «покажи папку \\server\folder»
только конкретный файл, да и то, отдельные команды для проигрывания .mkv или .iso
Поскольку я предложил только общую идею, то не могу ответить на первый вопрос. Реализация полного функционала может быть различной. Можно как усложнить скрипт PHP, так и свалить всю дальнейшую работу с полученным списком файлов на контроллер.
Да, команды "покажи папку" в протоколе нет. Простой способ решить задачу - средствами того же скрипта PHP создать в каждой папке файл плейлиста M3U. Сложный способ - повесить на контроллер задачу отследить статус текущего трека и по его завершению начинать воспроизведение следующего.