четверг, 10 сентября 2015 г.

Kodi - изменение путей к файлам в БД MySQL

Когда-то меня посетила светлая мысль использовать централизованную базу данных для библиотеки XBMC (теперь это Kodi). Благо, софт позволял это сделать. При использовании нескольких экземпляров мегакомбайна - а по другому Kodi/XBMC трудно назвать, преимущества такого подхода очевидны: данные о библиотеке хранятся в одном месте, можно продолжать просмотр видео или прослушивание музыки на любом устройстве с установленным Kodi и так далее и тому подобное.

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

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

А хранятся они в обычной файловой системе на каком-нибудь компьютере или компьютерах. Или NAS-ах. Или на тех и на других. В базе же хранятся только пути до файлов с фильмами и сериями. Причем, именно пути являются уникальными ключами информации. То есть, если положить один и тот же фильм в два разных места, то в базе данных для каждого из мест, в котором мы сохранили файл с фильмом, будет создана запись, указывающая на конкретный файл.

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

Мои источники видео

Логично предположить, что источник связан с каким-то хранилищем информации. И действительно, при задании источника вам придется указать тип этого хранилища и месторасположение на нем нужных вам файлов. Что такое тип хранилища? Ну, например, это может быть сетевой каталог, доступный по протоколу NFS или Samba (он же CIFS), или локальный диск, или UPnP источник.

Типы возможных хранилищ

Далее, у Kodi есть функция обновления информации о библиотеке. Когда она запущена, производится просмотр всех источников на предмет нахождения в них новых файлов. А как понять, файл новый или нет? Разработчики пошли следующим путем: они формируют полный путь файла из пути источника, заданного при его настройке, и самого имени найденного файла, и ищут по получившемуся значению информацию в базе данных. Если данные найдены, значит файл не новый, а не найдены - файл надо добавить в БД. При этом, конечно же, запоминается и полный путь. Надо сказать, я не смотрел исходные коды Kodi, поэтому - это только мои предположения, может, механизм и отличается, но, что важно, результат именно такой.

И еще немного про источники. Под одним источником может скрываться не один, а несколько мест хранения информации. То есть, можно логически объединить в одном источнике несколько сетевых каталогов, например.

Данные из двух устройств представлены в одном источнике

У меня так и сделано. Начиналось мое видеохранилище с домашнего NAS-а WD MyBook Live. Это было однодисковое двухтерабайтовое устройство. Хотя, почему "было"?! Оно и сейчас замечательно работает (тьфу три раза). Но, если честно, я был слегка удивлен тем, как быстро заполнились эти самые два терабайта. Нет, умом-то я понимаю, что файлов в тот момент по разным дискам у меня было разбросано много, то есть, уже начальный перенос отъел большую часть дискового пространства MyBook Live. Но...

Как бы то ни было, вскоре был приобретен старший брат моего домашнего NAS-а - WD MyBook Live Duo. Мой экземпляр - это двухдисковое устройство, каждый диск по два терабайта. Использую я его в режиме RAID 0 (хотя есть утверждение, что это не RAID 0, а так называемая spanning конфигурация дисков - производитель не посчитал себя обязанным точно указать используемую технологию), то есть, он виден моим устройствам, как один диск размером четыре терабайта.

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

Но разработчики Kodi (XBMC) пошли еще дальше - они научили свою программу логически объединять и отображать данные, как единое целое, если структуры хранения (часть пути к файлам) совпадают. Ну например. Есть у меня сериал. Первые несколько сезонов хранятся у меня на WD MyBook Live. Пусть путь будет таким: /TVSeries/VeryGoodFictionShow (название вымышленное), ну а там подкаталоги Season-1, Season-2 и Season-3. Новые же серии я размещаю на WD MyBook Live Duo. Если я назову подкаталоги, в которых хранятся эпизоды этого сериала, одинаково, то Kodi, при отображении, покажет их вместе. То есть, на другом устройстве воссоздаю структуру каталогов: /TVSeries/VeryGoodFictionShow и создаю там подкаталог Season-4. Kodi отобразит их, так, как будто все сезоны лежат вместе, в одном родительском каталоге. Более того, если на старом устройстве не поместилось окончание третьего сезона, то на новом создаем подкаталог Season-3 и новые серии помещаем туда. Kodi покажет все серии третьего сезона единым списком. Но если ошибетесь хоть в одной букве в файловом пути - не ждите чудес, медиакомбайн не сможет логически объединить вашу информацию.

