Friday, April 4, 2014

Raspberry Pi Information Radiator: Streaming Music

In my last post, I outlined a project I have been working on for building an information radiator using the raspberry pi. For the last few days, I have been using this for my own needs and I have noted that having the information on constant display has worked as a constant reminder and motivator. I quickly noticed the lack of the right metrics, like my overall GitHub and blogging activity, and I am currently working on adding and improving them. Nice!

I also recognized an opportunity to utilize the always-on nature of the radiator more completely. I  like to work to music and this device is always on and has audio hardware powered and ready-to-use (or so I guessed). While I could use it to signal updates to the display or something else purely functional, I figured, why do something functional when it is more fun to play internet radio?

Oh yeah. I'm not getting to those tasks on my task list... right. (it works!)

Since this was surprisingly quick, easy and appeals to the command-line lovers out there (my peeps), I figured I would share it.

Installing CMus

First, we need a tool for playing audio. There are surprisingly many music players for linux. I did not spend much time considering the alternatives. I just used CMus. It heralded command line usage and supported a vi-like command-line interface (I love you emacs, but you are absurdly fat for a command-line editor). Interestingly enough, I found what may be a more direct approach to what I will describe here using mpd (and it can be controlled from vim with vimmpc!). The message here is that this is not the only approach, or even the best. With that said, to install CMus was simple from raspbian:

 # Install CMus using apt  
 sudo apt-get install cmus  

Forcing audio through HDMI

For some reason the audio wasn't working. Fortunately, I noticed settings in the rapsi-config tool for audio and there was an option to force audio through HDMI. After enabling this setting, everything started working.

 # force audio through HDMI  
 sudo raspi-config  

The setting is under 'Advanced Settings' => 'Audio' => 'Force HDMI'. Once I enabled this, I did not have to reboot the device, though your mileage may vary.

Playing an Internet Radio Station

To test out the audio, I quickly searched the icecast stream directory for a reggae station. Once I found a station I could live with, I copied the M3U link location using my web browser. I then started CMus and added the file:
 # Start the player  
 # While you are in the program, type  
 :add url  

The station was added as <Stream>. To start playing it, I simply used arrow keys to select it and hit Enter. Once it was buffered, I heard Bob Marley singing to me from my television. However, when I quit the program the audio stopped immediately. Screen to the rescue!

Using Screen to run CMus in the Background

If you haven't used screen to detach from long-running processes before, try it. It's an awesome tool. It effectively allows you to detach and reattach to a terminal from different sessions. Did I say it was awesome already? It saved my sanity a few times doing OS installs over unreliable connections working in Kenya. After about the third time being disconnected and having to start over, I found this tool. Anyway, I quickly recognized it would work for running CMus in the background as well.

To install it:

 # Install screen using apt  
 sudo apt-get screen  

To start and detach from CMus:

 # Start screen  
 # Start CMus  
 # To detach once you started your audio, hit ctrl-a then ctrl-d  

Once you do this, you will be back to a command prompt and you should notice the audio continues playing! You can quit your terminal session, and it will continue running. When you are ready to access the program again, simply login and do the following:

 # Reattach to the previously detached session  
 screen -r  

There is a lot more flexibility and power screen can give you, but this will be enough to run CMus in the background.

Using CMus Remote

With what we already setup, you could operate CMus simply by attaching and reattaching to the running processing using screen. However, CMus provides a program called cmus-remote that allows you to communicate to the running program through a named pipe. If you don't know what that means, that's ok, it enables you to run commands and control CMus without having to attach to the running terminal in screen. Just login and you can do things like the following:

 # Stop the player  
 cmus-remote --stop  
 # Start the player  
 cmus-remote --play  
 # Query the status of the player  
 cmus-remote --query  
 # Sample output from querying  
 status playing  
 duration -1  
 position 21  
 tag title BobMarley  
 tag genre reggae  
 tag comment  
 set aaa_mode all  
 set continue true  
 set play_library true  
 set play_sorted false  
 set replaygain disabled  
 set replaygain_limit true  
 set replaygain_preamp 6.000000  
 set repeat false  
 set repeat_current false  
 set shuffle false  
 set softvol false  
 set vol_left 100  
 set vol_right 100  
 # Set the volume  
 cmus-remote -v 80%  
 cmus-remote -v 100%  

One thing I did note was that for some reason, setting the volume to anything below 80% with my setup seemed to mute the audio entirely.

Improving On It

This enables you to play audio, but it does force you to login to the raspberry pi to do it. This worked for me, but I could definitely see wanting to improve on this. Some specific ideas I had were controlling CMus via an IRC bot and stopping and starting based on a work schedule using cron. You might also use something like mpd to eliminate the need for using screen entirely. In any case, it is a simple approach that may spark some of your own ideas. Enjoy!

No comments:

Post a Comment