вторник, 10 января 2012 г.

Stora и все, все, все...

В декабре 2011 я переехал в новую квартиру. В ней планировал использовать не один телевизор, а несколько. Отказаться от телевидения, оставить исключительно сетевой доступ к новостям и к видео на сетевом хранилище. Прежний вариант с хранением фильмов на медиаплеере HDS6L исключался, т.к. предполагал подключение только к одному телевизору. Не ставить же медиаплееры с жесткими дисками под каждый телевизор!

В тот момент у меня был один телевизор UE40B7000. Отличный телевизор, который не хотел проигрывать из сети фильмы ни с одного DLNA сервера. Вернее, если быть более точным, проигрывал исключительно старые небольшие avi файлы, а вот более современные avi, mkv, m2ts и т.п. отказывался наотрез. Основания у него были самые разные, то видеокодек отсутствует, то аудиокодек отсутствует, то формат файла неизвестен. В итоге, прикидочно, из всей коллекции фильмов он проигрывал по DLNA не более 10% фильмов.

DLNA сервера были сделаны сперва на компьютере с Windows 7, а потом попробовал сделать на роутере  ASUS RT-N16. Оговорюсь сразу, сильно я не упорствовал, т.к. хотел, чтобы все заработало, так сказать, из коробки. Обломался.

В связи с переездом, собственно, было организовано небольшое новоселье для коллег (у нас так принято), которые подарили мне новую игрушку Netgear Stora (она же MS2000). В зависимости от ее возможностей предполагалось ее дальнейшее применение, одно из двух:
1. Хранение семейного фото и видео архива (RAID1).
2. Хранение фильмов (JBOD).
Выбор назначения Stora упирался в его возможности удобного хранения и трансляции фильмов через сеть на телевизоры и/или тоже самое с фото/видео архивом.

К тому момент я прикупил новый телевизор для гостиной UE55D7000. Очень надеялся на то, что уж он то с полпинка будет проигрывать любые файлы с DLNA сервера. Куда там! Все та же история. Ну стал он проигрывать чуть больше файлов, в итоге получил не 10%, а 15% проигрываемых фильмов. Меня такое неустроило совсем.

Конечно, есть вариант с покупкой сетевого медиаплеера, например, XDS73D, который возьмет на себя навигацию по сетевой шаре, обработку видеопотока и трансляцию видеосигнала по HDMI. Но это вариант  для богатых, т.к. к одному телевизору еще можно прикупить медиаплеер, ну даже для двух можно, но если телевизоров больше (3 или 4), то столько медиаплееров уже никуда не годится. Кроме этого, во время ремонта под каждое место для установки телевизора я подвел три розетки: силовая, антенная, сетевая. Если к сетевой розетке подключать медиаплеер, то телевизор остается без доступа к сети, зачем тогда все Smart TV функции? Разделить сетевой кабель свитчом на два? Тоже вариант, но за телевизором собирается целый моток всякой ерунды: силовой удлинитель, сетевой удлинитель (свитч), медиаплеер, два блока питания, пучок кабелей. Отвратительное решение!

В новогодние праздники началось изучение Stora. Изучение началось с загугливания и выхода на статью Netgear Stora MS2000 — раскрываем потенциал. В ней все хорошо описано, мне пригодилось:
Hard-reset - это когда я с игрушкой наигрался и всю ее испоганил.
Root - как без этого.
Перемещение папки /opt на жесткий диск - мне тоже боязно NAND постоянно перезаписывать.
Установка Optware - без ipkg никак.

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

Предустановленный DLNA сервер на Stora - minidlna. Толку от него мало, т.к. он тупо передает данные в сеть, что для телевизоров Samsung маловато. В итоге, принял решение отказаться от minidlna в пользу mediatomb. Большую роль в принятии такого решения сыграла статья Медиа-хранилище своими руками. Впечатлил чужой опыт, однако.

Внутри Stora установлен BusyBox. Установку mediatomb выполнил в соответствии с инструкцией описанной на форуме. Ее оказалось достаточно для того, чтобы mediatomb заработал, а телевизоры начали проигрывать почти все файлы. Особое внимание надо обратить на образец файла config.xml, который приведен в теме, а дополнительно можно глянуть сюда.

В итоге, после запуска mediatomb, старый телевизор стал проигрывать 90% файлов. Спотыкается исключительно по непонятным причинам, с которыми надеюсь разобраться. Новый телевизор проигрывает все, а что порадовало отдельно, файлы с 3D фильмами сразу переключают телевизор в нужный режим отображение 3D!

В настоящий момент решаю вопрос с организацией хранения файлов. По-умолчанию mediatomb тупо кидает ссылки на все файлы в один каталог Video. Но, как было сказано не мной, mediatomb "прекрасно скриптующийся"! Достаточно написать простой код в import.js в функции addVideo и файлы будут организованы по папкам, подпапкам и т.д.

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

