In one of our posts, Damian wrote about some traditions and culture in Desmart. I would like to pull this thread and show you how we inspire ourselves and improve our work.
A few years ago, someone decided to launch a radio in our office. It was a very good idea because it significantly improved the atmosphere at work. Employees don’t sit in four walls of total silence where you can only hear tapping on the keyboard. Believe me - the moment when the radio stops playing is a very noticeable annoying silence (our team is addicted to good music).
Let’s get back to the story - a few years ago Desmart was a small company where developers fit in two connected rooms. Radio, called by us “DeRadio” was working 24 hours a day on a PC. The computer was connected to an amplifier with four speakers mounted on the ceiling - such set was ideal until the company grew to a few developers’ rooms.
After expansion of the office, half of it was without music and no one liked it - we are very attached to our traditions and rules. One day, Piotr decided to do something about this silence. First of, we just plugged some speakers with amplifier to an old laptop and played some internet radio stations. It was some kind of solution, but we felt dissatisfied with it - every single part of the office was playing a different kind of music and it was not good for us. Besides that, we have a playlist with about seven thousand tracks on Spotify, and any of the employees can add his own music to it. We just started thinking again how to play this playlist simultaneously in all the rooms and Piotr said that we can try to stream music over LAN.
For this kind of audio distribution called multiroom audio, we needed server which will stream music over network and clients to listen to this stream and play it on speakers, so we need some cheap and energy-efficient hardware to do so. Radoslaw, our CTO said that we can just use one of this little ARM boards, and finally we decided to buy three Raspberry Pi.
Someone would probably say that there are good plug’n’play multiroom audio solutions, so why just waste time on it? It’s very simple, we just like to learn new things, we would like to have the satisfaction if it will work and the most important - we love to have fun ;)
In the rest of this post I will try to guide you on how to start your own streaming with Raspberry and Spotify.
First of all, you need to find which operating system for raspberry will be installed on your raspberry. After some research I decieded to use Raspbian. It’s a Debian based system made for Raspberry Pi, so it’s stable and it has a lot of packages.
Installation is very easy, you need to download the image of operating system and flash it onto microSD card. When you will have prepared microSD with OS, just plug it to your Raspberry Pi. For more details about installation you can read this instruction.
TIP: It’s recommended to buy a class 8 or 10 microSD card, it will improve the speed of installed operating system.
Start-up of Raspberry is a piece of cake. You just need to insert previously prepared SD card with OS, plug in a network cable, AC adapter and audio via mini jack or HDMI. Device will start automatically after AC adapter will be plugged into the socket. You can plug in a monitor and USB keyboard for configuration but it’s not required - you can do it via SSH. Just find Raspberry’s IP and connect to it with login ‘pi’ and password ‘raspberry’.
Before the configuration of streaming you need to tweak OS on Raspberry. I’ll present it to you in a few easy steps. Let’s do it!
- Login to Raspberry via SSH:
ssh pi@[IP ADDRESS]
- Run configuration script:
- Choose “Expand file system” - root partition will be resized to all available place on SD card. This change will be done after the next restart, but there is no need to do it now.
- For security reasons you should change password for the user, its always a bad idea to avoid it; to do so, choose “Change User Password” and insert the new one twice.
- In our case Raspberry has to deal with a huge amount of tracks. After a few lags I’ve decided to add heatsink and overclock Raspberry to 1GHz. If you have more than one thousand tracks to play, probably it will be good idea to overclock your device. If you don’t have heatsink you can safely overclock Raspberry by choosing “Modest” mode in the “Overclock” tab.
- It’s time for “Advanced Options”. In this tab you should change the hostname to a unique one. In our office every device of multiroom audio have ‘deradio’ prefix and after it, unique name for device, for example our server name is ‘deradio-shire’.
- If we don’t want to use only command lines, we should change “Memory Split” to 16MB. Default Raspbian takes 64MB of RAM for GPU (such a waste!).
- The last thing is to change default audio output in the “Audio” tab. Raspberry can play audio from minijack or HDMI, depending on what port will be used. You can force raspberry to use specific output.
After configuration is complete, choose “finish”. Raspberry will restart shortly with new settings.
Our server plays music from Spotify via software called Mopidy. It’s a music server with web interface and integration with other music services like SoundCloud or Google Play Music. It’s just ideal for multiroom audio system. Let’s install it with these steps:
Mopidy documentation recommends to enable IPv6 module:
sudo modprobe ipv6 echo ipv6 | sudo tee -a /etc/modules sudo wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add - sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/mopidy.list sudo apt-get update sudo apt-get install mopidy
After mopidy installation, you need to install mopidy-spotify extension if you want play music from Spotify.
sudo apt-get install mopidy-spotify
It’s time for configuration. Open /etc/mopidy/mopidy.conf and paste this code, remember to insert your Spotify credentials and some random password for [mpd] section:
#Audio output configuration, integration with icecast2 [audio] mixer = software mixer_volume = 85 output = alsasink #output = lame ! shout2send mount=stream.mp3 ip=127.0.0.1 port=8000 password=hackme # Spotify premium account configuration [spotify] enabled = true username = SPOTIFY_USERNAME password = SPOTIFY_PASSWORD bitrate = 320 #timeout = 10 #cache_dir = $XDG_CACHE_DIR/mopidy/spotify #settings_dir = $XDG_CONFIG_DIR/mopidy/spotify # Web access configuration [http] enabled = true hostname = 0.0.0.0 port = 6680 #static_dir = zeroconf = "" # Mpd server access, needs to be available for web interface or another MPD client (Android, CLI, etc.) [mpd] enabled = true hostname = 0.0.0.0 port = 6600 password = MPD_PASSWORD max_connections = 20 connection_timeout = 60 zeroconf = "" # Disable local search [local] enabled = false
If you want to know more about configuration see documentation.
Now you can test if mopidy works with your configuration, just start mopidy service and check the status:
sudo service mopidy start sudo service mopidy status
To start mopidy at boot, you just need to enter this line:
sudo update-rc.d mopidy enable
It’s time for web client installation. There’s a lot of web interfaces for mopidy on the web. In our case I’ve decided to install simple and lightweight interface simple-webclient.
If you want to install it, just run those commands:
UPDATE: @bluGeni wrote that you may to run this command first:
sudo pip install --upgrade setuptools
wget https://bootstrap.pypa.io/get-pip.py sudo python get-pip.py sudo pip install Mopidy-Simple-Webclient sudo service mopidy restart
After installation, open the browser and go to the IP address of your raspberry with port 6680. You should see a page where you can select web interface to use, click on simple-webclient and choose one of your playlists, after a few seconds you will be able to play music :)
Go ahead, plug in the amplifier, speakers or phones and you will hear music!
We have got the music locally and now it’s time to stream it. We will use icecast2 as audio server. Look at [audio] section in mopidy.conf file, there are two “output” parameters. Comment the first one, uncomment the second and save file. For now mopidy will be integrated with icecast2, but we don’t have it installed, so lets try to do it.
To install icecast, type this command:
sudo apt-get install icecast2
At some point during the installation, you will be asked to configure icecast but just dismiss this window, we will configure icecast with /etc/icecast2/icecast.xml. Copy the code below and paste it to configure file (remember to change passwords!):
<icecast> <limits> <clients>100</clients> <sources>2</sources> <threadpool>5</threadpool> <queue-size>524288</queue-size> <client-timeout>30</client-timeout> <header-timeout>15</header-timeout> <source-timeout>10</source-timeout> <burst-on-connect>1</burst-on-connect> <burst-size>0</burst-size> </limits> <authentication> <source-password>hackme</source-password> <relay-password>hackme</relay-password> <admin-user>admin</admin-user> <admin-password>hackme</admin-password> </authentication> <hostname>localhost</hostname> <listen-socket> <port>8000</port> <shoutcast-mount>/stream.mp3</shoutcast-mount> </listen-socket> <mount> <mount-name>/stream.mp3</mount-name> <fallback-mount>/void.mp3</fallback-mount> <fallback-override>1</fallback-override> </mount> <fileserve>1</fileserve> <paths> <basedir>/usr/share/icecast2</basedir> <logdir>/var/log/icecast2</logdir> <webroot>/usr/share/icecast2/web</webroot> <adminroot>/usr/share/icecast2/admin</adminroot> <alias source="/" dest="/status.xsl"/> </paths> <logging> <accesslog>access.log</accesslog> <errorlog>error.log</errorlog> <loglevel>4</loglevel> <logsize>10000</logsize> </logging> <security> <chroot>0</chroot> </security> </icecast>
Save it and edit /etc/default/icecast2 file, set the last attribute “ENABLE” to “true” and save the file.
In next step you need to generate an empty mp3 file. Yes, it’s not a joke - it’s needed for fallback stream when mopidy will change tracks - without this file icecast will interpret “end of track” as “end of stream”. It’s a known bug in mopidy. For more information about this problem see the advanced configuration section in mopidy documentation.
If you’re using linux just type in terminal:
rec -C 320 -c 2 -r 44100 void.mp3 trim 0 0.5
and send it to raspberry via SCP:
scp void.mp3 pi@[RASPBERRY IP ADDRESS]:~
Log in to raspberry SSH and move void.mp3 to
/usr/share/icecast2/web sudo mv ~/void.mp3 /usr/share/icecast2/web/void.mp3
To end the configuration type:
sudo service icecast2 start sudo service mopidy restart
Now, streaming should work. To check it, first choose playlist in web interface and click play, and next go to [RASPBERRY IP ADDRESS]:8000/stream.mp3 in the browser.
If everything went fine, you should hear music from any device with web browser in the same network as the server.
Every client on raspbery pi should have Raspbian installed and it should be configured as we do with the server but without overclocking. Client will not take a lot of resources.
To play music we need two packages - tmux and vlc.
sudo apt-get install vlc tmux
After installation only one command is needed:
tmux new -d -s radio "vlc http://[Raspberry server ip address]:8000/stream.mp3"
Now the client will be playing the stream. If you need to play music on the server just install tmux and vlc on it and execute the command above with 127.0.0.1 ip address.
It’s obvious that for various reasons a client can loose the connection to the server. Radoslaw gave me a good solution to this situation - cronjobs. It’s very simple, when the music stops playing, someone just restarts raspberry and cronjob is fired one minute after the boot.
To add this cronjob type:
@reboot sleep 60 && tmux new -d -s deradio "vlc http://[Raspberry server ip address]:8000/stream.mp3"
Are you satisfied with your own, cheap, simple and multiroom audio? I am, and I think that I will try to do a better one. I’m thinking of using RTP instead of HTTP protocol to achieve low latency when someone changes tracks, with HTTP it can be irritating or even frustrating for the user. If everything will be fine with RTP i will write the next ‘howto’.
Let me know in the comments below if you have any questions or concerns about my solution - I will try to help you with your DeRadio setup :)