User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Pianobar remote control

Thu Jan 03, 2013 10:59 pm

Not really Raspberry pi-related, but still. I've got my RPi set up as (among other things) a headless music server with MPD and Pianobar (Pandora radio). I've got my main computer upstairs (and the stereo downstairs) and decided to finally buy an Android phone to control the server. For MPD there are several Android clients but the only way to control Pianobar is through ssh.

Therefore I decided to write an app to control Pianobar. It's my first attempt at writing an Android app and pretty much the first time I write in Java so the code and the solution aren't the prettiest but I've got it working with basic functions such as play/pause, next track and fetching of artist/song/album and album cover from Last FM.

The way it's set up is that it logs in to the RPi with ssh and sends fifo commands to pianobar. The problem is that I'm using sshj and it doesn't support interactive commands, so I'm unable to get the station list at the first login and select station - it only works by setting an autoplay station in radiobar. Nor is it possible to select stations via fifo commands.

Any ideas how I could get an interactive session working or somehow be able to change stations?

ski522
Posts: 394
Joined: Sun Sep 30, 2012 2:22 pm

Re: Pianobar remote control

Fri Jan 04, 2013 12:06 pm

Might want to look into this web based app instead http://www.raspberrypi.org/phpBB3/viewt ... 35&t=21105

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Jan 04, 2013 12:40 pm

That's very cool, totally missed that one! It seems to do pretty much what my app does but with a different approach, some things in a much prettier way (like getting cover art directly from pianobar instead of last.fm, didn't even know about that possibility) and other things in a worse way (like a heavier load on the pi). It doesn't seem to be able to choose stations either though.

Php is probably the easiest way to get this to work well, but I kind of like the idea of having a native Android app.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Thu Jan 17, 2013 10:37 am

I've kind of managed to fix the station selection, it's possible to change between (but not see which they are) stations 1-5 (actually 0-4) and sorted out some other issues. I'm sticking with cover art from Last FM for now, since they are a bit smaller than Pandora's covers. The app is not very responsive, it's set up to probe pianobar every 15 seconds to get the current playing song and has to make an ssh connection for each command that is sent, so be a bit patient. There's still plenty to do, especially in terms of design and error handling, but it's working and in case someone else is interested the app is available at http://raspberrypiserver.no-ip.org/pianobar_remote.apk, just copy the file to your Android phone and install. It's been tested on an Android 2.3.6 phone with a 2.7" screen but should work on Android 2.3+.

To get it running you first need to install pianobar on the RPi

Code: Select all

sudo apt-get install pianobar
Then set up a config file with autologin

Code: Select all

nano ~/.config/pianobar/config
My config file looks like this

Code: Select all

control_proxy = http://165.225.xxx.xxx:80 
#I'm not in the US so I need a proxy to use pianobar, delete the line above if you are
tls_fingerprint = 2D0AFDAFA16F4B5C0A43F3CB1D4752F9535507C0
user = myemail@mail.com
password = mypassword
event_command = /home/pi/.config/pianobar/eventcommand.sh
Make an event command script

Code: Select all

nano ~/.config/pianobar/eventcommand.sh
With the following code

Code: Select all

#!/bin/bash

fold="$HOME/.config/pianobar"
stl="$fold/stationlist"
ctlf="$fold/ctl"
nowplaying="$fold/nowplaying"
while read L; do
        k="`echo "$L" | cut -d '=' -f 1`"
        v="`echo "$L" | cut -d '=' -f 2`"
        export "$k=$v"
done < <(grep -e '^\(title\|artist\|album\|stationName\|pRet\|pRetStr\|wRet\|wRetStr\|songDuration\|songPlayed\|rating\|songDuration\|songPlayed\|coverArt\|stationCount\|station[0-9]\+\)=' /dev/stdin)

case "$1" in
        songstart)
        echo -e "$artist \n$title \n$stationName \n$rating \n$coverArt \n$album" > "$nowplaying"
;;
	songlove)
        echo -e "$artist \n$title \n$stationName \n$rating \n$coverArt \n$album" > "$nowplaying"
;;
	songban)
	echo -e "" > "$nowplaing"