Первый подход...

Формат хранения выбрал следующий:
RU=Название фильма - названием фильма на русском языке
US=Оригинальное название - название фильма в оригинале, если французский, то FR и т.д.
C=Художественный - категория фильма: художественный, документальный, сериал и т.п.
G=Комедия - жанр фильма
A=Jim Carrey - актер
D=Peter Weir - режиссер
Y=1998 - год выпуска фильма
IMDB=tt0120382 - идентификатор фильма по базе imdb.com.

В итоге, имя файла получалось примерно такое:

RU=Шоу Трумана,US=The Truman Show,C=Художественный,G=Комедия,G=Драма,A=Jim Carrey,D=Peter Weir,Y=1998,IMDB=tt0120382.avi

Последовательность расположения полей со значениями или их количество (кроме наименований), не имеет значения. Составил регулярное выражение, которое тестировал с помощью Online Regular Expression Tester. Интегрировал код в файл import.js. Получил результат, представленный на картинке. Удобно, наглядно, гибко.



После внесения в базу медиатеки 4-х фильмов я понял, что моего терпения не хватит, атрибутировать фильмы общей емкостью в 2Тб. Надо искать какой-то выход более автоматизированный. В голову пришла идея, использовать сайт imdb.com в роли источника информации о фильме, а в названии файла фильма писать только названием фильма на русском языке и imdb идентификатор. Но как это обработать в import.js?

Второй подход...
Не нашел я способа, позволяющего из import.js обращаться к сайту imdbapi.com. В итоге, решил пойти по пути, выбранному в блоге Медиа-хранилище своими руками. Однако, группированное хранение фильмов связанных по одному признаку (многосерийные, сиквелы, сериалы и т.п) возложил на обычные папки, а имена файлам дал по принципам:
Русское название [Оригинальное название][2012,Жанр].avi - для зарубежных фильмов
и
Русское название [2012,Жанр].avi - для отечественных фильмов.

В итоге, получил следующее в папке и на сервере:

В итоге, получил следующее в хранилище DLNA сервера:

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

Фрагмент кода, ответственного за добавление видео файлов, приведен ниже:
function addVideo(obj)
{
  //extract extension
  var parts = obj.title.split(/(.+?)\.(\w{2,4})$/g);
  var fname = parts[1];
  var fext = parts[2];

  var re, arr;
  var rus_title = '';
  var frg_title = '';
  var year_num = '';
  var genre = '';

  //foreign film
  arr = fname.split(/(.+?)\s?\[(.*?)\]\s?\[(\d{4}),?(.*?)\]/g);
  if (arr.length > 1)
  {
    rus_title = arr[1];
    frg_title = arr[2];
    year_num = arr[3];
    genre = arr[4];
  }
  else
  {
  //soviet film
    arr = fname.split(/(.+?)\s?\s?\[(\d{4}),?(.*?)\]/g);
    if (arr.length > 1)
    {
      rus_title = arr[1];
      year_num = arr[2];
      genre = arr[3];
    }
  }
  
  //extract location
  var chain;
  var location = obj.location.split('/');
  var rootindex = 0;
  for (var i = 0; i < location.length; i++)
  {
    if (location[i] == "FamilyVideos")
    {
      rootindex = i;
      break;
    }
  }
  chain = new Array();
  if (rootindex + 1 < location.length - 1)
  {
    for (i = rootindex + 1; i < location.length - 1; i++)
    {
      chain.push(location[i]);
    }
    obj.title = fname;
    addCdsObject(obj, createContainerChain(chain)); 
    //add by classification
    if (year_num.length > 0)
    {
      chain = new Array('Классификация','По годам',year_num);
      addCdsObject(obj, createContainerChain(chain));
    }
    if (genre.length > 0)
    {
      var arr_genre = genre.split(/,/g);
      for (i = 0; i < arr_genre.length; i++)
      {
        chain = new Array('Классификация','По жанрам',arr_genre[i]);
        addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER);
      }
    }
    if (frg_title.length > 0)
    {
      var sub_chain = new Array('Классификация','По иностранным названиями');
      obj.title = frg_title + ' [' + year_num + ',' + genre + '].' + fext;
      addCdsObject(obj, createContainerChain(sub_chain));
    }
  }
}
Вот и все. Элегантно и удобно.
Самое главное для меня, что теперь все фильмы лежат в одном месте, в этом же самом месте установлен DLNA сервер, который транслирует в сеть все самые разные форматы видео файлов, а телевизоры подключены к сети одним кабелем без хаба и медиаплеера.

Похоже, что понадобится статья о дефрагментации.