PMRP UI yad

misko_2083

Played a little with this, there are just a few stations, but it looks ok to me.
I have compiled the latest yad and mpg123, so I'm not sure how it works with older versions.

It's a little slow on exit but that's how the remote control works with mpg123. There is a 10 seconds sleep on quit, then if mpg123 doesn't want to quit, we call the "killall".
How to setup? First you need a stations file. I think it's better to keep the stations out of the script. It's easier to maintain them this way.
There are just a few stations in there for now.
Honestly, I lost the willpower after seeing how many stations are there in the original pmrp script  :D
stations file:
## Stations
# Tag: "Name" "Category" "URL"

## 181.FM

181.FM: "Chilled Out" "Techno" "http://relay.181.fm:8700"
181.FM: "Energy 93" "Techno" "http://relay.181.fm:8044"
181.FM: "Energy 98" "Techno" "http://relay.181.fm:8800"
181.FM: "Studio 181" "Techno" "http://relay.181.fm:8072"
181.FM: "Techno Club" "Techno" "http://icyrelay.181.fm/181-technoclub_128k.mp3"
181.FM: "The Vibe of Vegas" "Techno" "http://relay.181.fm:8074"
181.FM: "Jammin 181" "Urban" "http://relay.181.fm:8042"
181.FM: "Old School HipHop" "Urban" "http://relay.181.fm:8068"
181.FM: "The Beat" "Urban" "http://relay.181.fm:8054"
181.FM: "The Box" "Urban" "http://relay.181.fm:8024"
181.FM: "True R&B" "Urban" "http://relay.181.fm:8022"

# Needs at least one empty new line at the end of the list
# to avoid yad list issue

OK, now the script (remember to change the path to stations file in this line => export pmrp_stations="/home/misko/Desktop/pmrpui/stations")
#!/bin/bash
command -v mpg123 >/dev/null 2>&1 || (yad --text="PMRP requires 'mpg123' but it's not installed!\nInstall 'mpg123' to enjoy PMRP."; exit 1)

TEXTDOMAIN=ydesk
TEXTDOMAINDIR=/usr/share/locale

export pmrp='@bash -c "run_stations %1"'
export pmrp_stations="/home/misko/Desktop/pmrpui/stations"

export fpipe=$(mktemp -u --tmpdir pmrp.XXXXXXXX)
export ppipe=$(mktemp -u --tmpdir ppmrp.XXXXXXXX)
export cpipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)

mkfifo "$fpipe"
mkfifo "$ppipe"
mkfifo "$cpipe"

trap "rm -f $fpipe $ppipe $cpipe" EXIT

pmkey=$(($RANDOM * $$))

# Categories are separated with "!" (without quotes)
# The last item in category is without trailing "!"
Categories="181.FM!
Blues!
Bollywood!
Classical!
Country!
Electronic!
Hits!
Jazz!
Medley!
Metal!
News_&_Views!
Oldies!
Reggae!
Rock!
SomaFM!
Urban"


function run_stations
{
    echo "2:@disable@"
    echo -e '\f' >> "$fpipe"

    ECHO_ONE='echo "Category: $1" >> "$ppipe"'
    ECHO_TWO='echo "-----------------------" >> "$ppipe"'
    case "$1" in
181.FM)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Blues)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Bollywood)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Classical)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Country)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Electronic)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Hits)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Jazz)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Medley)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Metal)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
"News_&_Views")
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Oldies)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Reggae)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Rock)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
SomaFM)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Urban)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
         *)
          echo "PMRP: Error! No such Category $1" >> "$ppipe"
            ;;
    esac
    echo "2:$pmrp"
}
export -f run_stations



function load_url
{
    echo "Station:$1   Url: $3" >> $ppipe
    echo "load $3" > $cpipe
}
export -f load_url

exec 3<> $fpipe
exec 4<> $ppipe
exec 5<> $cpipe

