This is a detailed step by step to properly setup miniDLNA in a jail, patch the sources with custom icons, setup the media libraries and properly setup a service daemon script with a non destructive rescan
Enjoy
Enjoy
Code:
# ************************************************************* # Requirements on TrueNAS main system: # ************************************************************* # First, I assume the media library to stream is in TrueNAS main system under below datasets: # - /mnt/my_media/tank/family # - /mnt/my_media/tank/movies # - /mnt/my_media/tank/children # - /mnt/data/tank/shared # Note: the media datasets can be either unix or windows SMB shares # In TrueNAS main system, we have created a dedicated user "minidlna" UID 1008, member of a group "smb_dlna" GID 1019 # Note: choose the UID/GID that you like, but later, we will need to create the same user/group IDs in the jail # The group "smb_dlna" has read only permissions on each of the above media datasets under "/mnt/my_media/tank/" # For easier maintenance, I advise storing the minidlna catalog database and log files in a dataset outside of the jail directories # That way, when the jail is destroyed, the database catalog doesn't need to be rebuilt which is a time and resource consuming operation # I assume a UNIX type dataset under main TrueNAS system "/mnt/data/tank/common" # In TrueNAS GUI, create a user "dlna" UID 933, member of group "dlna" GID 933 # Note: you must use the 933 IDs, because these are the IDs created by default when installing minidlna # We can also use teh same minidlna user created previously, but I prefer distinct users for teh lib access and running the daemon # It is the user running the minidlna daemon # In shell, we create the database and log directories for minidlna root@truenas:~ # mkdir -p /mnt/data/tank/common/minidlna/db chown dlna:dlna /mnt/data/tank/common/minidlna/db chmod 755 /mnt/data/tank/common/minidlna/db # The log directory can be set to root:wheel mkdir -p /mnt/data/tank/common/minidlna/log chown root:wheel /mnt/data/tank/common/minidlna/log chmod 755 /mnt/data/tank/common/minidlna/log # ************************************************************* # First step: Setup a jail named "streaming": # ************************************************************* # - Create a jail in TrueNAS GUI # - Assign the network and IP on the subnet where your receiving devices reside # Note: DLNA multicast traffic is limited to teh same subnet/VLAN, so the jail and media clients must be on teh same subnet # Add the jail mount point for the database and logs rw /mnt/data/tank/common -> /mnt/data/iocage/jails/streaming/root/mnt/common # Add the jail mount point for the media library # Note: the media directories will be mounted under /media in jail ro /mnt/data/tank/family -> /mnt/data/iocage/jails/streaming/root/media/family ro /mnt/my_media/tank/movies -> /mnt/data/iocage/jails/streaming/root/media/movies ro /mnt/my_media/tank/shared -> /mnt/data/iocage/jails/streaming/root/media/shared ro /mnt/my_media/tank/children -> /mnt/data/iocage/jails/streaming/root/media/children # fstab result: root@truenas:~ # cat /mnt/data/iocage/jails/streaming/fstab /mnt/data/tank/common /mnt/data/iocage/jails/streaming/root/mnt/common nullfs rw 0 0 /mnt/data/tank/family /mnt/data/iocage/jails/streaming/root/media/family nullfs ro 0 0 /mnt/my_media/tank/movies /mnt/data/iocage/jails/streaming/root/media/movies nullfs ro 0 0 /mnt/my_media/tank/shared /mnt/data/iocage/jails/streaming/root/media/shared nullfs ro 0 0 /mnt/my_media/tank/children /mnt/data/iocage/jails/streaming/root/media/children nullfs ro 0 0 # ************************************************************* # Jail: Add user/group permissions for the minidlna service # ************************************************************* # In teh jail, we will add the group and user that will access the libraries # Note: as stated above, this is not necessarily the same user running the mindlnad daemon # - shell into the jail root@truenas:~ # iocage console streaming # - notes about setting up the group and user # + username must exist on both host and jail # + username must have read rights on the media library IN THE HOST, either explicitely, or through a group membership (primary or auxiliary) # + username must be added to the jail, with THE SAME UID as in the host # + if username does not have an explicit read access to the media library on the host, but rather through a group membership: # then, the group with read access must also be added on the jail, with the same gid as in the host # # NOTE: we can start minidlnad daemon as root and it will no more need the username setup in minidlna.conf or any host permissions # However, I do not recommend this for security reasons # # - create group "smb_dlna" with gid 1019 : it must exist on TrueNAS host AND have read access to each share we want to stream root@streaming:~ # pw groupadd smb_dlna -g 1019 # - create user "minidlna" uid 1008 : it must exist on TrueNAS host. # If user minidlna has no explicit read access in the host, the group "smb_dlna" must be either his primary or auxiliary group in the host # In the jail, we must make "smb_dlna" the PRIMARY group of user "minidlna" pw useradd minidlna -d /nonexistent -s /usr/sbin/nologin -u 1008 -g 1019 -c "MiniDLNA" # ************************************************************* # Install minidlna using pkg install # ************************************************************* # This is the recommended first step because it installs latest version with all dependencies # Note: we cannot patch the source to use custom icons in this method, so we do it later in next section # root@streaming:~ # pkg update pkg install minidlna # [Optional] Force update with patched version having a TrueNAS icon instead of the FreeBSD ugly bad guy icon ! # - copy my patched pkg file to the jail under for example /mnt/common root@streaming:/mnt/common # pkg add -f minidlna-1.3.0_2,1-custom-icon.pkg # ************************************************************* # [Optional] Compile minidlna from FreeBSD ports collection # ************************************************************* # If you want to compile yourself the patched minidlna pkg with a custom icon, follow this section, else skip it # We will use this method to create a custom binary pkg from ports collection source files # We will patch the ports collection sources to use a custom icon # Then, we will create a binary pkg from these patched latest sources # The created binary pkg can be used to update the currently installed minidlna version # Also, use this method if the ports collection has a newer version than pkg install # Download/Update the ports collection # - If it is the first time or we deleted the collections to spare space: root@streaming:~ # portsnap fetch && portsnap extract && portsnap update # - If it is already extracted and not removed, just update the collection: portsnap fetch update # Download and extract the minidlna latest port source files cd /usr/ports/net/minidlna/ root@streaming:/usr/ports/net/minidlna # make clean # if we previously installed without cleaning make patch BATCH=yes # Note: make patch will run automatically the below 3 commands: make fetch # fetches the distfile tarball make extract # extracts the distfile into the work directory make patch # applies any specific FreeBSD patches # The port source files should be now located under "/usr/ports/net/minidlna/work/minidlna-4f6a473/" # Note: replace minidlna-4f6a473 directory with current version name # Edit source files to support custom icons: # - get the patched icons.c and icons_custom.c files from my git: https://github.com/PhilZ-cwm6/minidlna-bsd # - copy teh patched files to /mnt/common in jail # - we replace the modded icons.c and icons_custom.c files cp /mnt/common/icons.c /mnt/common/icons_custom.c /usr/ports/net/minidlna/work/minidlna-4f6a473/ # - [OPTIONAL]: edit the icons_custom.c file if you want to select different custom icons # Just uncomment only one line and comment the others. MINIDLNA_COL is for a default coloured minidlna icon # As is, teh patched files will use a TrueNAS icon #define TRUENAS /* #define FREENAS */ /* #define FREENAS_3D */ /* #define MINIDLNA_COL */ # - [OPTIONAL]: edit the icons.c file to revert to default FreeBSD icon /* #define USE_CUSTOM_ICON true */ # Compile and install the patched minidlna port: # - to update an existing install: root@streaming:/usr/ports/net/minidlna # make reinstall BATCH=yes # - to install for first time: root@streaming:/usr/ports/net/minidlna # make install BATCH=yes # Create a pkg file for offline install on other jails # - this creates a pkg binary file from our patched ports collection source with custom icons root@streaming:/usr/ports/net/minidlna # make package # --> /usr/ports/net/minidlna/work/pkg/minidlna-1.3.0_2,1.pkg # Copy the created patched "minidlna-1.3.0_2,1.pkg" file to the streaming jail # [OPTIONAL] Remove and cleanup the ports files if needed root@streaming:/usr/ports/net/minidlna # make clean rm -v /var/db/portsnap/tag rm -rvf /var/db/portsnap/files rm -rvf /usr/ports/* # Now, update minidlna installation in streaming jail with the patched package # Note: we should already have did "pkg install minidlna" like above to install stock version with dependencies # -f: to force update existing package of same version root@streaming:~ # pkg add -f minidlna-1.3.0_2,1.pkg # ************************************************************* # Setup minidlna config and service to auto start with jail # ************************************************************* # Ensure that "dlna" user and group were added by installer # User "dlna" is the user running the minidlnad service. Database files need to be writable by the dlna user # It is not the same user we setup under minidlna.conf that is used to access the media libraries # # - user:group dlna:dlna (933:933) should be created by minidlna installer root@streaming:~ # cat /etc/passwd | grep dlna dlna:*:933:933:DLNA Daemon:/nonexistent:/usr/sbin/nologin minidlna:*:1008:1019:MiniDLNA:/nonexistent:/usr/sbin/nologin cat /etc/group | grep dlna dlna:*:933: smb_dlna:*:1019: # - [OPTIONAL]: if the user:group dlna:dlna were not created: # The defaults for freeBSD port are dlna:dlna uid 933 and gid 933 root@streaming:~ # pw groupadd dlna -g 933 pw useradd dlna -d /nonexistent -s /usr/sbin/nologin -u 933 -g 933 -c "DLNA Daemon" # Edit minidlna service script root@streaming:~ # ee /usr/local/etc/rc.d/minidlna # - Paste the code between the [start][end] tags [CODE file start][minidlna] #!/bin/sh # # $FreeBSD: head/net/minidlna/files/minidlna.in 323762 2013-07-26 23:25:40Z wg $ # # PROVIDE: minidlna # REQUIRE: LOGIN # KEYWORD: shutdown # # Add the following line to /etc/rc.conf[.local] to enable minidlna: # # minidlna_enable="YES" . /etc/rc.subr name=minidlna rcvar=minidlna_enable load_rc_config $name minidlna_enable=${minidlna_enable-"NO"} # this is the user running the daemon, it doesn't need to exist on TrueNAS host minidlna_uid=${minidlna_uid-"dlna"} #minidlna_uid=${minidlna_uid-"root"} # path to minidlnad binary command=/usr/local/sbin/minidlnad # file that holds the pid of the minidlna service when it is started pidfile="/var/run/minidlna/minidlna.pid" # config file defined in minidlna.conf conf=/usr/local/etc/minidlna.conf # database folder (only touched at startup. In all cases, the db folder set in minidlna.conf is used) #dbfile=/var/db/minidlna dbfile=/mnt/common/minidlna/db # Add -r to do a non destructive scan on service start/restart # Using -R would destroy all cached data and do a full scan again, which is very time consuming command_args="-r -P $pidfile -u $minidlna_uid -f $conf" # Create the $pidfile basedir and $dbfile folders (-d) with proper owner (-o) # if folders exist, the owner is reset on every start of minidlna service start_precmd="install -d -o $minidlna_uid ${pidfile%/*} $dbfile" # On stopping the service, remove the pidfile stop_postcmd="rm -f $pidfile" extra_commands="rescan refresh" # rescan command: destructive rescan (-R option) with rebuild of all the media library database # a service restart is needed because minidlnad doesn't support -R without loading the daemon rescan_cmd="rescan_minidlna" rescan_minidlna() { echo 'Scanning media library and rebuilding database...' command_args="-R -P $pidfile -u $minidlna_uid -f $conf" if [ -f "$pidfile" ]; then run_rc_command restart else run_rc_command start fi } # refresh command: non destructive rescan (-r option) of the media lib # Actually same as restart refresh_cmd="refresh_minidlna" refresh_minidlna() { echo 'Scanning media library for changes...' command_args="-r -P $pidfile -u $minidlna_uid -f $conf" if [ -f "$pidfile" ]; then run_rc_command restart else run_rc_command start fi } run_rc_command $1 [CODE file end][minidlna] # - Set proper permissions chmod 755 /usr/local/etc/rc.d/minidlna chown root:wheel /usr/local/etc/rc.d/minidlna # Edit minidlna config file root@streaming:~ # ee /usr/local/etc/minidlna.conf # - Paste the code between the [start][end] tags [CODE start minidlna.conf] # port for HTTP (descriptions, SOAP, media transfer) traffic port=8200 # network interfaces to serve, comma delimited (8 interfaces max) #network_interface=eth0 # specify the user account name or uid to run as user=minidlna # set this to the directory you want scanned. # * if you want multiple directories, you can have multiple media_dir= lines # * if you want to restrict a media_dir to specific content types, you # can prepend the types, followed by a comma, to the directory: # + "A" for audio (eg. media_dir=A,/home/jmaggard/Music) # + "V" for video (eg. media_dir=V,/home/jmaggard/Videos) # + "P" for images (eg. media_dir=P,/home/jmaggard/Pictures) # + "PV" for pictures and video (eg. media_dir=PV,/home/jmaggard/digital_camera) media_dir=/media # set this to merge all media_dir base contents into the root container # note: the default is no #merge_media_dirs=no # set this if you want to customize the name that shows up on your clients friendly_name=TrueNAS miniDLNA # set this if you would like to specify the directory where you want MiniDLNA to store its database and album art cache #db_dir=/var/db/minidlna db_dir=/mnt/common/minidlna/db # set this if you would like to specify the directory where you want MiniDLNA to store its log file #log_dir=/var/log log_dir=/mnt/common/minidlna/log # set this to change the verbosity of the information that is logged # each section can use a different level: off, fatal, error, warn, info, or debug #log_level=general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn # this should be a list of file names to check for when searching for album art # note: names should be delimited with a forward slash ("/") 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 # set this to no to disable inotify monitoring to automatically discover new files # note: the default is yes inotify=yes # set this to yes to enable support for streaming .jpg and .mp3 files to a TiVo supporting HMO enable_tivo=no # set this to beacon to use legacy broadcast discovery method # defauts to bonjour if avahi is available tivo_discovery=bonjour # set this to strictly adhere to DLNA standards. # * This will allow server-side downscaling of very large JPEG images, # which may hurt JPEG serving performance on (at least) Sony DLNA products. strict_dlna=no # default presentation url is http address on port 80 #presentation_url=http://www.mylan/index.php # notify interval in seconds. default is 895 seconds. notify_interval=900 # serial and model number the daemon will report to clients # in its XML description serial=12345678 model_number=1 # Override the uuid to run multiple instances # uuid=550e8400-e29b-41d4-a716-446655440000 # specify the path to the MiniSSDPd socket #minissdpdsocket=/var/run/minissdpd.sock # use different container as root of the tree # possible values: # + "." - use standard container (this is the default) # + "B" - "Browse Directory" # + "M" - "Music" # + "V" - "Video" # + "P" - "Pictures" # + Or, you can specify the ObjectID of your desired root container (eg. 1$F for Music/Playlists) # if you specify "B" and client device is audio-only then "Music/Folders" will be used as root #root_container=. # always force SortCriteria to this value, regardless of the SortCriteria passed by the client # note: you can prepend the sort criteria with "!" to alter the titles of the objects so that they # will be alphanumerically sorted in the order you specify here, to work around clients that do their # own alphanumeric sorting. force_sort_criteria=+upnp:class,+upnp:originalTrackNumber,+dc:title # maximum number of simultaneous connections # note: many clients open several simultaneous connections while streaming #max_connections=50 # set this to yes to allow symlinks that point outside user-defined media_dirs. #wide_links=no # enable subtitle support by default on unknown clients. # note: the default is yes #enable_subtitles=yes [CODE end minidlna.conf] # - Set proper permissions chmod 644 /usr/local/etc/minidlna.conf chown root:wheel /usr/local/etc/minidlna.conf # Start minidlna daemon: root@streaming:~ # service minidlna onestart # Display version minidlnad -V # Test the daemon # - with a conservative scan -r service minidlna onestop service minidlna onestart service minidlna onerefresh # - with a destructive -R rescan service minidlna onestop service minidlna onerescan # Enable daemon on jail boot sysrc minidlna_enable=yes # - or echo minidlna_enable="YES" >>/etc/rc.conf # Start / stop / rescan (Destructive) / refresh (updates the library, non destructive) service minidlna stop service minidlna start service minidlna restart service minidlna rescan service minidlna refresh # If there are issues with permissions, delete these directories so that they are recreated with proper permissions: # - recreate the mount points # - delete minidlna database and log or manually chown/chmod them service minidlna stop rm -rvf /mnt/common/minidlna/db rm -rvf /mnt/common/minidlna/log/minidlna.log service minidlna start ## Fix file limit exceeded and additional files are not scanned by minidlna/Plex # - display max files limits, globally and per process: # sysctl -a : displays all readable variables root@streaming:~ # sysctl -a | grep kern.maxfiles kern.maxfiles: 2084861 kern.maxfilesperproc: 1876374 # - to read a particular variable, specify its name: sysctl kern.maxfiles kern.maxfiles: 2084861 # - to set a particular variable, use the variable=value syntax: sysctl kern.maxfiles=3000000 kern.maxfiles: 2084861 -> 3000000 sysctl kern.maxfilesperproc=3000000 kern.maxfilesperproc: 1876374 -> 3000000 # - to make the change stick on reboot, you must edit /etc/sysctl.conf ee /etc/sysctl.conf [sysctl.conf] { # Set max readable files kern.maxfiles=3000000 kern.maxfilesperproc=3000000 } [sysctl.conf] # - if the variable is read-only and doesn't apply on reboot, modify/add it to /boot/loader.conf ee /boot/loader.conf [loader.conf] { # Set max readable files kern.maxfiles=3000000 kern.maxfilesperproc=3000000 } [loader.conf]