Linux Mint 17 и DLNA
Зачем это все надо
Linux Mint — отличная домашняя ОС. Богатый выбор графических сред на любой вкус, простая и понятная даже новичку установка, сразу после установки имеем основной набор необходимого софта, удобный менеджер приложений, основные мультимедийные кодеки. В общем, отличная система для перехода и ознакомления с Linux.
Но возникает проблема для тех, у кого нет дома NAS или чего-то подобного, а смотреть контент с ПК на других устройствах, поддерживающих DLNA хочется. Под Linux существует множество различных DLNA-серверов, но оптимальным, все же, является MiniDLNA. И тому есть несколько причин. Во-первых, это типичный Unix-way: этот сервер является именно DLNA-сервером, а не комбайном с кучей свистелок, при этом контент без проблем воспринимается на любом устройстве. Даже телевизоры Samsung со своим AllShare прекрасно подключаются к нему. Также можно отметить и замечательную скорость работы и нетребовательность к ресурсам этого сервера.
И все бы было хорошо, но вот в с помощью команды
sudo apt-get install minidlna
установить его не получится — нет его в репозитарии.
Существуют разные варианты устранения этого недоразумения, но самый правильный путь — установка из исходников.
Чтобы не отвратить возможных новоиспеченных линуксоидов с этого пути и, возможно, помочь кому-то, напишу как обойти подводные камни, ибо информации много, но в начале пути людям нужно попроще.
Подготовка
Если будете выполнять команды в консоли, запущенной с правами root, команду sudo писать не нужно.
Для начала нужно установить необходимые библиотеки:
Обновляемся:
sudo apt-get update
И устанавливаем сами библиотеки:
sudo apt-get install libavcodec-dev libavformat-dev libavutil-dev libflac-dev libvorbis-dev libogg-dev libid3tag0-dev libexif-dev libjpeg-dev libsqlite3-dev
Самая свежая версия MiniDLNA на данный момент — 1.1.3, ее можно скачать здесь, либо загрузить из консоли:
wget --trust-server-names http://sourceforge.net/projects/minidlna/files/latest/download
ключ перед адресом нужен, чтобы сохранилось оригинальное имя, с выхдом новой версии имя файла будет отличатся. После этого архив нужно распаковать:
tar -xf minidlna-1.1.3.tar.gz
Теперь перейдем в распакованную папку с исходниками
cd minidlna-1.1.3
Если вы хотите, чтобы на устройстве отображались сразу папки с файлами, нужно немного подправить код:
Открывайте спойлер
Для отключения запроса способа отображения файлов нужно в папке с исходниками (minidlna-1.1.3, мы в нее уже должны были перейти) подправить файл upnpsoap.c, но сначала сделаем его резервную копию:
sudo cp upnpsoap.c upnpsoap.c.old
и откроем в редакторе
sudo 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;
}
}
Сразу после этого блока и перед блоком с запросами к БД добавляем код перенаправления папок для видео, музыки и изображений:
if( strcmp(ObjectID, VIDEO_ID) == 0 )
{
ObjectID = VIDEO_DIR_ID;
}
if( strcmp(ObjectID, MUSIC_ID) == 0 )
{
ObjectID = MUSIC_DIR_ID;
}
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;
}
Чтобы упростить процедуру последующего обновления, сохраним патч с внесенными изменениями:
diff -u upnpsoap.c.old upnpsoap.c > ../minidlna-folders.patch
Теперь вместо редактирования файла, достаточно применить патч:
cd ~/src/minidlna/minidlna-НоваяВерсия
patch < ../minidlna-folders.patch
Теперь можно переходить к конфигурированию.
Если вам это не нужно, переходите сразу к конфигурированию:
./configure
И компилируем:
make
Установка
1) Для тех, кто в дальнейшем захочет обновить версию, предыдущую можно удалить (конфигурационные файлы при этом сохраняются), если этого не сделать, то в случае, если в новой версии состав установочных файлов изменится, в /usr/local могут остаться старые файлы, при первой установке — переходим сразу к пункту 2.
Для удаления заходим в папку с предыдущей установкой и выполняем команду:
sudo apt-get remove minidlna
2) Запускаем установку (в комментариях предложили более правильный путь, чем make install):
sudo checkinstall -D
Ключ -D указывает, что должен быть создан Debian-пакет
3)Если мы производим первоначальную установку, нужно создать init-скрипт:
sudo nano /etc/init.d/minidlna
, если мы обновляем версию, больше ничего делать не нужно, при первоначальной установке у нас откроется пустой файл, в который нужно внести следующий код:
Листинг
#!/bin/sh
unset USER
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="DLNA/UPnP-AV media server"
NAME=minidlnad
DAEMON=/usr/local/sbin/minidlnad
PIDDIR=/run/$NAME
PIDFILE=$PIDDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/minidlna
DEFAULT=/etc/default/minidlna
[ -x $DAEMON ] || exit 0
[ -r $DEFAULT ] && . $DEFAULT
. /lib/init/vars.sh
. /lib/lsb/init-functions
if [ "$START_DAEMON" != "yes" ] && [ "$1" != "stop" ]; then
log_warning_msg "$NAME: Not starting $DESC."
log_warning_msg "$NAME: Disabled in $DEFAULT."
exit 0
fi
if [ -z $CONFIGFILE ]; then
CONFIGFILE=/etc/minidlna.conf
fi
if [ -z $LOGFILE ]; then
LOGFILE=/var/log/minidlna.log
fi
if [ -z $USER ]; then
USER=minidlna
fi
if [ -z $GROUP ]; then
GROUP=$USER
fi
DAEMON_ARGS="-f $CONFIGFILE -P $PIDFILE $DAEMON_OPTS"
do_start()
{
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
}
do_stop()
{
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
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
DAEMON_ARGS="$DAEMON_ARGS -R"
fi
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;;
*) log_end_msg 1 ;;
esac
;;
*)
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:
, сохранить комбинацией клавиш Ctrl+O и выйти из редактора — Ctrl+X.
4) После этого даем права на запуск скрипта:
sudo chmod 755 /etc/init.d/minidlna
5) И активируем запуск init-скрипта:
sudo update-rc.d minidlna defaults
6) Так как по умолчанию служба запускается под пользователем minidlna, нам нужно создать соответствующую учетную запись:
sudo adduser --system --home /var/lib/minidlna --group --gecos "MiniDLNA server" minidlna
7) Правим файл конфигурации сервера:
sudo nano /etc/minidlna.conf
В нем нам нужно следующее содержимое (здесь подправлен интервал, с которым сервер себя анонсирует, так как не все телевизоры опрашивают сервер, также вам надо прописать путь к папке с медиа, к примеру так: «media_dir=V,/mnt/sdb6/Video/Alex/» в соответствующем разделе файла):
Листинг minidlna.conf
port=8200
media_dir=/var/lib/minidlna
db_dir=/var/lib/minidlna
log_dir=/var/log
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
notify_interval=30
serial=12345678
model_number=1
8)Затем проверяем параметры init-скрипта /etc/default/minidlna:
sudo nano /etc/default/minidlna
Обычно корректировка не требуется. Если файл отсутствует, при первичной установке из исходников, копируем листинг:
START_DAEMON="yes"
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
Запуск сервера
Запускаем:
sudo service minidlna force-reload
Проверяем, работает ли служба, также смотрим параметры запуска:
ps ax | grep minidlna
Проверяем, слушается ли порт:
sudo ss -4lnp | grep minidlna
Проверяем лог:
cat /var/log/minidlna.log
В случае успешного старта, лог должен быть примерно следующим:
Gothician gothician
[2014/07/27 10:05:31] minidlna.c:1014: warn: Starting MiniDLNA version 1.1.3.
[2014/07/27 10:05:31] minidlna.c:355: warn: Creating new database at /var/lib/minidlna/files.db
[2014/07/27 10:05:31] minidlna.c:1053: warn: HTTP listening on port 8200
[2014/07/27 10:05:31] scanner.c:706: warn: Scanning /var/lib/minidlna
[2014/07/27 10:05:31] scanner.c:793: warn: Scanning /var/lib/minidlna finished (0 files)!
[2014/07/27 10:05:31] playlist.c:125: warn: Parsing playlists...
[2014/07/27 10:05:31] playlist.c:259: warn: Finished parsing playlists.
[2014/08/03 09:25:35] minidlna.c:1053: warn: HTTP listening on port 8200
Если видим: «WARNING: Inotify max_user_watches [8192] is low.», необходимо увеличить число дескрипторов слежения inotify до 100 000. Для этого в файл /etc/sysctl.conf добавим строки:
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'
Изменение параметра вступит в силу после перезагрузки системы.
Открываем в браузере адрес.сервера:8200, видим количество файлов в библиотеке, начиная с версии 1.1.2, также отображается список подключенных клиентов.
Настройка DLNA/UPnP-AV сервера завершена.
При появлении ошибок в каталоге, необходимо выполнить повторное сканирование файлов.
При использовании приведенного выше init-скрипта, для запуска сканирования медиа-библиотеки используем команду:
sudo service minidlna force-reload
Служба при этом будет перезапущена, подключенные клиенты будут отключены.
Для сканирования медиа-библиотеки при каждом старте системы можно задать ключ запуска: "-R" в параметре DAEMON_OPTS в файле /etc/default/minidlna. Сканирование большой медиа-библиотеки существенно нагружает диск, что может замедлить загрузку системы.
Полное формирование каталога может занять несколько минут. Сканирование папок выполняется в порядке их объявления в конфиге. Файлы из небольших папок, объявленных в конфиге выше, появятся в каталоге в самом начале процесса сканирования. Крупные папки с редко воспроизводимым контентом имеет смысл размещать в конфиге последними.
Все это опробовано на своей системе, пользуйтесь на здоровье. Надеюсь, количество пользователей Linux будет постоянно увеличиваться.
По материалам http://itadept.ru/, wiki.archlinux.org.
http://habrahabr.ru/post/231653/
|