Page 1 of 1

Shairport-sync metadata to websocket

Posted: Sat Nov 04, 2017 9:10 pm
by TheMiddle36
Hi everyone,

I’ve successfully been able to get the awesome Shairport-Sync to send currently playing meta data via PIPE to text files which are then periodically polled by my webpage to display the contents; artist, track title, and album name.

I’ve not yet worked out how to decode the album art, so am instead using an API and downloading the .png file.

As you can imagine, polling text files isn’t that efficient so I looked in to WebSockets to push the data to the webpage instead.

The following writes the PIPE output to files:

Code: Select all

import os
import time
import subprocess
from shutil import copyfile

#send values to files from pipe

cmd = "shairport-sync-metadata-reader < /tmp/shairport-sync-metadata"
proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)

x = 1
while True:

  line = proc.stdout.readline().decode()
  if line != '':
    wordKeys = ["Artist", "Title", "Album", "pbeg", "pend"]
    lineNow = line.rstrip()
    lineNow = lineNow.replace('"', '').strip()
    lineNow = lineNow.replace('.', '').strip()
    head, sep, tail = lineNow.partition(': ')
    for key in wordKeys:
        if key in lineNow:
            ####### update music status file #######
            if key == "pbeg":
              print ("Playing music!")
              s = open('/var/www/html/shairport-sync-metadata-webserver/shairport_status' ,'w')
            elif key == "pend":
              print ("Stopping music!")
              s = open('/var/www/html/shairport-sync-metadata-webserver/shairport_status' ,'w')
            elif key:
              f = open('/var/www/html/shairport-sync-metadata-webserver/' + head,'w') #create files for each wordkey
              newtail = tail.replace(':', '').strip()
              print ("**** updated: " + head + " = " + newtail)
#    print ("No input source")

And the following will initiate a websocket server. What I’d like to do is feed the PIPE output to the websockets using the

Code: Select all

command that can then be picked up in the browser... I think.

But I’m struggling to get the two pieces of code to work as one. Any help?

Code: Select all

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web

class WSHandler(tornado.websocket.WebSocketHandler):
  def check_origin(self, origin):
    return True
  def open(self):
    print 'New connection was opened'
    self.write_message("Welcome to my websocket!")

  def on_message(self, message):
    print 'Incoming message:', message
    self.write_message("You said: " + message)

  def on_close(self):
    print 'Connection was closed...'

application = tornado.web.Application([
  (r'/ws', WSHandler),

if __name__ == "__main__":
  http_server = tornado.httpserver.HTTPServer(application)

Re: Shairport-sync metadata to websocket

Posted: Wed Nov 08, 2017 10:58 am
by TheMiddle36

Depending on what order I put parts of the scripts I usually get one bit of functionality working or the other.

Self.write_message() is undefined though, even after it has explicitly been defined!

Re: Shairport-sync metadata to websocket

Posted: Thu Nov 09, 2017 10:18 am
by elParaguayo
I've not done anything with tornado/websockets before but I like shairport-sync so I'm happy to help if I can. I wrote some code a while ago for retrieving metadata but, at the time, I had no interest in getting the artwork - I can dig out that code and have a look.

As for the websockets stuff, can you post your code where you've tried to combine your scripts and I'll have a go on my laptop when I get a chance. Presumably you've also got a simple webpage to communicate with your python script, is that code you can share too?

It does seem a bit odd that write_message isn't working when it's a method in tornado.websocket.WebSocketHandler which you've subclassed.

Re: Shairport-sync metadata to websocket

Posted: Mon Feb 05, 2018 8:25 am
by idubnori
It is a metadata parser which contains artwork image acquisition and its example app has used websocket. But, its implementation is not Python. ... nfo-reader

Wondering if, hope this helps.