[LINUX] Modify and install ReadyMedia sources

Overview

I've been using DLNA for the last few years with ReadyMedia installed on my Raspberry Pi. There was something I was interested in after a long time, so I modified the source, so I will write an article from the installation.

wrap up

Construction environment (reference)

procedure

Procedure (1) Build and install ReadyMedia

Procedure (1-1) Installing the library

shell


# libjpeg-turbo
yum list libjpeg-turbo libjpeg-turbo-devel libjpeg-turbo-static libjpeg-turbo-utils
yum install libjpeg-turbo libjpeg-turbo-devel libjpeg-turbo-static libjpeg-turbo-utils

# sqlite3
yum list sqlite-devel
yum install sqlite-devel

# libexif
yum list libexif libexif-devel libexif-doc
yum install libexif libexif-devel libexif-doc

# libid3tag
yum list libid3tag libid3tag-devel
yum install libid3tag libid3tag-devel

#flac
yum list flac flac-devel flac-libs
yum install flac flac-devel flac-libs

In addition, if there is a shortage, install it as appropriate.

Procedure (1-2) Download and extract the ReadyMedia source

shell


cd /usr/local/src
wget http://jaist.dl.sourceforge.net/project/minidlna/minidlna/1.2.1/minidlna-1.2.1.tar.gz
tar zxvf minidlna-1.2.1.tar.gz
cd minidlna-1.2.1

Procedure (1-3) ReadyMedia source modification

Procedure (1-3-1) Change the cache size of album art

By default, the maximum is 160px, which makes the display rough during playback. Raise the maximum to 500px. (If you want to be bigger, make it bigger.)

Change 2 files.

shell


vi /usr/local/src/minidlna-1.2.1/albumart.c

Per 72 lines. Rewrite 160 to 500.

albumart.c


if( imsrc->width > imsrc->height )
{
	# dstw = 160;
	dstw = 500;
	# dsth = (imsrc->height<<8) / ((imsrc->width<<8)/160);
	dsth = (imsrc->height<<8) / ((imsrc->width<<8)/500);
}
else
{
	# dstw = (imsrc->width<<8) / ((imsrc->height<<8)/160);
	dstw = (imsrc->width<<8) / ((imsrc->height<<8)/500);
	# dsth = 160;
	dsth = 500;
}

shell


vi /usr/local/src/minidlna-1.2.1/metadata.c

Per 594 lines

metadata.c


if( ed->size )
{
	/* We might need to verify that the thumbnail is 160x160 or smaller */
	if( ed->size > 12000 )
	{
		imsrc = image_new_from_jpeg(NULL, 0, ed->data, ed->size, 1, ROTATE_NONE);
		if( imsrc )
		{
			#if( (imsrc->width <= 160) && (imsrc->height <= 160) )
			if( (imsrc->width <= 500) && (imsrc->height <= 500) )
				thumb = 1;
			image_free(imsrc);
		}
	}
	else
		thumb = 1;
}

Procedure (1-3-2) Change ARTIST information collection logic

If you keep the default, if the song has an album artist set, that will be prioritized. Logically   [ALBUM ARTIST] > [BAND] > [ARTIST] So, it seems that only the ARTIST attribute is managed in the DB, and it is registered with the one with high priority.

I don't know why, but it's very inconvenient to crush a track artist with a CD artist, so I'll just use ARTIST. In terms of processing, after taking [ARTIST], it is overwritten with [ALBUM ARTIST] or [BAND], so Comment out the part where the information is overwritten to eliminate the process.

shell


vi /usr/local/src/minidlna-1.2.1/metadata.c

Per 411 lines. Comment out the entire block of if statement.

metadata.c


/* If there is a album artist or band associated with the album,
   use it for virtual containers. */
//if( i < ROLE_ALBUMARTIST )
//{
//	for( i = ROLE_ALBUMARTIST; i <= ROLE_BAND; i++ )
//	{
//		if( song.contributor[i] && *song.contributor[i] )
//			break;
//	}
//	if( i <= ROLE_BAND )
//	{
//		m.artist = trim(song.contributor[i]);
//		if( strlen(m.artist) > 48 )
//		{
//			m.artist = strdup("Various Artists");
//			free_flags |= FLAG_ARTIST;
//		}
//		else if( (esc_tag = escape_tag(m.artist, 0)) )
//		{
//			m.artist = esc_tag;
//			free_flags |= FLAG_ARTIST;
//		}
//	}
//}

Procedure (1-4) Build and install ReadyMedia

shell


./configure
make -j2
make install

Step (1-5) ReadyMedia settings

By default, the sort is not related to media folders, so set that as well.

shell


cp /usr/local/src/minidlna-1.2.1/minidlna.conf /etc/
vi /etc/minidlna.conf

/etc/minidlna.conf


#Set media folder
media_dir=Arbitrary path

#Enter the DLNA server name
friendly_name=Any name

#Sort specification settings. Uncomment
force_sort_criteria=+upnp:class,+upnp:originalTrackNumber,+dc:title

Procedure (2) Service execution settings

Step (2-1) Creating an execution user and creating a cache folder

