0

I need to extract the ICY metadata from a live audio stream and was looking at doing this using mplayer as this outputs the metadata as it plays the audio stream. I'm open to other ways of doing this, the goal is to have the updated metadata (song info) saved to a text file that will update whenever the song (or data) changes.

One of the reasons I want to use mplayer is to ensure it works on the most diverse streams available (rather than just Shoutcast/Icecast).

I am able to extract the metadata now using this simple line : mplayer http://streamurl

The problem is that I do not want to keep calling it every x seconds as it fills up the destination server logs with x second calls (connect/disconnect).

I'd rather have it permanently connected to the stream and use the output of mplayer to output the icy metadata whenever the song updates.

The reason I do not want to just connect every x seconds is because I need quite a bit of granularity and would be checking every 10-15 seconds for an update.

I'd be happy to do this a different way, but would ultimately need the data outputted to a .txt file somehow.

Any pointers on how to achieve this would be greatly appreciated.

omega1
  • 1,031
  • 4
  • 21
  • 41

1 Answers1

0

What I did was to run it in a thread and capture its output. that way, you can do whatever you want with it: call a function to update a variable, for example.

For example:

class Radio:
    radio = None
    stream_text = None
    t1 = None

    def __init__(self, radio):
        self.radio = radio

    def getText(self):

        if self.stream_text:
            return self.stream_text
        return ""

    def setURL (self,radio):
        self.radio = radio
    def run(self):
        self.t1 = threading.Thread(target=self.start)
        self.t1.start()

    def start(self):
        self.p= subprocess.Popen(['mplayer','-slave','-quiet', self.radio], stdin=subprocess.PIPE, stdout=subprocess.PIPE,universal_newlines=True, bufsize = 1)
        for line in self.p.stdout:
            if line.encode('utf-8').startswith(b'ICY Info:'):
                info = line.split(':', 1)[1].strip()
                attrs = dict(re.findall("(\w+)='([^']*)'", info))
                self.stream_text = attrs.get('StreamTitle', '(none)')

By calling getText() every second, I'd get up-to-date info, but of course instead of doing it this way, you can send a call back function to be executed with every new update.

francisaugusto
  • 1,077
  • 1
  • 12
  • 29