📜 ⬆️ ⬇️

Linux Mint 17 and DLNA

Why is all this necessary


Linux Mint is a great home OS. A rich selection of graphical environments for every taste, simple and clear installation even for a beginner, right after installation we have the basic set of necessary software, a convenient application manager, basic multimedia codecs. In general, a great system to go and get familiar with Linux.

image

But there is a problem for those who do not have a NAS at home or something similar, but you want to watch content from a PC on other devices that support DLNA. Under Linux, there are many different DLNA servers, but the MiniDLNA is still optimal . And there are several reasons for this. Firstly, this is a typical Unix-way: this server is a DLNA server, and not a combine with a bunch of whistles, and the content is easily perceived on any device. Even Samsung TVs with their AllShare connect perfectly to it. You can also note the remarkable speed and undemanding to the resources of this server.
')
And everything would be fine, but with the help of the command
sudo apt-get install minidlna
install it fails - it is not in the repository.

There are various options for eliminating this misunderstanding, but the most correct way is to install from source.
In order not to ward off possible new linuxoids from this path and, possibly, to help someone, I will write how to get around the pitfalls, because there is a lot of information, but in the beginning of the path people need to be simpler.

Training

If you execute commands in a console running as root, you do not need to write the sudo command.

First you need to install the necessary libraries:

Updating:

 sudo apt-get update 
And install the libraries themselves:
 sudo apt-get install libavcodec-dev libavformat-dev libavutil-dev libflac-dev libvorbis-dev libogg-dev libid3tag0-dev libexif-dev libjpeg-dev libsqlite3-dev 


The latest version of MiniDLNA is currently 1.1.3, it can be downloaded here or downloaded from the console:
 wget --trust-server-names http://sourceforge.net/projects/minidlna/files/latest/download 
The key in front of the address is needed in order to preserve the original name, with the release of the new version the file name will be different. After this, the archive must be unpacked:

 tar -xf minidlna-1.1.3.tar.gz 
Now let's move to the unpacked source folder.
 cd minidlna-1.1.3 


If you want the folders with files on the device to be displayed at once, you need to tweak the code a little
Open spoiler
To disable the request to display the files, you need in the source folder (minidlna-1.1.3, we already had to go to it) to correct the upnpsoap.c file, but first make a backup copy of it:

 sudo cp upnpsoap.c upnpsoap.c.old 
and open it in the editor
 sudo nano upnpsoap.c 
search (F6), look for the procedure:

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


At the beginning of the procedure, a SOAP / XML request is parsed, then processed and returned. Parsing the request ends with a debugging message:
 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); 


Further, the choice of the root container is implemented depending on the configuration parameter 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; } } 


Immediately after this block and before the block with queries to the database, add the folder redirection code for video, music and images:

  //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; } 
As a result, the correct fragment should look like this:
  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; } 


To simplify the procedure for the subsequent update, save the patch as amended:
 diff -u upnpsoap.c.old upnpsoap.c > ../minidlna-folders.patch 


Now, instead of editing the file, just apply the patch:

 cd ~/src/minidlna/minidlna- patch < ../minidlna-folders.patch 
Now you can proceed to the configuration.
If you do not need it, go straight to configuring:

 ./configure 


And compile:

 make 


Installation

1) For those who want to update the version in the future, the previous one can be deleted (configuration files are saved), if this is not done, then in the new version, the set of installation files will change, old files may remain in / usr / local , at the first installation - go directly to step 2.

To delete, go to the folder with the previous installation and execute the command:
 sudo apt-get remove minidlna 
2) Start the installation (in the comments suggested a more correct path than make install):

 sudo checkinstall -D 
The -D switch indicates that a Debian package should be created.

3) If we perform the initial installation, we need to create an init script:
 sudo nano /etc/init.d/minidlna 
, if we update the version, nothing else needs to be done, during the initial installation we will have an empty file in which we need to enter the following code:

Listing
 #!/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=minidlnad DAEMON=/usr/local/sbin/minidlnad PIDDIR=/run/$NAME PIDFILE=$PIDDIR/$NAME.pid SCRIPTNAME=/etc/init.d/minidlna DEFAULT=/etc/default/minidlna # 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 : 
, save the key combination Ctrl + O and exit the editor - Ctrl + X.

4) After that, we give rights to run the script:
 sudo chmod 755 /etc/init.d/minidlna 
5) And activate the launch of the init-script:
 sudo update-rc.d minidlna defaults 
6) Since by default the service runs under the user minidlna, we need to create an appropriate account:

 sudo adduser --system --home /var/lib/minidlna --group --gecos "MiniDLNA server" minidlna 
7) Rule the server configuration file:
 sudo nano /etc/minidlna.conf 
We need the following content in it (here the interval with which the server announces itself is corrected, since not all TVs interrogate the server, you also need to set the path to the media folder, for example: "media_dir = V, / mnt / sdb6 / Video / Alex / "in the appropriate section of the file):

Listing minidlna.conf
 #   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 #  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=30 #      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 
8) Then we check the parameters of the init-script / etc / default / minidlna:
 sudo nano /etc/default/minidlna 
Normally no adjustment is required. If the file is missing, during the initial installation from source, copy the listing:
 #  ,   "yes" START_DAEMON="yes" #     #CONFIGFILE="/etc/minidlna.conf" #   - #LOGFILE="/var/log/minidlna.log" #        #  : minidlna #USER="minidlna" #GROUP="minidlna" #    DAEMON_OPTS="" 
Usually, after this, no additional settings are required, but if there are problems with access to the media (or you want to be safe), you can configure access rights:

Setting permissions:
Since the service runs as a user with limited rights, the published folders and files must be readable by all users, therefore, they must have 644 permissions: "rw- r-- r--" for files and 755: "rwx rx rx", for folders.

Check availability for each folder specified in minidlna.conf with the command:
 sudo -u minidlna ls -l  
If the folder is not available, set the access rights:
 sudo chmod -R 755  
Parent folders should also be readable by all users. Check the readability of each folder specified in the path. For parent folders, we use chmod without the -R switch, unless you need to reset permissions for all child files and folders.
As an alternative to changing permissions, you can run MiniDLNA on behalf of a user or group that owns files. To do this, set the USER and GROUP parameters in / etc / default / minidlna, and change the owner of the / var / lib / minidlna folder with the command:
 sudo chown -R : /var/lib/minidlna 


Server startup

Run:

 sudo service minidlna force-reload 


We check if the service is working, we also look at the launch parameters:

 ps ax | grep minidlna 


Check if the port is listening:

 sudo ss -4lnp | grep minidlna 


Check the log:

 cat /var/log/minidlna.log 


In case of a successful start, the log should be approximately as follows:

 Gothician gothician # cat /var/log/minidlna.log [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 


If you see: “WARNING: Inotify max_user_watches [8192] is low.”, You need to increase the number of inotify tracking descriptors to 100,000. To do this, add the following lines to the /etc/sysctl.conf file:

 #MiniDLNA warning fix fs.inotify.max_user_watches = 100000 


Manually Editor:

 sudo nano /etc/sysctl.conf 


Or copy-paste commands:

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


Changing a parameter will take effect after a system reboot.
Open the address of the server in the browser: 8200, see the number of files in the library, starting with version 1.1.2, also displays a list of connected clients.

Setup of DLNA / UPnP-AV server is completed.

If errors occur in the directory, you need to re-scan the files.
When using the above init-script, to start scanning the media library, use the command:

 sudo service minidlna force-reload 


The service will be restarted while connected clients will be disconnected.

To scan the media library at each system startup, you can specify a startup key: "-R" in the DAEMON_OPTS parameter in the / etc / default / minidlna file. Scanning a large media library significantly loads the disk, which can slow down the system load.

The complete formation of the directory may take several minutes. Folders are scanned in the order they are declared in the config. Files from small folders declared in the config above will appear in the directory at the very beginning of the scanning process. It makes sense to place large folders with infrequently reproduced content in the config file last.

All this is tested on your system, use on health. Hopefully the number of Linux users will constantly increase.

According to materials http://itadept.ru/ , wiki.archlinux.org .

Source: https://habr.com/ru/post/231653/


All Articles