killall mpg123 2>/dev/null
PLAYER="mpg123 --remote --fifo $cpipe --utf8 --title --preload 1 --buffer 768 --smooth"
$PLAYER 2>&1 /dev/null | tee >(awk '/@E/ || /@P/{if ($0=="@P 0") print "PMRP: playing stopped";
                                                else if ($0=="@P 1") print "PMRP: playing paused";
                                                else if ($0=="@P 2") print "PMRP: playing";
                                                else if ($0 ~ "^@E.") print "PMRP:",$1="",$0;
                                                else print $0; fflush(stdout)}'  >> "$ppipe") \
                            >(awk -F'=' '/StreamTitle/{gsub(/'\''/,"",$2);
                            gsub(/\;/,"",$2); print "Title:", $2; fflush(stdout)}' >> "$ppipe") &>/dev/null &

yad --plug="$pmkey" --tabnum=1 --form --field "Category":CB "$(for category in $Categories; do printf "%s" "$category"; done)" \
    --image=radio --image-ontop --field="Load Stations!gtk-add:fbtn" "$pmrp" &

yad --plug="$pmkey" --tabnum=2 --list --no-markup --dclick-action='bash -c "load_url %s"' \
    --text "Double click to play" --text-align=center --column="Name" --column="Category" --column="Url" \
    --search-column=1 --expand-column=1 --print-column="3" <&3 &

yad --text-info --title="PMRP-Log" --window-icon=radio --posx=710 --posy=100 --width=600 --height=500 --button="gtk-close" <&4 &

echo "PMRP: Ready to Play" >> "$ppipe"

yad --paned --key="$pmkey" --button="Show Log":'bash -c "yad --text-info --title=PMRP-Log --window-icon=radio --posx=710 --posy=100 --width=600 --height=500 < $ppipe" &' \
    --button="Pause/Continue":'bash -c "echo pause >> $cpipe"' \
    --button="Stop":'bash -c "echo stop >> $cpipe"'  --text="Select a Category and click to Load Stations" --width=700 --height=500 \
    --title=$"PMRP" --window-icon="radio" --posx=10 --posy=100

[[ $? == 252 ]] && echo quit >> $cpipe
echo "PMRP: Preparing for radio silence" >> "$ppipe"
# Takes a lot to quit, patience
sleep 10
# Well, sometimes it fails to quit, SIGTERM
killall mpg123 2>/dev/null
echo "PMRP: Zzzzzzz" >> "$ppipe"

exec 3>&-
exec 4>&-
exec 5>&-


zephyr

#1
^ Nicely done, works as advertised! Only took about 5 minutes and added a few more stations from the list found on the  https://github.com/hakerdefo/pmrp script. Really great sound, use MOC for my music collection, pmrp perfect for internet radio!

misko! Thank You!! Absolutely great tutorial, worked as you stated from the word go!  :)

Been ages since posting a screenie and found zimagesz or just me having issues. Give it a shot at it or it didn't happen!  ::)



Looks like  https://scrot.moe/ works!
Cheers

zephyr

CROWZ / STAR / Devuan / refracta / VSIDO

misko_2083

#2
Thank you zephyr, I'm really glad you like it.
Lookin good on your desktop.  ;)
I'm thinking of changing a few things. Not sure what is the best approach.
I could redirect the data to the upper tab to dispay the info about the curent status of the player, like the title, playing status and errors.
Then, there won't be need for two windows. The log window will be available to open but I think from a file. That way, when it's closed, it will not lose the data.
Will see what can I do and what is the best way.

I want to thank Hakerdefo for creating pmrp (poor man's radio player).
Cheers

zephyr

^ Cool idea to have a separate log file, notification on upper tab. Over all a super project with PMRP.

Hakerdefo's script has a lot of great radio streams and tried many of them of all genre's.  Thanks to the both of you for your much appreciated efforts! :)

zephyr
CROWZ / STAR / Devuan / refracta / VSIDO

misko_2083

#4
The code is ready. I just need to enter the stations.

New script here:
#!/bin/bash
command -v mpg123 >/dev/null 2>&1 || (yad --text="PMRP requires 'mpg123' but it's not installed!\nInstall 'mpg123' to enjoy PMRP."; exit 1)

TEXTDOMAIN=ydesk
TEXTDOMAINDIR=/usr/share/locale

