Search code examples
pythonmp3icecast

Analysing MP3 stream for Silence


I would like to detect silence from an icecast radio stream, i have attempted the following code, however when i silence the stream the rms value stays the same where i would expect a close to zero value: any help

Code:

from urllib import urlopen
import audioop, numpy as np



url =  "http://localhost:8382/listen.mp3"
u = urlopen(url)
data = u.read(8192)

while data:
        data = u.read(8192)
        #rms = audioop.rms(data, 2) 
        d = np.frombuffer(data, np.int16)
        numpy_rms = np.sqrt(sum(d*d)/len(d))
        print numpy_rms, audioop.rms(data, 2)
        #print rms
        print (min(d), max(d)), audioop.minmax(data,2)

alternate to analysing live stream, but not preferred option: i have considered saving a 10 second mp3 files from the stream but not i am not sure how to analyse MP3. se code below

Code:

#! /usr/bin/env python
import argparse
from icerec.stream_writer import StreamWriter
from pprint import pprint

parser = argparse.ArgumentParser(description='Tool that will record a icecast stream.')

parser.add_argument('url', help="Icecast stream URL")
parser.add_argument('length', type=int, help="Length of time to record stream (in seconds)")
parser.add_argument('-d', '--destination', default="./", 
                    help="File destination. Defaults to current directory")
parser.add_argument('-f', '--filename', default="output.mp3", help="File name of saved stream")

args = parser.parse_args()

s = StreamWriter( args.url, args.length, destination=args.destination, filename=args.filename)

s.record()
pprint(s.metadata)

Solution

  • I come up with this solution.

    #! /usr/bin/env python
    from icerec.stream_writer import StreamWriter
    from pprint import pprint
    import array
    import httplib,urllib
    from pydub.utils import get_array_type
    
    from pydub.playback import play
    from pydub.utils import mediainfo
    from pydub import AudioSegment
    from pydub.silence import split_on_silence
    import numpy as np
    import  audioop
    
    poURL = 'api.pushover.net:443'
    apikey = 'xxxxxxxxxxxxxx'
    
    #pushover_alert################################################################
    def Notify(poApiKey, poUserKey, poTitle, poMessage, poPriority,poSound):
            conn = httplib.HTTPSConnection(poURL)
            conn.request('POST', '/1/messages',
            urllib.urlencode({
            'token': poApiKey,
            'user': poUserKey,
            'token': poApiKey,
            'user': poUserKey,
            'title': poTitle,
            'message': poMessage,
            'priority': poPriority,
            'sound': poSound,
            }), { 'Content-type': 'application/x-www-form-urlencoded' })
    
    while True:
    
            try:
                    s = StreamWriter( "http://localhost:8382/listen.mp3", 0.5, destination="/var/www/html/", filename="output.mp3")
                    s.record()
                    #pprint(s.metadata)
                    sound = AudioSegment.from_mp3("/var/www/html/output.mp3")
    
    
                    bit_depth = sound.sample_width * 8
                    array_type = get_array_type(bit_depth)
                    numeric_array = array.array(array_type, sound._data)
                    info = mediainfo("/var/www/html/output.mp3")
                    #print numeric_array
                    if sound.rms <10:
                            i += 1
                    else:
                            i = 0
    
                    if i  == 5:
                            mesg = 'Qkradio Stream Silence Detected for more than 5seconds'
                            print 'alert sent', mesg
                            Notify('xxxxxxxxxxxx','xxxxxxxxxxxxx','Aquarium controller',mesg,0,'siren')
                    print i ,"\tfile rms:", sound.rms,"\tfile loudness:", sound.dBFS, "\tPeak Amplitude:", sound.max,"\tlength:", len(sound),"\tSample rate:" ,info['sample_rate']
            except:
                    print "error"