Настройка источников хранится в XML файле sources.xml. Модификация источников, добавление их или удаление - все находит отражение в этом файле. Так как у меня используется несколько экземпляров Kodi, то каждый раз при изменениях источников приходилось извращаться, чтобы изменения были учтены везде. Я перепробовал много методов, пока не остановился на использовании общего для всех установок Kodi единственного файла sources.xml. Я разместил его на сетевом диске и изменил настройки всех Kodi (файл advancedsettings.xml) так, чтобы они смотрели на этот общий файл. Собственно говоря, я все это уже описывал. Но, как говорится, повторение - мать учения.

В заключении этой затянувшейся вводной части хочу добавить вот еще что. Когда я настраивал источники, то в качестве имен хостов при указании SMB источников использовал NetBIOS имена. В тот момент я думал, что это удачная идея. Ведь, при использовании DHCP, хосты каждый раз могут получать новые IP адреса, если, конечно, явно не задать им статические адреса. И, не смотря на то, что для обоих домашних NAS-ов я задал именно статические адреса, в настройке источников Kodi я использовал их NetBIOS имена. О чем, спустя некоторое время, и пожалел.

Так что же было не так с именами NetBIOS? В принципе, они нормально работали. Очень редко, можно пересчитать на пальцах одной руки, какое-нибудь из устройств с Kodi не могло открыть источник, но повторное обращение срабатывало всегда. Единственное, что немного напрягало - это скорость открытия источников: по мере усложнения структуры физических источников и добавления новых хранилищ, открытие логических источников контента происходило все медленнее. Я, может быть, и смирился бы со сложившейся ситуацией, но язвительные подколки домочадцев по поводу "ничего не работает" и "сапожник без сапог" возымели свой эффект - я решился на замену NetBIOS имен на IP адреса. Тем более, что в документации Kodi именно так и советовали поступить,по крайней мере, для указания машины на которой установлен сервер MySQL.

Итак, мне предстояло заменить три имени на соответствующие IP. Много это или мало? Ну, во-первых, хотелось бы обозначить, какие именно имена я собирался заменить на IP. Это, как я уже говорил, имя хоста, на котором был запущен MySQL. Кроме того, для полноты картины, я вознамерился заменить имена MyBook Live и MyBook Live Duo во всех источниках. Казалось бы, что тут такого, исправляешь файлы advancedsettings.xml (там указан компьютер с MySQL) и sources.xml (там описаны источники) - вот и все дела. Но все не так просто.

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

Какие? Самое простое: при очередном обновлении библиотеки все файлы, размещенные, по сути, в тех же местах, что и раньше, получат новый путь, в котором вместо NetBIOS имени будет фигурировать IP адрес. Таких записей в БД нет и Kodi их добавит, как новые. Как следствие, вся информация задвоится - по каждому файлу будет две записи - одна со старым, другая - с новым путем. Остальные данные будут идентичны.

И это не просто теория. После изменения настроек источников, я, по неосторожности, запустил Kodi. Функция обновления библиотеки у меня настроена на автоматическое выполнение при запуске медиакомбайна. Когда я увидел замелькавшие названия файлов (у меня включен флаг отображения процесса обновления), я выключил Kodi, но несколько десятков файлов успело задублироваться (ну да, тормознул я).

Парочка настроек по автоматическому обновлению библиотеки

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

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

Но можно подправить данные и вручную непосредственно в БД. Мне было это интересно, поэтому я решил, что пойду именно этим путем. Кроме того, при этом не потеряется информация о просмотренных фильмах и сериалах.

Итак, приступим. Первым делом нам понадобится инструмент для работы с БД MySQL. Я порылся в интернете, почитал отзывы и выбрал - HeidiSQL. Установка этой программы ничем не примечательна, так что не буду на ней подробно останавливаться. Когда установка завершена, запускаем программу и подключаемся к нужной БД - тут надо вспомнить пароль пользователя БД. Но если не помните - не беда, он записан в файле advancrdsettings.xml, впрочем, как и имя пользователя. Самое интересное начинается именно сейчас, после подключения к БД.

У HeidiSQL есть очень интересная функция, которая, в конечном итоге, сильно мне помогла. Это - поиск текста по всей базе данных. Для доступа к этой функциональности необходимо выбрать соответствующий пункт меню.


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


После этого программа начинает пробегать объекты БД в попытке выполнить ваше задание, и, по завершении этого процесса, выдает на экран список объектов с указанием того, сколько строк этого объекта содержат искомую подстроку.


