DLNA сервер для Linux Debian / Ubuntu на базе MiniDLNA

Настраиваем домашний DLNA-сервер на базе MiniDLNA, он же ReadyMedia в Linux Debian или Ubuntu Server.

Содержание

Ссылки

Сайт проекта: http://sourceforge.net/projects/minidlna/.

Другие реализации DLNA-сервера под Linux: Plex, MediaTomb, Rygel.

Список DLNA-серверов и клиентов в Википедии.

Клиент для Android: BubbleUPnP.

Установка MiniDLNA

Простейшим способом установки является, установка пакета из репозитория вашего дистрибутива:

sudo apt-get update
sudo apt-get install minidlna

Если в вашем дистрибутиве пакет отсутствует, MiniDLNA можно установить из исходников.

В репозитории Debian 7 доступен пакет с версией 1.0.24, версия хотя и не самая свежая, но вполне рабочая. На момент написания этих строк, из ключевых изменений, в версии 1.1.1 была реализована поддержка динамических сетевых интерфейсов. Если требуется поднять DLNA-сервер на Wi-Fi интерфейсе, или при запуске возникает ошибка: "No IPaddress automatically detected!". Значит, необходимо установить последнюю версию MiniDLNA из исходников.

В случае успешной установки пакета, переходим к разделу: "Настройка MiniDLNA", иначе читаем далее.

Установка Sudo

Если в вашей системе отсутствует команда sudo, желательно ее установить. Sudo нам потребуется в процессе настройки, для тестирования прав доступа к папкам с медиа-файлами.

Устанавливаем sudo:

apt-get install sudo

Добавляем пользователя в группу sudo:

usermod -aG sudo пользователь

Выходим из системы и входим заново, чтобы изменение группы вступило в силу.

Установка MiniDLNA из исходников

Устанавливаем сборочные зависимости:

sudo apt-get update
sudo apt-get build-dep minidlna

Если при установке зависимостей возникает ошибка: "Невозможно найти пакет с исходным кодом для minidlna". Значит, пакет MiniDLNA  отсутствует в вашей версии дистрибутива. В этом случае придется установить зависимости вручную:

sudo apt-get install gcc debhelper libavcodec-dev libavformat-dev libavutil-dev libexif-dev libflac-dev libid3tag0-dev libjpeg-dev libogg-dev libsqlite3-dev libvorbis-dev

Создаем папку для исходников в профиле пользователя и переходим в нее:

mkdir -p ~/src/minidlna
cd ~/src/minidlna

Сборка стабильной версии MiniDLNA

Загружаем исходники последней стабильной версии:

wget --trust-server-names http://sourceforge.net/projects/minidlna/files/latest/download

С ключом --trust-server-name, будет сохранено исходное имя файла: "minidlna-1.1.4.tar.gz", номер версии может отличаться. Если ключ не указан, файл будет сохранен под именем: "download".

Распаковываем архив:

tar -xf minidlna-1.1.4.tar.gz

Переходим в папку с исходниками:

cd minidlna-1.1.4

Конфигурируем:

./configure

Компилируем:

make

Сборка текущей разрабатываемой версии MiniDLNA из Git-репозитория

Для сборки из Git-репозитория, потребуются дополнительные пакеты:

sudo apt-get install git autoconf automake autopoint

Получаем исходники:

git clone git://git.code.sf.net/p/minidlna/git minidlna-git

Переходим в папку с исходниками:

cd minidlna-git

Создаем скрипт автоконфигурации:

./autogen.sh

Конфигурируем:

./configure

Компилируем:

make

Установка

Удаляем пакет, если он был установлен ранее:

sudo apt-get remove minidlna

Устанавливаем собранную версию:

sudo make install

При первичной установке, копируем minidlna.conf в папку /etc:

sudo cp -i minidlna.conf /etc

Создаем init-скрипт:

sudo nano /etc/init.d/minidlna

Если скрипт остался от оригинального пакета Debian, достаточно исправить путь к исполняемому файлу, выделенный красным. Если файл отсутствует, копируем следующий листинг:

#!/bin/sh
#
# MiniDLNA initscript
#
# Based on the mediatomb debian package.
# Original authors: Tor Krill <tor@excito.com>
#                   Leonhard Wimmer <leo@mediatomb.cc>
#                   Andres Mejia <mcitadel@gmail.com>
#
# Modified by: Benoit Knecht <benoit.knecht@fsfe.org>
#
### BEGIN INIT INFO
# Provides:          minidlna
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop::    $network $local_fs $remote_fs
# Should-Start:      $all
# Should-Stop:       $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start minidlna at boot time
# Description:       Manage the minidlna daemon, a DLNA/UPnP-AV media server.
### END INIT INFO

unset USER

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="DLNA/UPnP-AV media server"
NAME=minidlna
DAEMON=/usr/local/sbin/minidlnad
PIDDIR=/run/$NAME
PIDFILE=$PIDDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
DEFAULT=/etc/default/$NAME

# Exit if the package is not installed
[ -x $DAEMON ] || exit 0

# Read configuration variable file if it is present
[ -r $DEFAULT ] && . $DEFAULT

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# Do not start the daemon if NO_START is enabled in DEFAULT
if [ "$START_DAEMON" != "yes" ] && [ "$1" != "stop" ]; then
        log_warning_msg "$NAME: Not starting $DESC."
        log_warning_msg "$NAME: Disabled in $DEFAULT."
        exit 0
fi

# Set the default configuration file
if [ -z $CONFIGFILE ]; then
        CONFIGFILE=/etc/minidlna.conf
fi

# Set the default log file
if [ -z $LOGFILE ]; then
        LOGFILE=/var/log/minidlna.log
fi

# Run as `minidlna' if USER is not specified or is `root'
if [ -z $USER ]; then
        USER=minidlna
