Pianobar remote control


43 posts   Page 1 of 2   1, 2
by azeam » 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?
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by ski522 » Fri Jan 04, 2013 12:06 pm
Might want to look into this web based app instead viewtopic.php?f=35&t=21105
Posts: 394
Joined: Sun Sep 30, 2012 2:22 pm
by azeam » 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
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by azeam » 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
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by azeam » 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
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by azeam » 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
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by azeam » 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
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by azeam » 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
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by bonelifer » 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
Posts: 122
Joined: Thu Jan 12, 2012 4:01 am
Location: http://www.phpbb.com/community/memberlist.php?mode=viewprofile&u=147848
by azeam » 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
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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,
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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"?
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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.
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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--"
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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.
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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.
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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?
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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.
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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?
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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?
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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.
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm
by azeam » 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.
User avatar
Posts: 192
Joined: Fri Oct 26, 2012 11:13 pm
by magic_man185 » 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.
Posts: 33
Joined: Tue Oct 09, 2012 7:01 pm