export pmrp='@bash -c "run_stations %2"'
export pmrp_stations="/home/misko/Desktop/pmrpui/stations"

export fpipe=$(mktemp -u --tmpdir pmrp.XXXXXXXX)
export ppipe=$(mktemp -u --tmpdir ppmrp.XXXXXXXX)
export cpipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)
export statuspipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)
export PMRPID=$(mktemp -u --tmpdir PMRPID.XXXXXXXX)

mkfifo "$fpipe"
mkfifo "$cpipe"
mkfifo "$statuspipe"

trap "rm -f $fpipe $ppipe $cpipe $statuspipe $PMRPID" EXIT

pmkey=$(($RANDOM * $$))

# Categories are separated with "!" (without quotes)
# The last item in category is without trailing "!"
Categories="181.FM!
Blues!
Bollywood!
Classical!
Country!
Electronic!
Hits!
Jazz!
Medley!
Metal!
News_&_Views!
Oldies!
Reggae!
Rock!
SomaFM!
Urban"


function run_stations
{
    echo "3:@disabled@"
    echo -e '\f' >> "$fpipe"

    case "$1" in
181.FM)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Blues)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Bollywood)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Classical)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Country)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Electronic)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Hits)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Jazz)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Medley)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Metal)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
"News_&_Views")
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Oldies)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Reggae)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Rock)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
SomaFM)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Urban)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
         *)
          echo "PMRP: Error! No such Category $1" >> "$ppipe"
            ;;
    esac
    echo "3:$pmrp"
}
export -f run_stations

function load_url
{
    #status_block "Station: $1  Genre: $2 url: $3"
    echo "Station: $1   Url: $3" >> $ppipe
    echo "load $3" > $cpipe
}
export -f load_url

function status_block
{
if [[ ! -z "$ERROR" ]]; then
   unset ERROR
else
  if [[ "$(echo "$1" | grep -c "^Station:*")" = 1 ]]; then
      STATION="$1"
  elif [[ "$(echo "$1" | grep -c "^Title:*")" = 1 ]];then
      TITLE="$1"
  elif [[ "$(echo "$1" | grep -c "^PMRP:*")" = 1 ]];then
      if [[ "$(echo "$1" | grep -c "^PMRP:   Error opening stream:*")" = 1 ]];then
         ERROR="$1"
      else
         STATUS="$1"
      fi
  fi

  if [[ -z "$ERROR" ]]; then
    echo "$STATION\n$STATUS\n$TITLE" >> "$statuspipe"
    echo "$(for category in $Categories; do printf "%s" "$category"; done)" >> "$statuspipe"
    echo "$pmrp" >> "$statuspipe"
  else
    echo "\n$ERROR\n" >> "$statuspipe"
    echo "$(for category in $Categories; do printf "%s" "$category"; done)" >> "$statuspipe"
    echo "$pmrp" >> "$statuspipe"
  fi
fi
}
export -f status_block

exec 3<> $fpipe
exec 4<> $ppipe
exec 5<> $cpipe
exec 6<> $statuspipe

killall mpg123 2>/dev/null
PLAYER="mpg123 --remote --fifo $cpipe --utf8 --title --preload 1 --buffer 768 --smooth"
$PLAYER 2>&1 /dev/null | awk '/@E/ || /@P/ || /@I/{if ($0=="@P 0") {print "PMRP: stop";}
                                                else {if ($0=="@P 1") {print "PMRP: paused";}
                                                else {if ($0=="@P 2") {print "PMRP: playing";}
                                                else {if ($0 ~ "@E.*") {print "PMRP:",$1="",$0;}
                                                else {if ($0 ~ "StreamTitle=*") {gsub(/^.*StreamTitle=/,"");gsub(/'\''/,"");gsub(/\;/,"");print "Title:", $0;}
                                                else {if ($0 ~ "ICY-NAME:*"){gsub(/^@I ICY-NAME:/,"");print "Station:", $0}}}}}}}
                                                {fflush(stdout)}'  | tee >(while read -r line; do status_block "$line"; done) >>"$ppipe" &  echo $! > "$PMRPID"

