kirtan-shah / nowplaying-cli

macOS command-line utility for retrieving currently playing media
GNU General Public License v3.0
154 stars 9 forks source link

json output? #17

Open daniel-white opened 8 months ago

daniel-white commented 8 months ago

Would you consider adding a JSON output to allow tools like jq to parse this?

kirtan-shah commented 8 months ago

I would. Could you elaborate on what output you'd like to generate with a nowplaying-cli | jq | xyz pipeline that can't be done currently?

daniel-white commented 8 months ago

i'm thinking it would be beneficial to hook into my shell's prompt and i can mix and match with jq since its a more regular structure with json

kirtan-shah commented 8 months ago

you can do nowplaying-cli artist title playbackRate ... to retrieve multiple properties separated by newlines. Is there a specific format you're thinking of where json would be more useful?

rogeruiz commented 3 weeks ago

hi @kirtan-shah I ran into this issue myself.

Is there a specific format you're thinking of where json would be more useful?

For my needs, JSON would be better so I can parse individual fields and build a string using jq rather than parse new lines from the output of the tool. I'm integrating this into a script that runs in my SketchyBar.

I'd like to get JSON output from the tool so I can pull all of the necessary information from nowplaying-cli in a single command. Without JSON output, I've had to do some string manipulation with sed to convert the output into something that jq can parse.

I'm using sed below to create JSON output for now.

#!/bin/bash

raw=$(nowplaying-cli get-raw)
key_prefix="kMRMediaRemoteNowPlayingInfo"

json=$(
  sed 's/ =/:/' <(echo "${raw}") | # replace all ` =` with `:`
    sed 's/;/,/' | # replace all `;` with `,`
    sed -r 's/\\[A-Za-z0-9]+ //' | # replace any UNICODE escape sequences (`\U25ba`) with ``
    sed -r "s/(${key_prefix}[A-Za-z]+)/\"\1\"/" | # wrap all keys in quotes
    sed -r "s/(\"${key_prefix}UniqueIdentifier\": .+),/\1/" # guess the last key and replace the `,` with ``
)

echo "${json}" | jq .

It's not perfect and there are some keys that I need to remove completely in order to properly encode this into JSON. Also this solution messes up whenever there are UNICODE escape characters.

rogeruiz commented 3 weeks ago

I also have another way to pull sections of the nowplaying-cli get <prop> output in a better way with Bash associative arrays which does what I need for now. While JSON support would be nice, I believe it might be too much work given the escape sequences that some of the values of properties have in them.

See the updated gist here: https://gist.github.com/rogeruiz/817a92a4919db531baf1c184f842516b

declare -A info=(
  [artist]=''
  [title]=''
  [album]=''
  [isMusicApp]=''
)
count=0

nowplaying-cli get artist title album isMusicApp | {
  while read -r line; do
    case ${count} in
    0) info[artist]+=" $line" ;;
    1) info[title]+=" $line" ;;
    2) info[album]+=" $line" ;;
    3) info[isMusicApp]+=" $line" ;;
    *) ;;
    esac
    count=$((count + 1))
  done

  # declare -n info
  echo "artist: ${info[artist]}"
  echo "title: ${info[title]}"
  echo "album: ${info[album]}"
  echo "isMusicApp: ${info[isMusicApp]}"
}