fi

# If no group is specified, use USER
if [ -z $GROUP ]; then
        GROUP=$USER
fi

DAEMON_ARGS="-f $CONFIGFILE -P $PIDFILE $DAEMON_OPTS"

#
# Function that starts the daemon/service
#
do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        touch $LOGFILE && chown $USER:$GROUP $LOGFILE || return 2
        if [ ! -d $PIDDIR ]; then
            mkdir $PIDDIR || return 2
        fi
        chown $USER:$GROUP $PIDDIR || return 2

        start-stop-daemon --start --quiet --pidfile $PIDFILE \
                --chuid $USER:$GROUP --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE \
                --chuid $USER:$GROUP --exec $DAEMON -- \
                $DAEMON_ARGS \
                || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2
        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2
        # Many daemons don't delete their pidfiles when they exit.
        rm -rf $PIDDIR
        return "$RETVAL"
}

case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
    do_start
    case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
  ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
       status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                if [ "$1" = "force-reload" ]; then
                        # Rescan the collection
                        DAEMON_ARGS="$DAEMON_ARGS -R"
                fi
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
        exit 3
        ;;
esac

:

Для дистрибутивов на базе Debian 6 в init-скрипте необходимо скорректировать параметр PIDDIR, для современных дистрибутивов корректировка не требуется.

PIDDIR=/var/run/$NAME

Разрешаем запуск скрипта:

sudo chmod 755 /etc/init.d/minidlna

Активируем запуск init-скрипта в rc.d:

sudo update-rc.d minidlna defaults

По умолчанию служба запускается под пользователем minidlna, создаем учетную запись:

sudo adduser --system --home /var/lib/minidlna --group --gecos "MiniDLNA server" minidlna

Также, при первичной установке, потребуется создать файл параметров init-скрипта (/etc/default/minidlna), рассмотренный далее, в процессе настройки.

При установке из исходников, minidlna.conf требует дополнительной корректировки. В пакете Debian пути по умолчанию были изменены, теперь их необходимо прописать явно. 

Открываем редактор:

sudo nano /etc/minidlna.conf

Задаем путь для хранения базы данных, используем домашнюю папку пользователя minidlna, созданного на предыдущем шаге:

db_dir=/var/lib/minidlna

Задаем путь к лог-файлу:

log_dir=/var/log

Настройка MiniDLNA

Правим файл конфигурации:

sudo nano /etc/minidlna.conf

Как минимум, потребуется задать путь к папке с медиа-файлами, параметр: "media_dir".  Также можно задать имя сервера, отображаемое клиентом, параметр: "friendly_name".

В случае если наш DLNA-сервер по совместительству является интернет-шлюзом, также необходимо задать внутренний сетевой интерфейс, параметр: "network_interface".

Параметры в комментариях файла конфигурации содержат значения по умолчанию.

# Порт сервера
port=8200

# Сетевой интерфейс
# Можно задать несколько интерфейсов
# в формате network_interface=eth0,eth1
#network_interface=eth0

# Имя пользователя или UID, под которым будет работать служба
# Добавлен в версии 1.1.0
# В Debian задается в параметрах init-скрипта
#user=jmaggard

# Путь к папке с медиа-файлами
# Для сканирования нескольких папок, укажите несколько параметров media_dir
# Чтобы сканировать файлы определенного типа, укажите соответствующий префикс:
#   A - аудио: media_dir=A,/home/jmaggard/Music
#   V - видео: media_dir=V,/home/jmaggard/Videos
#   P - изображения: media_dir=P,/home/jmaggard/Pictures
# Начиная с версии 1.1.0, можно задать несколько типов:
#   PV - изображения и видео: media_dir=AV,/var/lib/minidlna/digital_camera
#
# При изменении параметра, потребуется повторное сканирование файлов.
# Необходимо выполнить команду "service minidlna force-reload" от имени root [подробнее].
# Начиная с версии 1.1.0, при изменении параметра, сканирование выполняется автоматически.
media_dir=/var/lib/minidlna

# Объединять корневые папки
# Параметр добавлен в версии 1.1.3
# Включаем, чтобы избавиться от лишнего уровня вложенности
# Расположение видео файлов при значении "no": Video/Folders/Video, при значении "yes": Video/Folders
# При изменении параметра, потребуется повторное сканирование файлов.
merge_media_dirs=yes

# Имя DLNA-сервера, отображаемое клиентом
# По умолчанию: "$HOSTNAME:$USER"
#friendly_name=

# Путь к папке для хранения базы данных и кэша обложек альбомов
db_dir=/var/lib/minidlna

# Путь к папке с лог-файлами
log_dir=/var/log

# Уровень детальности лога
# В формате log_level=источник1,источник2=значение1,источник3,источник4=значение2 ...
# Доступные источники: "general", "artwork", "database", "inotify", "scanner", "metadata", "http", "ssdp", "tivo"
# Возможные значения: "off", "fatal", "error", "warn", "info" or "debug"
#log_level=general,artwork,database,inotify,scanner,metadata,info,ssdp,tivo=warn

# Перечень имен файлов-обложек альбомов, разделитель: "/"
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg

# Автообнаружение новых файлов
# Включено по умолчанию
#inotify=yes

# Поддержка устройств TiVo
#enable_tivo=no

# Строго следовать DLNA-стандарту
# Использовать серверное масштабирование для очень больших JPEG-изображений
# Что может снизить скорость их обработки.
#strict_dlna=no

# Адрес веб-страницы устройства
# По умолчанию IP-адрес и заданный порт сервера
#presentation_url=http://www.mylan/index.php

# Интервал отправки SSDP-уведомлений, в секундах
#notify_interval=895

# Серийный номер и номер модели DLNA-сервера, сообщаемый клиенту
serial=12345678
model_number=1