yad --plug="$pmkey" --tabnum=1 --form --cycle-read --field "Status":CB --field "Category":CB  \
    --image=radio --image-ontop --field="Load Stations!gtk-add:fbtn" <&6  &

yad --plug="$pmkey" --tabnum=2 --list --no-markup --dclick-action='bash -c "load_url %s"' \
    --text "Double click to play" --text-align=center --column="Name" --column="Category" --column="Url" \
    --search-column=1 --expand-column=1 --print-column="3" <&3 &

# Uncoment next line if you want to start with log
# tail -f "$ppipe" | yad --text-info --title="PMRP-Log" --tail --window-icon=radio --width=600 --height=500 --button="gtk-close" &

echo "PMRP: Ready to Play" >> "$ppipe"

# loads fields on startup
status_block "PMRP:   Poor Man's Radio Player"

yad --paned --key="$pmkey" --button="Show Log":'bash -c "tail -f -n +1 $ppipe | yad --text-info --tail --title=PMRP-Log --window-icon=radio --width=600 --height=500 --button=gtk-close" &' \
    --button="Pause/Continue":'bash -c "echo pause >> $cpipe"' \
    --button="Stop":'bash -c "echo stop >> $cpipe"'  --text="Select a Category and click to Load Stations" --width=700 --height=500 \
    --title=$"PMRP" --window-icon="radio" --posx=10 --posy=100

[[ $? == 252 ]] && echo quit >> $cpipe
echo "PMRP: Preparing for radio silence" >> "$ppipe"
# Takes a lot to quit, patience
sleep 10
# Well, sometimes it fails to quit, kill
kill $(<$PMRPID) 2>/dev/null
echo "PMRP: Zzzzzzz" >> "$ppipe"

exec 3>&-
exec 4>&-
exec 5>&-
exec 6>&-

What do you think?   :)

zephyr

#5
Looks great, single window is best! Best radio stream application I've used!



Found some music streams for 181.FM.
here

Nice job!

zephyr
CROWZ / STAR / Devuan / refracta / VSIDO

misko_2083

#6
Thanks Zephyr.  ;)
Changed the looks. It's still slow when the station is geo-blocked or unavailable (404).

#!/bin/bash
command -v mpg123 >/dev/null 2>&1 || (yad --text="PMRP requires 'mpg123' but it's not installed!\nInstall 'mpg123' to enjoy PMRP."; exit 1)

TEXTDOMAIN=ydesk
TEXTDOMAINDIR=/usr/share/locale

export pmrp='@bash -c "run_stations %2"'
export pmrp_stations="stations"

export fpipe=$(mktemp -u --tmpdir pmrp.XXXXXXXX)
export ppipe=$(mktemp -u --tmpdir ppmrp.XXXXXXXX)
export cpipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)
export statuspipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)
export PMRPID=$(mktemp -u --tmpdir PMRPID.XXXXXXXX)

mkfifo "$fpipe"
mkfifo "$cpipe"
mkfifo "$statuspipe"

trap "rm -f $fpipe $ppipe $cpipe $statuspipe $PMRPID" EXIT

pmkey=$(($RANDOM * $$))

# Categories are separated with "!" (without quotes)
# The last item in category is without trailing "!"
Categories="181.FM!
Blues!
Bollywood!
Classical!
Country!
Electronic!
Hits!
Jazz!
Medley!
Metal!
News_&_Views!
Oldies!
Reggae!
Rock!
Serbia!
SomaFM!
Urban"


function stations
{
   echo "Category: $1" >> "$ppipe"
   < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
   | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
}
export -f stations

function run_stations
{
    echo "3:@disabled@"
    echo -e '\f' >> "$fpipe"

    case "$1" in
181.FM)
          stations "$1"
    ;;
Blues)
          stations "$1"
    ;;
Bollywood)
          stations "$1"
    ;;
Classical)
          stations "$1"
    ;;
Country)
          stations "$1"
    ;;
Electronic)
          stations "$1"
    ;;
Hits)
          stations "$1"
    ;;
Jazz)
          stations "$1"
    ;;
Medley)
          stations "$1"
    ;;
Metal)
          stations "$1"
    ;;
"News_&_Views")
          stations "$1"
    ;;