Одна печаль, в этом списке "смешались в кучу кони, люди". То есть, в списке присутствуют таблицы, представления (view), даже тригеры. Я решил, что меня интересуют только таблицы.  Почему? Да, я знаю, что в MySQL некоторые представления являются редактируемыми, то есть, изменение значения в представлении приводит к изменению этого же значения и в таблице, на основании которой построено представление. Но существуют ограничения на то, какие view можно менять, а какие - нет. Я не хотел разбираться в том, как построены представления в БД Kodi и не нарушают ли они этих самых правил, поэтому и выбрал таблицы.

После вывода на экран списка объектов можно нажать кнопку "Показать результаты" и на экране будут выведены объекты со своим содержимым - один объект - одна закладка.


Тут надо внимательно просмотреть все колонки каждой таблицы (почему таблицы - смотри выше) для того, чтобы понять, какие именно поля придется менять. Ну и потом написать скрипт обновления. У меня получился такой:

update art set url = replace(url,'//MYBOOKLIVE/','//XXX.XXX.XXX.XXX/');
update art set url = replace(url,'//MYBOOKLIVEDUO/','//YYY.YYY.YYY.YYY/');
update episode set c18 = replace(c18,'//MYBOOKLIVE/','//XXX.XXX.XXX.XXX/');
update episode set c18 = replace(c18,'//MYBOOKLIVEDUO/','//YYY.YYY.YYY.YYY/');
update files set strFilename = replace(strFilename,'//MYBOOKLIVE/','//XXX.XXX.XXX.XXX/');
update movie set c22 = replace(c22,'//MYBOOKLIVE/','//XXX.XXX.XXX.XXX/');
update movie set c22 = replace(c22,'//MYBOOKLIVEDUO/','//YYY.YYY.YYY.YYY/');
update path set strPath = replace(strPath,'//MYBOOKLIVE/','//XXX.XXX.XXX.XXX/');
update path set strPath = replace(strPath,'//MYBOOKLIVEDUO/','//YYY.YYY.YYY.YYY/');
update art set url = replace(url,'%2f%2fMYBOOKLIVE%2f','%2f%2fXXX.XXX.XXX.XXX%2f');
update art set url = replace(url,'%2f%2fMYBOOKLIVEDUO%2f','%2f%2fYYY.YYY.YYY.YYY%2f');
commit work;

XXX.XXX.XXX.XXX - статический IP адрес MyBook Live
YYY.YYY.YYY.YYY - статический IP фдрес MyBook Live Duo.

Настоящие адреса я не привожу, кому они помогут, все равно надо будет заменить на свои, если попытаетесь использовать скрипт для своих нужд (ну да, вдруг кто соберется ломать?). И не забудьте, что и NetBIOS имена, скорее всего, тоже придется изменить на свои.

Перед тем, как запустить скрипт в HeidiSQL, я сделал бэкап текущего состояния БД. Опять же, используя HeidiSQL.


В ответ на выбор пункта меню "Экспорт базы данных в SQL" программа выводит окно, которое позволяет указать некоторые параметры экспорта. Я приведу свой вариант заполнения этого окошка.


Немного пояснений. Во-первых, отмечаем базу данных, которую хотим экспортировать. Во-вторых, указываем, какие команды надо включить в генерируемый скрипт для самой БД и таблиц. Я выбрал и для БД и для таблиц галки "Уничтожить" и "Создать". Основание самое что ни на есть простое - если что пойдет не так - забудем все, как страшный сон (импорт пересоздаст базу с нуля). На самом деле, наверное, можно было оставить выключенными обе галки для БД, но мне показалось, что так будет надежнее. В-третьих, выбираем, каким образом данные должны попасть в таблицы. Так как я выбрал, по сути, пересоздание и БД и таблиц, то логично выбрать вставку данных (insert). Ну и на последок, в- четвертых, я указал имя файла, использовав шаблоны, которые понимает HeidiSQL. Расшифрую мой выбор (%host_%db_%y%m%d): имя файла будет собрано следующим образом - имяхоста_имяБД_ГодМесяцДень.sql


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

Да, в завершении, хочу привести ссылку на документацию самого Kodi по проведению только что описанной мною процедуры. Есть совпадения, есть отличия. Надо сказать, что эту ссылку я нашел уже после того, как произвел все описанные манипуляции самостоятельно. Такие вот дела...

Комментариев нет:

Отправить комментарий