# Путь к сокету MiniSSDPd, если установлен
# Требуется для обеспечения работы нескольких DLNA/UPnP служб на одном сервере
#minissdpdsocket=/run/minissdpd.sock

# Контейнер, используемый в качестве корневой папки для клиентов
#   * "." - стандартный контейнер
#   * "B" - "Обзор папки"
#   * "M" - "Музыка"
#   * "V" - "Видео"
#   * "P" - "Изображения"
# Если задано "B" и клиент представится как аудиоплеер, в качестве корня будет использована папка "Music/Folders"
#root_container=.

# Всегда использовать заданный критерий сортировки, вместо значения, запрошенного клиентом
#force_sort_criteria=+upnp:class,+upnp:originalTrackNumber,+dc:title

# Максимальное число одновременных подключений
# Учтите: многие клиенты открывают несколько подключений одновременно
#max_connections=50

Проверяем параметры init-скрипта /etc/default/minidlna:

sudo nano /etc/default/minidlna

Обычно корректировка не требуется. Если файл отсутствует, при первичной установке из исходников, копируем листинг:

# Запускать демон, если задано "yes"
START_DAEMON="yes"

# Путь к файлу конфигурации
#CONFIGFILE="/etc/minidlna.conf"

# Путь к лог-файлу
#LOGFILE="/var/log/minidlna.log"

# Запуск от имени заданного пользователя и группы
# По умолчанию: minidlna
#USER="minidlna"
#GROUP="minidlna"

# Дополнительные ключи запуска
DAEMON_OPTS=""

Поскольку служба работает под пользователем с ограниченными правами, публикуемые папки и файлы должны быть доступны на чтение для всех пользователей, следовательно, иметь разрешения 644: "rw- r-- r--", для файлов и 755: "rwx r-x r-x", для папок.

Проверяем доступность для каждой папки, заданной в minidlna.conf, командой:

sudo -u minidlna ls -l папка

Если папка недоступна, задаем права доступа: 

sudo chmod -R 755 папка

Вышестоящие папки также должны быть доступны на чтение всем пользователям. Проверяем доступность на чтение каждой папки, указанной в пути. Для вышестоящих папок используем chmod без ключа -R, если не требуется сброс разрешений для всех дочерних файлов и папок. 

В качестве альтернативы смене разрешений, можно запустить MiniDLNA от имени пользователя или группы-владельца файлов. Для этого необходимо задать параметры USER и GROUP в /etc/default/minidlna, и сменить владельца папки /var/lib/minidlna командой:

sudo chown -R пользователь:группа /var/lib/minidlna

Запуск MiniDLNA

Запускаем службу:

sudo service minidlna start

Проверяем, работает ли служба, также смотрим параметры запуска:

ps ax | grep minidlna

Проверяем, слушается ли порт:

sudo ss -4lnp | grep minidlna

Проверяем лог:

cat /var/log/minidlna.log

В случае успешного старта, лог должен быть примерно следующим:

[2014/04/07 22:00:48] minidlna.c:1000: warn: Starting MiniDLNA version 1.1.2.
[2014/04/07 22:00:48] minidlna.c:354: warn: Creating new database at /var/lib/minidlna/files.db
[2014/04/07 22:00:48] minidlna.c:1039: warn: HTTP listening on port 8200
[2014/04/07 22:00:48] scanner.c:702: warn: Scanning /var/lib/minidlna
[2014/04/07 22:00:55] scanner.c:789: warn: Scanning /var/lib/minidlna finished (25 files)!
[2014/04/07 22:00:55] playlist.c:125: warn: Parsing playlists...
[2014/04/07 22:00:55] playlist.c:256: warn: Finished parsing playlists.
[2014/04/07 22:00:55] inotify.c:198: warn: WARNING: Inotify max_user_watches [8192] is low or close to the number of used watches [14] and I do not have permission to increase this limit.  Please do so manually by writing a higher value into /proc/sys/fs/inotify/max_user_watches.

Если видим: "WARNING: Inotify max_user_watches [8192] is low.", необходимо увеличить число дескрипторов слежения inotify до 100 000. Для этого в файл /etc/sysctl.conf добавим строки:

#MiniDLNA warning fix
fs.inotify.max_user_watches = 100000

Вручную редактором:

sudo nano /etc/sysctl.conf

Или копипастом команды:

sudo sh -c 'printf "\n\n#MiniDLNA warning fix\nfs.inotify.max_user_watches = 100000\n" >> /etc/sysctl.conf && cat /etc/sysctl.conf'

Изменение параметра вступит в силу после перезагрузки системы.

Открываем в браузере http://адрес.сервера:8200, видим количество файлов в библиотеке, начиная с версии 1.1.2, также отображается список подключенных клиентов.

Настройка DLNA/UPnP-AV сервера завершена.

Если вместо сообщений и папок-контейнеров MiniDLNA отображаются знаки вопроса, отключаем локализацию.

Если был установлен пакет:

sudo mv /usr/share/locale/ru/LC_MESSAGES/minidlna.mo minidlna.mo.del

При установке из исходников:

sudo mv /usr/local/share/locale/ru/LC_MESSAGES/minidlna.mo minidlna.mo.del

Перезапускаем MiniDLNA с повторным сканированием библиотеки:

sudo service minidlna force-reload

Сканирование медиа-библиотеки MiniDLNA

При появлении ошибок в каталоге, необходимо выполнить повторное сканирование файлов.

При использовании приведенного выше init-скрипта, для запуска сканирования медиа-библиотеки используем команду:

sudo service minidlna force-reload

Служба при этом будет перезапущена, подключенные клиенты будут отключены.

В системах на базе systemd указанная выше команда больше не работает. Простейшим способом обновления библиотеки остается ручное удаление базы данных и перезапуск службы:

sudo rm /var/lib/minidlna/files.db
sudo systemctl restart minidlna

Для сканирования медиа-библиотеки при каждом старте системы можно задать ключ запуска: "-R" в параметре DAEMON_OPTS в файле /etc/default/minidlna. Сканирование большой медиа-библиотеки существенно нагружает диск, что может замедлить загрузку системы.

Полное формирование каталога может занять несколько минут. Сканирование папок выполняется в порядке их объявления в конфиге. Файлы из небольших папок, объявленных в конфиге выше, появятся в каталоге в самом начале процесса сканирования. Крупные папки с редко воспроизводимым контентом имеет смысл размещать в конфиге последними.

Отключение запроса способа отображения файлов: All Files, Folders

Настраиваем отображение содержимого папок Music, Pictures, Video без промежуточного запроса способа их отображения.

Частично вопрос можно решить установкой параметра: "root_container=B" в minidlna.conf. При этом сам запрос не отключается, но содержимое папок отображается непосредственно в корневом контейнере.

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

Отключение виртуальных папок в MiniDLNA версии 1.1.4 и выше

Для версии 1.1.4 применяем патч, и добавляем параметр disable_extended_directories=yes в minidlna.conf. Данный патч войдет в состав следующей версии MiniDLNA, для более поздних версий достаточно задать параметр в файле конфигурации.

Получаем и устанавливаем пакет с исходниками, как описано в разделе: "Установка или обновление MiniDLNA из исходников".

Переходим в папку с исходниками:

cd ~/src/minidlna/minidlna-1.1.4

Загружаем и применяем патч:

wget http://sourceforge.net/p/minidlna/feature-requests/101/attachment/diff.dif
patch < diff.diff

Собираем и устанавливаем исправленную версию:

sudo make install

Редактируем файл конфигурации:

sudo nano /etc/minidlna.conf

Добавляем параметр:

# Отключить виртуальные папки
disable_extended_directories=yes

Перезапускаем службу с повторным сканированием медиа-библиотеки:

sudo service minidlna force-reload

В системах на базе systemd для повторного сканирования потребуется удалить базу данных вручную:

sudo rm /var/lib/minidlna/files.db
sudo systemctl restart minidlna

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

Отключение виртуальных папок в MiniDLNA версии 1.1.3 и ниже

Получаем и устанавливаем пакет с исходниками, как описано в разделе: "Установка или обновление MiniDLNA из исходников".

Переходим в папку с исходниками:

cd ~/src/minidlna/minidlna-1.1.3

Необходимые константы идентификаторов папок объявлены в scanner.h

#define MUSIC_ID                "1"
#define MUSIC_ALL_ID            "1$4"
#define MUSIC_GENRE_ID          "1$5"
#define MUSIC_ARTIST_ID         "1$6"
#define MUSIC_ALBUM_ID          "1$7"
#define MUSIC_PLIST_ID          "1$F"
#define MUSIC_DIR_ID            "1$14"
#define MUSIC_CONTRIB_ARTIST_ID "1$100"
#define MUSIC_ALBUM_ARTIST_ID   "1$107"
#define MUSIC_COMPOSER_ID       "1$108"
#define MUSIC_RATING_ID         "1$101"

#define VIDEO_ID                "2"
#define VIDEO_ALL_ID            "2$8"
#define VIDEO_GENRE_ID          "2$9"
#define VIDEO_ACTOR_ID          "2$A"
#define VIDEO_SERIES_ID         "2$E"
#define VIDEO_PLIST_ID          "2$10"
#define VIDEO_DIR_ID            "2$15"
#define VIDEO_RATING_ID         "2$200"

#define IMAGE_ID                "3"
#define IMAGE_ALL_ID            "3$B"
#define IMAGE_DATE_ID           "3$C"
#define IMAGE_ALBUM_ID          "3$D"
#define IMAGE_CAMERA_ID         "3$D2" // PlaysForSure == Keyword
#define IMAGE_PLIST_ID          "3$11"
#define IMAGE_DIR_ID            "3$16"
#define IMAGE_RATING_ID         "3$300"

Нам необходимо при запросе папок MUSIC_ID, VIDEO_ID и IMAGE_ID, перенаправить клиента в MUSIC_DIR_ID, VIDEO_DIR_ID и IMAGE_DIR_ID соответственно.

Обработка запросов клиента реализована в файле upnpsoap.c.

Сохраняем резервную копию файла:

cp upnpsoap.c upnpsoap.c.old

Запускаем редактор:

nano upnpsoap.c

Активируем поиск (F6), ищем процедуру: "BrowseContentDirectory".