useradd -s /sbin/nologin upnp
mkdir -R /var/cache/minidlna
chown -R upnp:upnp /var/cache/minidlna

Step (2-2) Creating a unit for the service

shell


touch /etc/systemd/system/minidlna.service
vi /etc/systemd/system/minidlna.service

/etc/systemd/system/minidlna.service


[Unit]
Description=minidlna server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
User=upnp
Group=upnp
Restart=always
RestartSec=10
ExecStart=/usr/local/sbin/minidlnad -R -d -f /etc/minidlna.conf
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill $MAINPID

[Install]
WantedBy=multi-user.target

Step (2-3) Enable / execute for service

shell


#Service activation
systemctl enable minidlna.service
#Service start
systemctl start minidlna.service
#Log check
journalctl -f -u minidlna.service

Step (3) Confirmation

Check with the DLNA client. (On Windows, the only decent DLNA client seems to be MediaMonkey.)

Step (9) Bonus

Change inotify monitoring limit

ReadyMedia uses inotify Although it is automatically added when a file system change is detected. Tune inotify if necessary.

shell


#Check the maximum number of monitors per user
cat /proc/sys/fs/inotify/max_user_watches

#Change the maximum number of monitors per user(Temporary)
sysctl fs.inotify.max_user_watches=100000

#Change the maximum number of monitors per user(permanent)
touch /etc/sysctl.d/90-inotify.conf
vi /etc/sysctl.d/90-inotify.conf

conf:/etc/sysctl.d/90-inotify.conf


#Set the maximum number of monitors per user
fs.inotify.max_user_watches = 100000

Impressions

I've been doing trial and error for the last few years when listening to home media indoors and outdoors. I've been trying DLNA (ReadyMedia), BubbleUPnP, SubSonic (lms), etc. ReadyMedia is grateful that playlists placed on the file system are available. It is very useful for BGM playback even indoors.

Also, I bought nearly 600 songs the other day, so When I listened to them and thought about remembering the song titles, I thought that the qualification information was also very important. I'm glad I was able to correct the artist name display this time. (Because I'm working hard to organize the tags ...)

photo.jpg (Reference) Amazon Kindle + BubbleUPnP

Digression

Digression ① Read the resizing logic slowly

metadata.c


if( imsrc->width > imsrc->height )
{
	dstw = 160;
	dsth = (imsrc->height<<8) / ((imsrc->width<<8)/160);
}
else
{
	dstw = (imsrc->width<<8) / ((imsrc->height<<8)/160);
	dsth = 160;
}

The place of this correction. I thought that the size after resizing was calculated by the atmosphere, but It was difficult to understand and I gave up reading. However, if you think about it slowly, it's still a little interesting code.

Probably because there is no particular basis for the coefficient to increase the value. If so, I think it would be faster to use shift operations rather than multiplication. Even if you don't normally use decimal numbers, it seems that you are considering FPU.

python


height' = \frac{height\times 256}{(width \times 256) \div desired size}

No, it's a math level story, so I don't have to break it down to this point. Even when I was making an i-appli, I couldn't use decimal numbers, so HP gauges, scroll bars, etc. I felt nostalgic because the calculation on the integer side was common.

Digression (2) Arithmetic that optimizes the resizing logic expression

I used to calculate the ratio during the resizing process, Actually, I have experience of being able to perform integer arithmetic without ratio calculation by letting multiplication be performed first. Well, in my case it was just a fool, so it took me several years to notice it (explosion). (I was looking for a percentage ...) I tried to do some math to see if it could be optimized.

python


\begin{align}
height' &= \frac{height \times 256}{(width \times 256) \div desired size} \\
&= \frac{height}{width \div desired size} \\
&= \frac{height}{width \times \frac{1}{Desired size}} \\
&= \frac{height}{width} \times \frac{Desired size}{1} \\
&= (height \div width) \times desired size\\
&= height \times desired size\div width \\
\end{align}

That's why

python


height' = height \times desired size\div width \\

Can you go : thinking: Let's check! SS.png I checked it in Excel, but it looks okay. (At the point where the deficit is calculated, check the amount by the error of the ass ratio before and after resizing.) There is a risk of overflowing digits, but sometimes the formula becomes simple, so There may be a review of the calculation formula under these restrictions.

Reference (Acknowledgment)

Recommended Posts

Modify and install ReadyMedia sources
Install pyenv and pyenv-virtualenv
Install and configure KVM
Install Python and Flask (Windows 10)
Install Python 3.7 and Django 3.0 (CentOS)
Install Pyethapp and generate an account
Install Python 2.7.9 and Python 3.4.x with pip.
Install Mecab and mecab-python3 on Ubuntu 14.04
How to install and use Tesseract-OCR
Install and run dropbox on Ubuntu 20.04
Install OpenCV and Chainer on Ubuntu
(Windows10) Install Linux environment and gnuplot.
Install CUDA 8.0 and Chainer on Ubuntu 16.04
Build and install OpenCV on Windows
How to install and configure blackbird
How to install CUDA and nvidia-driver
How to install and use Graphviz
Install fabric on Ubuntu and try
Compile and install Git from source.
Install and configure `pyenv` Ansible playbook
Install easy_install and pip on windows
Until you install and run matplotlib