;;
	
	 usergetstations)
	   if [[ $stationCount -gt 0 ]]; then
		  rm -f "$stl"
		  for stnum in $(seq 0 $(($stationCount-1))); do
			 echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
		  done
	   fi

	   ;;
	   stationcreate)
           if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
	stationaddgenre)
         if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
	songexplain)
          if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
           stationaddshared)
          if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
        stationdelete)
           if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi
		echo -e "" > "$nowplaying"
           ;;
esac
Make the event command file executable

Code: Select all

chmod +x ~/.config/pianobar/eventcommand.sh
Finally make a fifo that receives the commands

Code: Select all

mkfifo ~/.config/pianobar/ctl
The login details when the app starts up are for the ssh connection to the RPi, you can change the user/port/host but they are set to the default RPi details.
Last edited by azeam on Tue Apr 02, 2013 6:15 pm, edited 2 times in total.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Jan 18, 2013 2:07 pm

Have made some changes since yesterday (a bit nicer GUI, more responsive etc.) The eventcommand file has to be changed to the following though

Code: Select all

#!/bin/bash

fold="$HOME/.config/pianobar"
stl="$fold/stationlist"
ctlf="$fold/ctl"
nowplaying="$fold/nowplaying"
while read L; do
        k="`echo "$L" | cut -d '=' -f 1`"
        v="`echo "$L" | cut -d '=' -f 2`"
        export "$k=$v"
done < <(grep -e '^\(title\|artist\|album\|stationName\|pRet\|pRetStr\|wRet\|wRetStr\|songDuration\|songPlayed\|rating\|songDuration\|songPlayed\|coverArt\|stationCount\|station[0-9]\+\)=' /dev/stdin)

case "$1" in
        songstart)
        echo -e "$artist \n$title \n$stationName \n$rating \n$coverArt \n$album" > "$nowplaying"
;;
	songlove)
        echo -e "$artist \n$title \n$stationName \n$rating \n$coverArt \n$album" > "$nowplaying"
;;
	songban)
	echo -e "" > "$nowplaing"
;;
	
	 usergetstations)
	   if [[ $stationCount -gt 0 ]]; then
		  rm -f "$stl"
		  for stnum in $(seq 0 $(($stationCount-1))); do
			 echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
		  done
	   fi

	   ;;
	   stationcreate)
           if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
	stationaddgenre)
         if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
	songexplain)
          if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
           stationaddshared)
          if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
        stationdelete)
           if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi
		echo -e "" > "$nowplaying"
           ;;
esac
Last edited by azeam on Tue Apr 02, 2013 6:16 pm, edited 1 time in total.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Tue Jan 22, 2013 4:16 pm

Finally got the station list to work, also decreased the bandwidth usage and fixed some other stuff. The main issue now is that pianobar sometimes misses the FIFO commands, haven't figured out yet if it's just the way it is or if there's some better way to send the commands. For now, just click again if nothing happens.

Same link as before to the new version of the app. New event command file:

Code: Select all

#!/bin/bash

fold="$HOME/.config/pianobar"
stl="$fold/stationlist"
ctlf="$fold/ctl"
nowplaying="$fold/nowplaying"
while read L; do
        k="`echo "$L" | cut -d '=' -f 1`"
        v="`echo "$L" | cut -d '=' -f 2`"
        export "$k=$v"
done < <(grep -e '^\(title\|artist\|album\|stationName\|pRet\|pRetStr\|wRet\|wRetStr\|songDuration\|songPlayed\|rating\|songDuration\|songPlayed\|coverArt\|stationCount\|station[0-9]\+\)=' /dev/stdin)

case "$1" in
        songstart)
        echo -e "$artist \n$title \n$stationName \n$rating \n$coverArt \n$album" > "$nowplaying"
;;
	songlove)
        echo -e "$artist \n$title \n$stationName \n$rating \n$coverArt \n$album" > "$nowplaying"
;;
	songban)
	echo -e "" > "$nowplaing"
;;
	
	 usergetstations)
	   if [[ $stationCount -gt 0 ]]; then
		  rm -f "$stl"
		  for stnum in $(seq 0 $(($stationCount-1))); do
			 echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
		  done
	   fi

	   ;;
	   stationcreate)
           if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
	stationaddgenre)
         if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
	songexplain)
          if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
           stationaddshared)
          if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi

           ;;
        stationdelete)
           if [[ $stationCount -gt 0 ]]; then
                  rm -f "$stl"
                  for stnum in $(seq 0 $(($stationCount-1))); do
                         echo "$stnum) "$(eval "echo \$station$stnum") >> "$stl"
                  done
           fi
		echo -e "" > "$nowplaying"
           ;;
esac
Last edited by azeam on Tue Apr 02, 2013 6:16 pm, edited 1 time in total.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Mon Feb 04, 2013 3:15 pm

Got a bit of time today to improve the GUI, added option to remember login details, auto-pause on incoming phone call and some other minor stuff. Will from now on stop spamming this thread and instead keep this website updated with the latest install instructions, screenshots etc.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Thu Feb 28, 2013 6:35 pm

Just wanted to add that the app has gone through lots of changes and is now available on Google Play, see Pianobar Remote Control for the latest setup instructions and download link.

User avatar
bonelifer
Posts: 127
Joined: Thu Jan 12, 2012 4:01 am
Location: http://www.phpbb.com/community/memberli ... e&u=147848
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 5:39 pm

azeam is it also available as a downloadable APK for people who can't install Market on their device?

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 5:53 pm

bonelifer wrote:azeam is it also available as a downloadable APK for people who can't install Market on their device?
Yes, you can download the latest version at http://raspberrypiserver.no-ip.org/pianobar_remote.apk

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 8:32 pm

azeam,

Your project looks interesting, I will try it out at some point. I am currently working with pianobar and the fifo file, and I was wondering if you could tell me what is going on. I have pianobar installed on the Raspberry Pi, the config file is set to auto login, and it is working properly. I have the fifo file that I set up with mkfifo /home/pi/.config/pianobar/ctl. I start pianobar, and it starts playing music no problems, and I can control it with the on screen commands. When I open another terminal and type echo "p" >> /home/pi/.config/pianobar/ctl to try to send a command through the fifo to pianobar, the terminal just sits there locked up forever. If I press Ctrl + C to break the action it says Interrupted system call, but no matter how long I let it sit, the command never goes through to the fifo and pianobar doesn't respond to the command. Have you seen this, or would you have any idea why this is happening?

Thanks,

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 8:45 pm

magic_man185 wrote:azeam,

Your project looks interesting, I will try it out at some point. I am currently working with pianobar and the fifo file, and I was wondering if you could tell me what is going on. I have pianobar installed on the Raspberry Pi, the config file is set to auto login, and it is working properly. I have the fifo file that I set up with mkfifo /home/pi/.config/pianobar/ctl. I start pianobar, and it starts playing music no problems, and I can control it with the on screen commands. When I open another terminal and type echo "p" >> /home/pi/.config/pianobar/ctl to try to send a command through the fifo to pianobar, the terminal just sits there locked up forever. If I press Ctrl + C to break the action it says Interrupted system call, but no matter how long I let it sit, the command never goes through to the fifo and pianobar doesn't respond to the command. Have you seen this, or would you have any idea why this is happening?

Thanks,
When you start pianobar, do you get a message saying "(i) Control fifo at /home/pi/.config/pianobar/ctl opened"?

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 8:47 pm

Thanks for the fast response, no it doesn't say that when it starts up, any idea why it isn't opening it? I have even tried changing the permissions of the fifo file with chmod 0777.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 8:53 pm

magic_man185 wrote:Thanks for the fast response, no it doesn't say that when it starts up, any idea why it isn't opening it? I have even tried changing the permissions of the fifo file with chmod 0777.
Try to remove it and create the file again.

Code: Select all

mkfifo ~/.config/pianobar/ctl
If you do a "ls -l" the file permissions for the ctl file should be "prw-rw-r--"

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 9:00 pm

If I just create the ctl file, the permissions are prw-r--r--. I figured out the problem, although I don't know if there is any way around it. When I run pianobar as the pi user, it recognized the configuration file, but it does not load the fifo file. If I log in as root and run pianobar, it is looking for the configuration file in /root/.config/pianobar/config and doesn't find it, so I have to manually login and everything. However, if I copy the configuration file to /root/.config/pianobar/config and run pianobar as root, then it works and it loads the fifo file. Is there a way to run pianobar as pi and still have the fifo file work? All of the tutorials I have seen for pianobar do not mention having to run as root.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 9:09 pm

magic_man185 wrote:If I just create the ctl file, the permissions are prw-r--r--. I figured out the problem, although I don't know if there is any way around it. When I run pianobar as the pi user, it recognized the configuration file, but it does not load the fifo file. If I log in as root and run pianobar, it is looking for the configuration file in /root/.config/pianobar/config and doesn't find it, so I have to manually login and everything. However, if I copy the configuration file to /root/.config/pianobar/config and run pianobar as root, then it works and it loads the fifo file. Is there a way to run pianobar as pi and still have the fifo file work? All of the tutorials I have seen for pianobar do not mention having to run as root.
Sounds like you created the fifo file as root (sudo mkfifo...), is that right? You can (should) create it without sudo when it's in your (pi's) home directory.

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 9:14 pm

You are right, I did create the fifo as root, because I am putting it in ~/.config/pianobar/ctl according to tutorials I have been following, and it says permission denied unless you log in as root. Do you have to put the ctl file in the home directory to get it to work without root?

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 9:19 pm

magic_man185 wrote:You are right, I did create the fifo as root, because I am putting it in ~/.config/pianobar/ctl according to tutorials I have been following, and it says permission denied unless you log in as root. Do you have to put the ctl file in the home directory to get it to work without root?
No need to be root to make the fifo file. Just stay logged in as pi and do

Code: Select all

mkfifo ~/.config/pianobar/ctl
The tilde (~) is the same as your home directory (/home/user, in this case /home/pi), shouldn't give you a permissions denied.

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 9:20 pm

This is exactly what I get:

pi@raspberrypi ~ $ mkfifo ~/.config/pianobar/ctl
mkfifo: cannot create fifo `/home/pi/.config/pianobar/ctl': Permission denied

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 9:25 pm

magic_man185 wrote:This is exactly what I get:

pi@raspberrypi ~ $ mkfifo ~/.config/pianobar/ctl
mkfifo: cannot create fifo `/home/pi/.config/pianobar/ctl': Permission denied
Very strange, no idea why that happens. Try to create the file /home/pi/.config/pianobar/ctl with sudo as you did and do

Code: Select all

sudo chown pi:pi /home/pi/.config/pianobar/ctl

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 9:32 pm

I tried that command, and it shows the change in ownership of the file in ls -l, but it pianobar without root still doesn't load the ctl file. This is so weird, everything I have seen online says that this should work without root, I even did this on a fresh O.S. card to make sure nothing else was interfering, and I still can't get it working the way it should (with the file in the .config/pianobar folder). Thanks for all the help by the way, I appreciate it. Any other ideas?

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 9:37 pm

What if you go to ~/.config and do "ls -l", is the pianobar folder own by root or pi/pi?

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 9:47 pm

It is owned by root. I did the chown to the pianobar folder and it WORKED!! Just a question, when you installed pianobar did you download it through apt-get or did you have to compile it from git? I had to compile it so that is why the folder was owned by root I think. When I tried the pianobar from apt-get it wouldn't connect to Pandora because of a TLS handshake failure.

User avatar
azeam
Posts: 194
Joined: Fri Oct 26, 2012 11:13 pm
Contact: Website

Re: Pianobar remote control

Fri Mar 01, 2013 9:53 pm

magic_man185 wrote:It is owned by root. I did the chown to the pianobar folder and it WORKED!! Just a question, when you installed pianobar did you download it through apt-get or did you have to compile it from git? I had to compile it so that is why the folder was owned by root I think. When I tried the pianobar from apt-get it wouldn't connect to Pandora because of a TLS handshake failure.
Glad you could sort it out! :) I've used the version in the repositories and it did work the last time I tried it, but since I'm using Pandora One now (for the 192kbit) it requires the git version with this patch, so that's what I've been running lately.

magic_man185
Posts: 34
Joined: Tue Oct 09, 2012 7:01 pm

Re: Pianobar remote control

Fri Mar 01, 2013 10:02 pm

I've finally got it all figured out. When I compiled pianobar, I compiled it as root. That caused the pianobar folder to be owned by root. I just deleted pianobar and recompiled it using sudo commands instead, and it works that way everything should. Thank you so much for your help, it has been greatly appreciated. Now I look forward to trying out your android app.

Return to “Java”

Who is online

Users browsing this forum: mamech and 5 guests