static void
BrowseContentDirectory(struct upnphttp * h, const char * action)
{

В начале процедуры выполняется разбор SOAP/XML-запроса, затем его обработка и возврат результата.

Разбор запроса завершается формированием отладочного сообщения:

	DPRINTF(E_DEBUG, L_HTTP, "Browsing ContentDirectory:\n"
			 " * ObjectID: %s\n"
			 " * Count: %d\n"
			 " * StartingIndex: %d\n"
			 " * BrowseFlag: %s\n"
			 " * Filter: %s\n"
			 " * SortCriteria: %s\n",
			ObjectID, RequestedCount, StartingIndex,
			BrowseFlag, Filter, SortCriteria);

Далее реализован выбор корневого контейнера в зависимости от конфигурационного параметра root_container:

	// Если запрошен корневой контейнер
	if( strcmp(ObjectID, "0") == 0 )
	{
		// Выставляем флаг корневого контейнера
		args.flags |= FLAG_ROOT_CONTAINER;
		// Если в конфиге задан корневой контейнер
		if( runtime_vars.root_container )
		{
			// Если клиентом является аудио плейер и в конфиге задан обзор папок
			// Отправляем его в папку с музыкой
			if( (args.flags & FLAG_AUDIO_ONLY) && (strcmp(runtime_vars.root_container, BROWSEDIR_ID) == 0) )
				ObjectID = MUSIC_DIR_ID;
			else // Иначе выставляем контейнер, заданный в конфиге
				ObjectID = runtime_vars.root_container;
		}
		else // Если контейнер в конфиге не задан
		{
			// Если клиентом является аудио плейер
			// Отправляем его в папку с музыкой
			if( args.flags & FLAG_AUDIO_ONLY )
				ObjectID = MUSIC_ID;
		}
	}

Сразу после этого блока и перед блоком с запросами к БД добавляем код перенаправления папок для видео, музыки и изображений:

	//Redirect video to folder
	if( strcmp(ObjectID, VIDEO_ID) == 0 )
	{
		ObjectID = VIDEO_DIR_ID;
	}

	//Redirect music to folder
	if( strcmp(ObjectID, MUSIC_ID) == 0 )
	{
		ObjectID = MUSIC_DIR_ID;
	}

	//Redirect images to folder
	if( strcmp(ObjectID, IMAGE_ID) == 0 )
	{
		ObjectID = IMAGE_DIR_ID;
	}

В итоге правленный фрагмент должен выглядеть следующим образом:

        if( strcmp(ObjectID, "0") == 0 )
        {
                args.flags |= FLAG_ROOT_CONTAINER;
                if( runtime_vars.root_container )
                {
                        if( (args.flags & FLAG_AUDIO_ONLY) && (strcmp(runtime_vars.root_containe$
                                ObjectID = MUSIC_DIR_ID;
                        else
                                ObjectID = runtime_vars.root_container;
                }
                else
                {
                        if( args.flags & FLAG_AUDIO_ONLY )
                                ObjectID = MUSIC_ID;
                }
        }

        //Redirect video to folder
        if( strcmp(ObjectID, VIDEO_ID) == 0 )
        {
                ObjectID = VIDEO_DIR_ID;
        }

        //Redirect music to folder
        if( strcmp(ObjectID, MUSIC_ID) == 0 )
        {
                ObjectID = MUSIC_DIR_ID;
        }

        //Redirect images to folder
        if( strcmp(ObjectID, IMAGE_ID) == 0 )
        {
                ObjectID = IMAGE_DIR_ID;
        }

        if( strcmp(BrowseFlag+6, "Metadata") == 0 )
        {
                args.requested = 1;
                sql = sqlite3_mprintf("SELECT %s, " COLUMNS
                                      "from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID$
                                      " where OBJECT_ID = '%q';",
                                      (args.flags & FLAG_ROOT_CONTAINER) ? "0, -1" : "o.OBJECT_I$
                                      ObjectID);
                ret = sqlite3_exec(db, sql, callback, (void *) &args, &zErrMsg);
                totalMatches = args.returned;
        }

Собираем и устанавливаем исправленную версию:

sudo make install

Перезапускаем службу:

sudo service minidlna restart

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

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

RSS
  • Александр
    08.04.2016 16:36
    Добрый день. Проблема заключается в том, что при загрузке системы(всегда) или при перезапуске минидлна(не всегда) в библиотеке нет файлов, хотя они там присутствуют. в логе отсутствует "сканирование" при запуске сервиса(как я понял при добавлении опции DAEMON_OPTS="-R" происходит сканирование при запуске). какие-либо ошибки в логе также отсутствуют. force-reload не помогает. inotify включено, период сделал 30 сек. заметил, сканирование происходит только в случае изменения содержания библиотеки(как я понимаю это срабатывает как раз inotify)
    • Александр
      08.04.2016 22:19
      проблема была в том, что нужно было прописать в fstab раздел с библиотекой. он у меня в ntfs. как я понял, он монтируется только при первом обращении к нему.
  • Сергей
    25.02.2016 09:54
    Нужна помощь!
    Вроде как поднял на centose minidlna.
    На другом компьютере вижу в "сети" данный медиа ресурс! Пытаюсь в него войти что бы загрузить в него файлы, аон меня кидает в браузер по ip адерса сервера. Собственно вопрос как загружать файлы с стороннего компютора?
    • IT Adept
      25.02.2016 11:15
      Загрузка файлов протоколом не предусмотрена.

      Используйте SMB/CIFS, NFS, WebDAV или FTP.

      DLNA-протокол необходим преимущественно для просмотра фильмов на телевизоре.
  • Александр
    27.12.2015 19:01
    Нид хэлп :)
    Инотифи включен
    интервал обновлений 600
    но изменения ( новые видео ) в папке появляются только после форсе-релоад :(

    в вар\лог\минидлна данные пишутся только после перезапуска
    или если удалить файлик видео, и попробовать его через поток посмотреть, тогда пишет в лог, что файл не найден.
    по всей видимости инотифи не отрабатывает при изменении содержания каталогов :( куда копнуть не знаю уже :(
    • IT Adept
      27.12.2015 20:42
      Никогда не сталкивался с подобной проблемой. Но подобная жалоба не первая.

      У меня Inotify работал исправно на Debian 6, далее на Debian 7, теперь перешел на Gentoo, и тут никаких проблем. Кроме глюка с переименованиями.

      Какой дистрибутив используете? Какая версия дистрибутива? На какой файловой системе хранятся медиа-файлы? Попробую затестить на виртуальной машине.
      • Александр
        28.12.2015 00:24
        странность заметил
        на серваке ubuntu 14.04 - на нем не пашет
        развернул на d-link dns327l - на нем все пашет.
        на шарацентре
        [root@sharecenter /]# cat /proc/version
        Linux version 3.2.40 (nelson@LinuxNas) (gcc version 4.6.4 (Linaro GCC branch-4.6.4. Marvell GCC Dev 201310-2126.3d181f66 64K MAXPAGESIZE ALIGN) ) #1 Wed Apr 22 14:57:45 CST 2015


        Изменил содержание каталога, при этом заглянул в лог на шарацентре.
        в логе ничего не появилось. А при веб просмотре состояния длна сервака X.X.X.X:8200
        количество файлов уменьшилось. Значит длна отслеживает состояние.

        Блин, всю голову уже сломал куда копать.
        • Александр
          28.12.2015 01:02
          Такое ощущение что inotify просто не работает
          • IT Adept
            28.12.2015 23:56
            Проверил в виртуалке на чистой Ubuntu 14.04 Server.

            Inontify работает, проблемы не вижу.

            Ищите маны по настройке и тестированию inotify. Проверьте, работает ли inotify в других программах.

            Поставьте в виртуалку чистую систему и MiniDLNA, затем переносите настройки с рабочего сервера, ищите, после каких изменений возникает проблема.
            • Александр
              29.12.2015 11:42
              давно руки чесались снести все нафиг и настроить заного
              на выхах займусь
              и поставлю минидлна 1.1.4
              • Александр
                07.01.2016 00:59
                Вообщем разобрался вроде с ситуевиной :)
                начал подробно читать как и что делает inotify
                Вообщем данная плюшка вшита в ядро, а минидлна считывает события которые произошли в интересных ей папках.
                У меня оно не работало потому, что мой сервак юзал сетевой NAS как монтированные диски, на NASe работал трансмишон, который качал фильмы.
                Получается трансмишон скачивал файлы, размещал их в папочке, НО система основного сервака ничего не знала об изменениях на дисках, так как эти изменения делала другая система.
                Сейчас сделал папочку в родной системе, перекинул трансмишон на основной сервак, закачал пару фильмов, и вуаля, инотифи отработало, фильм появился в списке тут же
                вообщем надо либо научиться инотифи отслеживать изменения на подмонтированных папках, либо заюзать единую систему. :)

                надо подумать как мне лучше сделать :)
                • Александр
                  07.01.2016 01:31
                  Кстати, на репах есть новая версия 1.1.5
                  Сайчас так же нашел там славный патчик - который делает картинки превью к фильмам лежащим в папке
                  • IT Adept
                    07.01.2016 15:36
                    Рациональнее разместить DLNA-сервер непосредственно на NASе, чтоб дважды данные по сети не перекачивать.

                    С Inotify на сетевых дисках, подключенных через CIFS, есть проблема в ядре Linux. Изменения на сетевом диске не отслеживаются. Отслеживаются только локальные изменения внутри одной системы.

                    Вместо CIFS можно попробовать использовать NFS или WebDAV протоколы. Как там обстоят дела с Inotify я не проверял, но вроде как пишут, что ограниченная поддержка Inotify имеется.


                    MiniDLNA 1.1.5 стоит у меня с октября. Работает без проблем. Статья вполне актуальная. Волшебные папки впрочем штатно в конфиге так и не отключаются, приходится как и раньше патчить вручную.
                    • Александр
                      08.01.2016 13:43
                      На NASe есть небольшие подтормозки в процессе просмотра видео с хорошим разрешением. Так как проц там не для этого все таки. Я фильмы смотрю на проекторе, и это очень ощутимо заметно на большом экране. Поэтому все перенес на сервак. Там проблем с потоком не обнаружено.
                      Собственно по этому проблемы с монтированием отпадают. На NASe буду фотки хранить :)

                      по поводу папок да, жаль то без бубна не допиливается. При этом на репах иногда чтоб получить патчик на нужную версию приходится в диспут вступить. Потому что выложен патчик один, а потом выясняется, что он к новой версии не идет. Атачат в теле переписки нужный. Очень печально.
  • Максим
    11.06.2015 14:32
    minidlna.c:367: fatal: Failed to clean old file cache! Exiting...
    Что бы это могло значить? Minidlna запускается только через команду "minidlna -d -f /conf/minidlna.conf" при этом не оставляя никаких записей в логе, запуск же из автозагрузки и через команды "sudo service minidlna force-reload" и
    "sudo systemctl restart minidlna" приводит к такой записи в логе, соответственно minidlna не запускается. Удаление БД и Art_cache не помогло
    • IT Adept
      11.06.2015 23:25

      Смотрим фрагмент кода minidlna.c, в районе строки 367:

      snprintf(cmd, sizeof(cmd), "rm -rf %s/files.db %s/art_cache", db_path, db_path);
      if (system(cmd) != 0)
          DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache!  Exiting...\n");
      

      Ошибка возникает при попытке удаления базы медиа-библиотеки и кэша обложек.

      Проверьте владельца папки /var/lib/minidlna и ее файлов:

      ls -ld /var/lib/minidlna
      ls -l /var/lib/minidlna
      

      Результат должен быть:

      drwxr-xr-x 2 minidlna minidlna 4096 июн  6 00:05 /var/lib/minidlna
      -rw-r--r-- 1 minidlna minidlna 77824 июн 12 01:17 files.db
      

      Задайте владельца папки:

      sudo chown -R minidlna:minidlna /var/lib/minidlna
      
      • Максим
        13.06.2015 22:16
        Спасибо. Проблема возникла после перехода на ubuntu 15.04 и установки пакета из исходников, решил ее с помощью установки через "sudo apt-get install minidlna". Теперь все работает как на 14.10 за исключением того, что запуск minidlna начинается со сканирования всех папок, запись в логе "warn: New media_dir detected; rescanning...", в прошлой версии при запуске база данных уже была видна, не терялось время на сканирование
  • Павел
    03.02.2015 11:05
    Подскажите, есть в настройках возможность указания частоты обновления библиотеки? Все работает хорошо, но чтоб minidlna увидела новую папку, приходится перегружать комп
    • IT Adept
      03.02.2015 13:41

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

      В minidlna.conf для включения и отключения inotify имеется одноименный параметр, включенный по умолчанию:

      inotify=yes

      У меня отслеживание новых и удаленных папок работает четко. Но при переименовании не редко возникает дублирование записей в библиотеке, приходится сбрасывать базу вручную.

      • Павел
        30.03.2015 11:29
        Увы, inotify запущен - с помощью inotifywait отслеживаю изменения ФС, но вот minidlna автоматически библиотеку не обновляет
        • Va-Bank
          09.04.2015 16:13
          У меня был косяк с minidlna, когда в библиотеке были пустые папки. Пример:
          Video/Комедии/фильм1.mkv
          Video/Комедии/фильм2.mkv
          Video/Боевики/фильм1.mkv

          Если удалить, например, фильм1.mkv из папки "Боевики", то minidlna перестает видеть эту папку. Будет видно только папку "Комедии". И даже если записать в эту папку фильмы, то minidlna уже их не прочитает. Приходится вручную сбрасывать базу. Поэтому я не довожу до такого состояния. Вначале пишу новый фильм, потом удаляю старый.

          А вообще у меня на библиотеку натравлен transmission, у которого включена опция incomplete-dir. Закачка идет в папку "Incomplete", которая изначально за пределами библиотеки для minidlna. Затем когда трансмишн полностью скачивает фильм, то он его переносит в нужную папку библиотеки. Minidlna тут же его видит. Никаких проблем.
  • Pascal
    28.11.2014 17:46
    Комрады, подскажите. У меня проблема с запоминанием последнего места воспроизведения на ТВ в связке с minidlna сервером. Мучаюсь уже неделю, не могу найти решения. Использую minidlna 1.1.3 установленный через репозиторий Entware с телевизором Samsung UE46F8000.
    • IT Adept
      28.11.2014 21:31

      Проблема с закладками на телевизорах Samsung появилось в версии 1.1.3 и не исправлена в 1.1.4, баг-репорт.

      Установите версию 1.1.2.

      Или соберите из исходников актуальную версию, скорректировав файл clients.c. В строке 69 добавьте флаг FLAG_SAMSUNG_DCM10:

       	/* User-Agent: DLNADOC/1.50 SEC_HHP_[TV]UE40D7000/1.0 */
       	/* User-Agent: DLNADOC/1.50 SEC_HHP_ Family TV/1.0 */
       	{ ESamsungSeriesCDE,
      	  FLAG_SAMSUNG | FLAG_DLNA | FLAG_NO_RESIZE | FLAG_SAMSUNG_DCM10,
      	  "Samsung Series [CDEF]",
       	  "SEC_HHP_",
       	  EUserAgent
       	},
      
  • Алексей
    16.11.2014 14:58
    Может кто знает, как пакет создать для debian из исходника, чтоб каждый раз не компилировать? И сестему обновлять будет легче.
    • IT Adept
      16.11.2014 20:54

      Создать deb-пакет, установить и зарегистрировать его в системе можно с помощью CheckInstall.

      Устанавливаем CheckInstall:

      sudo apt-get install checkinstall
      

      Переходим в папку с исходниками MiniDLNA и выполняем установку, в параметрах указываем зависимости:

      sudo checkinstall --requires=libavcodec-dev,libavformat-dev,libavutil-dev,libexif-dev,libflac-dev,libid3tag0-dev,libjpeg-dev,libogg-dev,libsqlite3-dev,libvorbis-dev
      
  • Александр
    12.11.2014 21:11
    Ребят,такой вопрос. Хочу смотреть стримы с Twitch.tv через DLNA на телевизоре. Подгружаю видео через Livestreamer в каталог видимый для minidlna, но пока не выключить Livestreamer на телевизоре файла не видно. Как поправить или может какой-то другой софт использовать для таких целей?
  • Андрей
    05.11.2014 15:47
    Добрый день

    После установки из исходников 1.1.4 (перед этим стояла 1.1.3) появились проблемы с кодировкой на Smart TV: названия системных папок (в роде Все Видео) начали отображаться вопросами. Возможно, конечно, что это также произошло после апгрейда OMV на 7 Debian. Явных настроек кодировки я в miniDLNA не нашел. Может, кто-то сталкивался?
    • IT Adept
      05.11.2014 16:39
      Собрал у себя 1.1.4 в Debian 7. Проблем с кодировкой не наблюдаю.

      Системные папки у меня на английском отображаются (All Files, Folders, Recently Added).
      • Андрей
        06.11.2014 12:45
        У меня, судя по всему, они отражаются на русском и в неправильной кодировке. Не подскажете, где можно поменять локаль miniDLNA?
        • IT Adept
          07.11.2014 17:33

          В качестве быстрого решения можно переименовать файл с русской локализацией:

          sudo mv /usr/local/share/locale/ru/LC_MESSAGES/minidlna.mo minidlna.mo.bak
          sudo service minidlna force-reload
          

          Вопрос требует дополнительного изучения, позже напишу о результатах.

  • Андрей
    04.07.2014 15:59
    Еще один момент: что будет нужно сделать, чтобы обновиться на более свежую версию из тех же исходников?
    • IT Adept
      05.07.2014 00:25

      Обновление практически не отличается от первичной установки.

      Загружаем свежие исходники, компилируем.

      Но перед установкой, рекомендуется удалить старую версию.

      Для этого переходим в папку с исходниками установленной версии и выполняем команду:

      sudo make uninstall
      

      Затем устанавливаем новую версию.

      Впрочем, можно установить новую версию поверх старой, без деинсталляции. Работать будет в любом случае.

      Но если в новой версии изменится состав установочных файлов, в иерархии /usr/local могут остаться устаревшие файлы.

      • Андрей
        05.07.2014 08:15
        Благодарю за объяснение. Я так понимаю, что при этом все скрипты и конфиги сохранятся и по-новому их создавать не придется.
        • IT Adept
          05.07.2014 15:22
          Файлы, созданные вручную, включая init-скрипт и minidlna.conf, процедурой установки и удаления не затрагиваются.
  • Андрей
    01.07.2014 14:40
    Добрый день

    Пользуюсь OpenMediaVault, проблема с местным minidlna версии 1.0.25 заключалась в том, что minidlna успешно сканировал все фотографии и аудиофайлы, но не видел где-то половину видеофайлов. То есть с каждым стартом он просто обновлял библиотеку, но сканировал в нее, скажем, 500 файлов из 1000. Причем если найти папку, которую он пропустил, и поменять ей имя - она появлялась в библиотеке до следующего рестарта. Собрал по инструкции последний релиз - проблема та же. В логах о видео нет ничего. Доступ к папка у него есть
    • IT Adept
      01.07.2014 21:37

      Попробуйте повысить детальность лога сканирования до уровня info или debug в minidlna.conf:

      log_level=general,artwork,database,inotify,scanner,metadata,info,ssdp,tivo=warn,scanner=info
      

      Выполните повторное сканирование медиа-файлов:

      service minidlna force-reload
      

      Проверьте сообщения в лог-файле. Возможно удастся локализовать проблему.

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

      Один раз, давно была подобная проблема, деталей уже не помню. Решил удалением проблемного файла.

      • Андрей
        01.07.2014 23:01
        Спасибо, буду пробовать. Интересно то, что в папке Video, в которой и находятся видеофайлы, и папки, и файлы, сканируются до буквы O включительно. То есть ниже O в латинице и вся кириллица не сканируются. Касается только видеофайлов.
        • IT Adept
          01.07.2014 23:22
          Вот на латинской букве O в папке с видео где-то и спотыкается.

          Очень походит на мою проблему.

          Если в логе, в режиме info, сканирование закончится без ошибок на букве O, переместите последний отсканированный файл в логе и следующий за ним по алфавиту файл или папку и повторите сканирование.
          • Андрей
            03.07.2014 13:54
            Так и оказалось. В одной из папок лежали *.mp4 файлы, которые сервер не мог переварить и останавливался. Вообще поведение, как по мне, несколько странное. Логично было, чтобы он пропускал, что не может съесть, и шел дальше
            • IT Adept
              03.07.2014 17:54
              У меня mp4 крутит без проблем. В основном ролики с Ютьюба, но есть и пара сериалов.

              Вероятно, возникает необрабатываемая ошибка при чтении метаданных из битого файла в сторонней библиотеке. В результате завершается процесс сканирования.
              • Андрей
                03.07.2014 18:12
                Да, это все были mp4 из одного источника (webrip, не youtube). Есть и другие, но они сканируются
  • Михаил
    05.05.2014 15:12
    Я прошу прощения у меня вот такая ошибка:
    Во время "sudo make clean install":

    .
    CC misc.o
    CC tagutils.o
    CC playlist.o
    CC image_utils.o
    CC albumart.o
    CC log.o
    CCLD minidlnad
    sed -e s@:SBINDIR:@/usr/local/sbin@ linux/minidlna.init.d.script
    make[2]: Вход в каталог `/home/mediaserver/src/minidlna/minidlna-1.1.2'
    test -z "/usr/local/sbin" || /bin/mkdir -p "/usr/local/sbin"
    /usr/bin/install -c minidlnad '/usr/local/sbin'
    make[2]: Цель `install-data-am' не требует выполнения команд.
    make[2]: Выход из каталога `/home/mediaserver/src/minidlna/minidlna-1.1.2'
    make[1]: Выход из каталога `/home/mediaserver/src/minidlna/minidlna-1.1.2'
    mediaserver@mediaserver:~/src/minidlna/minidlna-1.1.2$


    Из репозитория DAEMOIN Minidlna прописывается в /usr/bin/minidlna а не в /usr/local/bin
    Я извиняюсь, в этом деле нуб. Подскажите пожалуйста что нужно исправить чтобы скомпилить без ошибки. Спасибо огромное!
    • IT Adept
      05.05.2014 16:03
      Сборка и установка проходит успешно.

      Программы собранные вручную, обычно устанавливаются /usr/local/, это нормально.

      Необходимо скорректировать путь и имя файла службы в init-скрипте. Читаем раздел Установка. Строки, которые необходимо исправить, выделены красным.
      • Михаил
        05.05.2014 21:32
        Благодарю Вас. Всё получилось, спасибо огромное, это бесценный опыт. Желаю развития вашему ресурсу.
  • Михаил
    04.05.2014 14:23
    С первого раза не удалось собрать и установить из исходников с патчем "Отключение запроса способа отображения файлов: All Files, Folders"

    Minidlna вроде собрался и запустился, но патч не заработал.
    • IT Adept
      04.05.2014 16:55

      Себе собирал по той же схеме, патч рабочий, версия 1.1.2.

      Скорректируйте уведомление о старте в minidlna.c, строка: 1000. После номера версии, добавьте: "-Folders":

      DPRINTF(E_WARN, L_GENERAL, "Starting " SERVER_NAME " version " MINIDLNA_VERSION "-Folders.\n");
      

      Выполните:

      sudo make clean install
      

      Перезапустите службу:

      sudo service minidlna restart
      

      Проверьте, изменилось ли уведомление о старте в лог-файле:

      cat /var/log/minidlna.log
      

      Если установка прошла успешно, уведомление должно быть следующим:

      [2014/05/04 18:53:08] minidlna.c:1000: warn: Starting MiniDLNA version 1.1.2-Folders.
      

Ваш комментарий:


Вы не бот: