Я уже давно пользуюсь домашним облаком Seafile, которое развёрнуто дома на виртуальном сервере Ubuntu 18.
Seafile — это личное хранилище для хранения данных в стиле Dropbox. Seafile — замечательный инструмент для создания личного, семейного или корпоративного файлового хранилища. Не очень сложен в установке и настройке. Бесплатен.
В один прекрасный день мне подсказали мысль, сделать на базе Seafile + MiniDLNA домашний медиа сервер. Идея простая, загружаем в Seafile фильм, на любом телевизоре дома смотрим. Современные телевизоры поддерживают технологию DLNA, которая позволяет смотреть фильмы по сети.
DLNA (Digital Living Network Alliance) — набор стандартов, которые позволяют передавать и воспроизводить в реальном времени фото, видео и аудио файлы по домашней сети. Поддерживается проводная (Ethernet) и беспроводная (Wi-Fi) связь.
Задача не так проста, как кажется на первый взгляд, для настройки медиа сервера нужно решить две задачи:
- Получить доступ к данным Seafile как в обычной файловой системе.
- Поднять DLNA сервер.
По отдельности про решение этих двух задач можно почитать здесь:
В Seafile данные не хранятся в виде файлов а разбиты на блоки. Это позволяет эффективно использовать механизм дедупликации данных. Но для предоставления данных серверу DLNA эти блоки нужно превратить в обычные файлы. Для этого используется расширение seaf-fuse. Seaf-fuse является реализацией виртуальной файловой системы FUSE. Этот скрипт монтирует всё содержимое Seafile в папку (которая называется "mount point"), так что мы получаем доступ ко всем файлам Seafile так же, как к обычной папке на сервере.
https://manual.seafile.com/extension/fuse/
Доступ к зашифрованным папкам с помощью seaf-fuse не предоставляется, поэтому библиотеку с фильмами не шифруем. Данные доступны только для чтения, это нам подходит. В debian/centos для монтирования папки FUSE пользователь должен быть в группе "fuse".
Как использовать seaf-fuse
Создаём точку монтирования, назначаем владельцем пользователя, от имени которого работает seafile:
mkdir /opt/seafile-fuse
chown sf\: /opt/seafile-fuse
У меня Ubuntu, поэтому для монтирования директории пользователь должен быть участником группы fuse. Создадим группу и добавим в неё пользователя:
groupadd fuse
usermod -aG fuse sf
Для проверки можно запустить скрипт seaf-fuse от имени пользователя, под которым работает seafile:
/opt/seafile-server-latest/seaf-fuse.sh start /opt/seafile-fuse
В папке /opt/seafile-fuse появится содержимое Seafile. Теперь мы можем получить путь к папке с фильмами, например:
/opt/seafile-fuse/user@example.com/5403ac56-5552-4e31-a4f1-1de4eb889a5f_Video
Для остановки монтирования:
/opt/seafile-server-latest/seaf-fuse.sh stop
По умолчанию доступ к содержимому имеет пользователь root, дадим доступ всем пользователям сервера. Редактируем файл /etc/fuse.conf. Раскомментируем опцию:
user_allow_other
Для проверки можно запустить скрипт seaf-fuse от имени пользователя, под которым работает seafile, с параметрами:
/opt/seafile-server-latest/seaf-fuse.sh start -o allow_other /opt/seafile-fuse
В папке /opt/seafile-fuse появится содержимое Seafile. Доступ к содержимому имеют все пользователи.
Автоматизируем запуск seaf-fuse
Запуск служб Seafile у меня уже автоматизирован:
Добавим автозапуск seaf-fuse в systemd.
${seafile_dir} — измените переменную на путь к вашей директории Seafile. У меня /opt.
User и Group — измените на своего пользователя и группу.
Работаем под рутом. Создаём сервис seafile-fuse:
sudo vim /etc/systemd/system/seafile-fuse.service
Сервис будет запускаться после seafile и seahub. Содержимое:
[Unit]
Description=Seafile fuse
After=network.target seafile.service seahub.service
[Service]
Type=forking
ExecStart=${seafile_dir}/seafile-server-latest/seaf-fuse.sh start -o allow_other /opt/seafile-fuse
ExecStop=${seafile_dir}/seafile-server-latest/seaf-fuse.sh stop
LimitNOFILE=infinity
User=sf
Group=sf
[Install]
WantedBy=multi-user.target
Настраиваем автозагрузку:
systemctl daemon-reload
systemctl enable seafile-fuse
Проверяем:
systemctl start seafile-fuse
systemctl status seafile-fuse
Теперь после загрузки сервера папка с содержимым Seafile будет монтироваться автоматически.
MiniDLNA
Можно установить любой DLNA сервер, первый кандидат на установку — minidlna. Сейчас проект носит название ReadyMedia, но пакеты в Ubuntu носят прежнее название. Это легковесный DLNA/UPnP медиа сервер. По сути осуществляет единственную функцию: предоставляют сетевой доступ к медифайлам по протоколу DLNA/UPnP. Обладает рядом достоинств и недостатков, выявленных в процессе эксплуатации.
Достоинства minidlna:
- Потребляет мало ресурсов. При формировании базы грузит процессор, после работает почти незаметно.
- Простота настройки. Есть пакеты под разные ОС, NAS, DD-WRT/OpenWRT.
- Возможность работы под любым указанным пользователем в качестве демона.
- Ничего лишнего.
Недостатки minidlna:
- DLNA поддерживается не в полной мере. Может не обнаруживаться некоторыми устройствами.
- Не производит перекодирование на лету. Если телевизор не может распознать файл, то проиграть не сможет.
- Проблемы с автоматическим обновлением базы. Подробности в статье.
Особенности minidlna:
- Нет GUI и web. Это для кого-то недостаток, а для кого-то достоинство.
Ссылки
https://sourceforge.net/projects/minidlna/
Установка MiniDLNA в Ubuntu 18
Устанавливаем пакет из репозитория:
apt-get install -y minidlna
Конфигурационный файл находится по адресу: /etc/minidlna.conf.
Сервис у меня будет работать от пользователя sf. Создадим рабочую папку для базы и логов:
mkdir /opt/minidlna
chown sf\: /opt/minidlna
Настроим /etc/minidlna.conf:
#user=sf
media_dir=V,/opt/seafile-fuse/user@example.com/5403ac56-5552-4e31-a4f1-1de4eb889a5f_Video
# media_dir=A,/home/sf/Music
# media_dir=P,/home/sf/Photo
merge_media_dirs=yes
db_dir=/opt/minidlna/cache/minidlna
log_dir=/opt/minidlna/log
root_container=V
port=8200
friendly_name=MiniDLNA Media Server
model_name=MiniDLNA
inotify=yes
notify_interval=895
media_dir — директория, к которой будем предоставлять доступ.
merge_media_dirs — объединять медиа директории.
db_dir — директория, в которой формируется база данных DLNA.
log_dir — директория, в которой находится log файл. Мне кажется, переопределяется в /etc/defaults/minidlna.
root_container — контейнер для корневой директории.
port — порт, по умолчанию 8200.
friendly_name — название сервера, которое будет отображаться на телевизоре, клиенте DLNA.
model_name — модель, тоже для DLNA клиента.
inotify=yes — важный параметр, который включает возможность автоматического отслеживания добавление и удаления контента в директории. Вот только данный функционал не работает в примонтированных директориях типа cifs или виртуальных папок fuse, они просто не формируют уведомления для операционной системы.
notify_interval — интервал в секундах, через который minidlna броадкастом уведомляет по сети о своём существовании всем устройствам. По умолчанию примерно 15 минут (895 секунд).
user — здесь можно указать пользователя, под которым будет работать minidlna, однако, в Ubuntu данный параметр (вместе с группой) переопределяется в файле /etc/defaults/minidlna, поэтому его нужно указать там в параметрах USER и GROUP:
Здесь же указывается запуск в режиме демона:
START_DAEMON="yes"
Обращаем внимание на опцию:
DAEMON_OPTS="-r"
Опция применяет параметр при запуске службы:
- -r — добавляет новые объекты в базу, удаляет несуществующие. На виртуальной папке fuse работало только удаление.
- -R — удаляет базу и формирует заново. Работает без нареканий.
Перезапускаем службу:
systemctl restart minidlna
Или:
service minidlna restart
Проверяем, работает ли служба, также смотрим параметры запуска:
service minidlna status
Настройка MiniDLNA медиа сервера завершена.
Исправление ошибок
В логах ошибка:
[2021/10/25 12:53:17] monitor.c:218: warn: WARNING: Inotify max_user_watches [8192] is low or close to t he number of used watches [92] and I do not have permission to increase this limit. Please do so manual ly by writing a higher value into /proc/sys/fs/inotify/max_user_watches
Правим /etc/sysctl.conf, дописываем:
#MiniDLNA warning fix
fs.inotify.max_user_watches = 100000
Главное, чтобы значение было не меньше 65536.
Изменение применится после перезагрузки системы.
В браузере http://адрес_сервера:8200, видим количество файлов в библиотеке и список подключенных клиентов.
Сканирование библиотеки
При запуске демона minidlna сканирует подключённые медиа директории. Сканирование задано параметром "-r" в файле /etc/defaults/minidlna опцией:
DAEMON_OPTS="-r"
Опция добавляет новые объекты в базу, удаляет несуществующие. Если указать опцию "-R", то при запуске демона база удалится и сформируется заново. Сканирование больших библиотек может длиться несколько минут.
Перезапустить сканирование библиотеки можно вручную:
rm /opt/minidlna/cache/minidlna/files.db
systemctl restart minidlna
Или:
minidlnad -R && systemctl restart minidlna
Автоматическое обновление данных с помощью inotify на виртуальных папках не работает. Единственный вариант полного обновления библиотеки — запуск команды вручную или с помощью crontab по ночам.
Результат работы на стареньком телевизоре Philips
Входим в сеть.
Обнаружен наш сервер.
Папки читаются.
Файлы читаются.
Превьюшки нет. Судя по конфигурационному файлу, у minidlna есть возможность загрузки превьюшек для аудио альбомов. Возможно, для фильмов тоже заработает. Но мне не хочется это делать вручную.
Фильм проигрывается. Даже с субтитрами.
Результат работы на телевизоре LG
Захожу в SmartShare.
Перехожу к устройствам.
Обнаружен наш сервер.
Папки и файлы читаются.
Фильм проигрывается. Тоже с субтитрами.
Результаты
На базе домашнего облака Seafile + MiniDLNA получилось сделать домашний медиа сервер. С фильмами, фотографиями и музыкой.
Минусы
- После загрузки фильма приходится ждать, когда ночью (или в другое настроенное вами в crontab время) сработает скрипт обновления базы DLNA. Или запускать скрипт вручную.
- База обновляется долго, если в Seafile большой альбом фотографий и фильмов, то обновление может длиться несколько минут.
- При запуске скрипта обновления базы сервис DLNA перезапускается. Если в этот момент проигрывается фильм, то воспроизведение останавливается.
- Нет встроенного механизма превьюшек для фильмов.
- Нет кодирования видео на лету. Нужно подбирать формат фильма, который понимает телевизор.
- Нет GUI веб интерфейса для просмотра фильмов в браузере.
Плюсы
- Фильмы по DLNA заработали и на старом телевизоре Philips и на более новом LG.
- MiniDLNA и Seafile не требовательны к ресурсам, процессор и память не жрут.
- Оно-таки работает.
- А ведь можно запустить несколько разных серверов DLNA, параллельно с MiniDLNA. Чем я позже и займусь...
Заметки
- Мне хотелось бы превьюшки к видео, чтобы дети могли по картинке выбирать что смотреть.
- А ещё хочу IPTV, это уже не в рамках этой статьи.
- И хочу просмотр фильмов по Web, Seafile этого не даёт.
- Фильмы высокого качества по Wi-Fi тормозят, нужно подключать телевизор к проводной сети Ethernet.
Я буду пробовать и другие медиа серверы с поддержкой DLNA, ждите новый статей.