Oldies)
          stations "$1"
    ;;
Reggae)
          stations "$1"
    ;;
Rock)
          stations "$1"
    ;;
Serbia)
          stations "$1"
    ;;
SomaFM)
          stations "$1"
    ;;
Urban)
          stations "$1"
    ;;
         *)
          echo "PMRP: Error! No such Category $1" >> "$ppipe"
            ;;
    esac
    echo "3:$pmrp"
}
export -f run_stations

function load_url
{
    echo "Station: $1   Url: $3" >> $ppipe
    echo "LOAD $3" >> $cpipe
    curl -Is "$3" | awk -F':' '/icy-br/{print "Bitrate:" $2}' >>$ppipe
}
export -f load_url

function status_block
{
if [[ ! -z "$ERROR" ]]; then
   unset ERROR
else
  if [[ "$(echo "$1" | grep -c "^Station:*")" = 1 ]]; then
      STATION="$1"
  elif [[ "$(echo "$1" | grep -c "^Title:*")" = 1 ]];then
      TITLE="$1"
  elif [[ "$(echo "$1" | grep -c "^PMRP:*")" = 1 ]];then
      if [[ "$(echo "$1" | grep -c "^PMRP:   Error opening stream:*")" = 1 ]];then
         ERROR="$1"
      else
         STATUS="$1"
      fi
  fi
 
  if [[ -z "$ERROR" ]]; then
    echo "$STATION\n$STATUS\n$TITLE" >> "$statuspipe"
  else
    echo "\n$ERROR\n" >> "$statuspipe"
  fi

   echo "$(for category in $Categories; do printf "%s" "$category"; done)" >> "$statuspipe"
   echo "$pmrp" >> "$statuspipe"
fi
}

exec 3<> $fpipe
exec 4<> $ppipe
exec 5<> $cpipe
exec 6<> $statuspipe

killall mpg123 2>/dev/null
# Don't use buffer here because of geo-locked stations
PLAYER="mpg123 --remote --fifo $cpipe --title --preload 1 --no-resync"
$PLAYER 2>&1 /dev/null | awk '/@E/ || /@P/ || /@I/{if ($0=="@P 0") {print "PMRP: stop";}
                                                else {if ($0=="@P 1") {print "PMRP: paused";}
                                                else {if ($0=="@P 2") {print "PMRP: playing";}
                                                else {if ($0 ~ "@E.*") {print "PMRP:",$1="",$0;}
                                                else {if ($0 ~ "StreamTitle=*") {gsub(/^.*StreamTitle=/,"");gsub(/'\''/,"");gsub(/\;/,"");print "Title:", $0;}
                                                else {if ($0 ~ "ICY-NAME:*"){gsub(/^@I ICY-NAME:/,"");print "Station:", $0}}}}}}}
                                                {fflush(stdout)}'  | while read -r line; do status_block "$line"; echo "$line" >>"$ppipe"; done &  echo $! > "$PMRPID"

yad --plug="$pmkey" --tabnum=1 --form --cycle-read --field "":TXT --field "Category":CB  \
     --image-ontop --field="Load Stations!gtk-add:fbtn" <&6  &

yad --plug="$pmkey" --tabnum=2 --list --no-markup --dclick-action='bash -c "load_url %s"' \
    --text "Double click to play" --text-align=center --column="Name" --column="Category" --column="Url" \
    --search-column=1 --expand-column=1 --print-column="3" <&3 &

# Uncoment next line if you want to start with log
# tail -f "$ppipe" | yad --text-info --title="PMRP-Log" --tail --window-icon=radio --width=600 --height=500 --button="gtk-close" &

echo "PMRP: Ready to Play" >> "$ppipe"

# loads fields on startup
status_block "PMRP:   Poor Man's Radio Player"

yad --paned --key="$pmkey" --button="Show Log":'bash -c "tail -f -n +1 $ppipe | yad --text-info --tail --title=PMRP-Log --window-icon=radio --width=600 --height=500 --button=gtk-close" &' \
    --button="Pause/Continue":'bash -c "echo pause >> $cpipe"' \
    --button="Stop":'bash -c "echo stop >> $cpipe"'  --text="Select a Category and click to Load Stations" --width=700 --height=500 \
    --title=$"PMRP" --splitter=300 --window-icon="radio" --orient=hor --image=radio --image-on-top --posx=10 --posy=100

[[ $? == 252 ]] && echo quit >> $cpipe
echo "PMRP: Preparing for radio silence" >> "$ppipe"
# Takes a lot to quit, patience
sleep 10
# Well, sometimes it fails to quit, kill
kill $(<$PMRPID) 2>/dev/null
echo "PMRP: Zzzzzzz" >> "$ppipe"

exec 3>&-
exec 4>&-
exec 5>&-
exec 6>&-

filip

@Misko

Nice work!  :) :)

Couple of notes/ideas:

1. I don't know for sure whether "mpv" has a remote control, however if it does it might be much better then "mpg123" ( atleast there woudn't be a "Quit lag" )
2. "Close to tray" would be awesome, though AFAIK it's not (yet) possible with YAD??  ???

hakerdefo

Great job Misko  8)
No one scripts better in YAD than you  8)
One of these days I'll port all the PMRP stations to the format supported by PMRP-UI. Promise  :)
Cheers!!!
You Can't Always Git What You Want

misko_2083

#9
Quote from: filip on May 05, 2017, 11:44:50 PM
@Misko

Nice work!  :) :)

Couple of notes/ideas:

1. I don't know for sure whether "mpv" has a remote control, however if it does it might be much better then "mpg123" ( atleast there woudn't be a "Quit lag" )
2. "Close to tray" would be awesome, though AFAIK it's not (yet) possible with YAD??  ???
@Filip
Thanks.  :)
mpv - That's a great idea! mpv has a remote (somewhere :)) ), I will dig into documentation.
Close to tray - It's easy to close it, bringing it back is another story  :D  :D  :D
                          Will see about that. It's a good option to have a radio that stays out of the way.
Quote from: hakerdefo on May 06, 2017, 07:17:04 PM
Great job Misko  8)
No one scripts better in YAD than you  8)
^

Quote from: hakerdefo on May 06, 2017, 07:17:04 PM
One of these days I'll port all the PMRP stations to the format supported by PMRP-UI. Promise  :)
Cheers!!!

Thank you, that would be awesome.

filip

Quote from: misko_2083 on May 07, 2017, 11:10:31 AM
@Filip
Thanks.  :)
mpv - That's a great idea! mpv has a remote (somewhere :)) ), I will dig into documentation.

Between the couch cushions perhaps!?  ;D :D :D

Joke aside, I did take a quick look @docs/google, but didn't find anything. The "bad" here is that MPV has support for real remote controlers ( the hardware ones ), which is the main hit on Google, making the shell "remote" we need here hard to find... And the docs are longer then the Bible...  ;D

Quote from: misko_2083 on May 07, 2017, 11:10:31 AM
Close to tray - It's easy to close it, bringing it back is another story  :D  :D  :D
                          Will see about that. It's a good option to have a radio that stays out of the way.

"Kill to tray" ;D ;D

Maybe if there is an easy way to keep information about current station/log etc somewhere it might be doable with something like ( untested, just a thought ):


function main() {

if [[ "$LOG_AND_CURRENT_STATION_AND_OTHER_DATA" = true ]]
# main dialog stuff in here with the "--button=Close!close:1" & "DATA" appended somehow
else
# main dialog stuff in here with the "--button=Close!close:1"
fi

RET=$?
if [[ "$RET" == 1 ]]; then
WIN_VISIBLE=false
else
WIN_VISIBLE=true
fi
}
export main
main

function window_toggle() {
# called on tray left click
if [[ "$WIN_VISIBLE" = true ]]; then
main
fi
}


The bad side with the above is that you cannot click the tray icon to toggle the window. In other words, window needs to be closed the usual ways, and can only be brought back from tray with the "on tray" click.
Hope it helps some. :)
Cheers!

hakerdefo

This is for misko and filip. I hope it will be useful  :)

A small script for controlling mpv via the JSON IPC

JSON IPC

Cheers!!!
You Can't Always Git What You Want

misko_2083

Quote from: filip on May 07, 2017, 08:36:44 PM
Between the couch cushions perhaps!?  ;D :D :D
Joke aside, I did take a quick look @docs/google, but didn't find anything. The "bad" here is that MPV has support for real remote controlers ( the hardware ones ), which is the main hit on Google, making the shell "remote" we need here hard to find... And the docs are longer then the Bible...  ;D
Whish it was between the couch cushions... That was a a big documentation to read.  :D
Found some usefull options on the way...
Mpv loads entire list file at once, and I had to do "playlist_remove current" to load a new list.
After sorting that out, the rest weas relatively easy.
Instead of saving the current song metadata, we call it with the internal print command 'print_text ${metadata}'.
That way it fills in the text column after returning from tray.
*Changes
1. Now uses mpv
2. Close to tray option added
*What doesn't work?
1. error status
2. category is lost when returning from tray
#!/bin/bash
command -v mpv >/dev/null 2>&1 || (yad --text="PMRP requires 'mpv' but it's not installed!\nInstall 'mpv' to enjoy PMRP."; exit 1)

TEXTDOMAIN=ydesk
TEXTDOMAINDIR=/usr/share/locale

export LANG=C.UTF-8

export pmrp='@bash -c "run_stations %2"'
export pmrp_stations="stations"

export fpipe=$(mktemp -u --tmpdir pmrp.XXXXXXXX)
export ppipe=$(mktemp -u --tmpdir ppmrp.XXXXXXXX)
export cpipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)
export statuspipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)
export PMRPLIST=$(mktemp -u --tmpdir PMRPLIST.XXXXXXXX)

# Pipe for setting values in the form tab
mkfifo "$fpipe"
# control pipe - send commands to mpv
mkfifo "$cpipe"
# status pipe - send text to left text pane
mkfifo "$statuspipe"

# Create the list file
> $PMRPLIST

trap "rm -f $fpipe $ppipe $cpipe $statuspipe $PMRPLIST" EXIT

pmkey=$(($RANDOM * $$))

# Categories are separated with "!" (without quotes)
# The last item in category is without trailing "!"
Categories="181.FM!
Blues!
Bollywood!
Classical!
Country!
Electronic!
Hits!
Jazz!
Medley!
Metal!
News_&_Views!
Oldies!
Reggae!
Rock!
Serbia!
SomaFM!
Urban"


function stations
{
   echo "Category: $1" >> "$ppipe"
   < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
   | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
}
export -f stations

function run_stations
{
    echo "3:@disabled@"
    echo -e '\f' >> "$fpipe"

    case "$1" in
181.FM)
          stations "$1"
    ;;
Blues)
          stations "$1"
    ;;
Bollywood)
          stations "$1"
    ;;
Classical)
          stations "$1"
    ;;
Country)
          stations "$1"
    ;;
Electronic)
          stations "$1"
    ;;
Hits)
          stations "$1"
    ;;
Jazz)
          stations "$1"
    ;;
Medley)
          stations "$1"
    ;;
Metal)
          stations "$1"
    ;;
"News_&_Views")
          stations "$1"
    ;;
Oldies)
          stations "$1"
    ;;
Reggae)
          stations "$1"
    ;;
Rock)
          stations "$1"
    ;;
Serbia)
          stations "$1"
    ;;
SomaFM)
          stations "$1"
    ;;
Urban)
          stations "$1"
    ;;
         *)
          echo "PMRP: Error! No such Category $1" >> "$ppipe"
            ;;
    esac
    echo "3:$pmrp"
}
export -f run_stations

function load_url
{
    echo "Station: $1   Url: $3" >> $ppipe   
    # Station to the list
    echo "$3" > $PMRPLIST
    # Unload current Playlist
    echo "playlist_remove current" > $cpipe
    # Load list
    echo "loadlist $PMRPLIST" > $cpipe
}
export -f load_url

function status_block
{
if [[ ! -z "$PMRP" ]]; then
   unset PMRP
else
  if [[ "$(echo "$1" | grep -c "^Name*")" = 1 ]]; then
      STATION="$1"
  elif [[ "$(echo "$1" | grep -c "^Title*")" = 1 ]];then
      TITLE="$1"
  elif [[ "$(echo "$1" | grep -c "^Bitrate")" = 1 ]];then
      BITRATE="$1 Kb/s"
  elif [[ "$(echo "$1" | grep -c "^PMRP:*")" = 1 ]];then
      PMRP="$1"
  fi
 
  if [[ -z "$PMRP" ]]; then
    echo "$STATION\n$BITRATE\n$TITLE" >> "$statuspipe"
  else
    echo "\n$PMRP\n" >> "$statuspipe"
  fi

   echo "$(for category in $Categories; do printf "%s" "$category"; done)" >> "$statuspipe"
   echo "$pmrp" >> "$statuspipe"
fi
}

exec 3<> $fpipe
exec 4<> $ppipe
exec 5<> $cpipe
exec 6<> $statuspipe

echo "PMRP: Ready to Play" >> "$ppipe"

killall mpv 2>/dev/null

  mpv --playlist=$PMRPLIST --input-file=$cpipe --cache 2048 --no-config --idle=yes 2>&1 \
     | awk '/[statusline]/{if ($0 ~ "icy-br:*") {gsub(/^.*icy-br:/,"");print "Bitrate  ", $0 ;}
                                 else {if ($0 ~ "icy-name:*") {gsub(/^.*icy-name:/,"");print "Name    ", $0;}
                                 else {if ($0 ~ "icy-genre:*") {gsub(/^.*icy-genre:/,"");print "Genre -", $0;}
                                 else {if ($0 ~ "icy-title:*") {gsub(/^.*icy-title:/,"");print "Title        ", $0;}}}}}
                                 {fflush(stdout)}'  | while read -r line; do status_block "$line"; echo "$line" >>"$ppipe"; done &
function main() {
  yad --plug="$pmkey" --tabnum=1 --form --cycle-read --field "":TXT --field "Category":CB  \
     --image-ontop --field="Load Stations!gtk-add:fbtn" <&6  &

  yad --plug="$pmkey" --tabnum=2 --list --no-markup --dclick-action='bash -c "load_url %s"' \
    --text "Double click to play" --text-align=center --column="Name" --column="Category" --column="Url" \
    --search-column=1 --expand-column=1 --print-column="3" <&3 &

  # Uncoment next line if you want to start with log
  # tail -f "$ppipe" | yad --text-info --title="PMRP-Log" --tail --window-icon=radio --width=600 --height=500 --button="gtk-close" &

  # loads fields on startup
  status_block "PMRP:   Poor Man's Radio Player"

  # Reprints metadata after returning from tray
  echo 'print_text ${metadata}' > $cpipe

  yad --paned --key="$pmkey" --button="Close to Tray!gtk-close":1 \
      --button="Show Log":'bash -c "tail -f -n +1 $ppipe | yad --text-info --tail --title=PMRP-Log --window-icon=radio --width=600 --height=500 --button=gtk-close" &' \
      --button="Pause/Continue":'bash -c "echo cycle pause >> $cpipe"' \
      --button="Stop":'bash -c "echo stop >> $cpipe"'  --text="Select a Category and click to Load Stations" --width=700 --height=500 \
      --title=$"PMRP" --splitter=300 --window-icon="radio" --orient=hor --image=radio --image-on-top --posx=10 --posy=100
RET="$?"

case $RET in
  252)
    echo "quit" >> $cpipe
    echo "PMRP: Preparing for radio silence" >> "$ppipe"
    echo "PMRP: Zzzzzzz" >> "$ppipe"
    ;;
   1)  yad --notification   \
          --image="radio"  \
          --text="PMRP"
        # Need to do this after returned from tray
        status_block ""
main
    ;;
   *) exit 1
    ;;
esac
}
main

exec 3>&-
exec 4>&-
exec 5>&-
exec 6>&-


@hakerdefo thanks. ;)

zephyr

#13
Thanks to you both, hakerdefo and misko, great radio application. My "go to" now for radio music streams!



thanks again!

z

CROWZ / STAR / Devuan / refracta / VSIDO