簡體   English   中英

使用python流mp3 icecast數據

[英]Stream mp3 icecast data using python

我正在嘗試編寫自己的套接字流媒體,在這里我使用python的套接字連接到已知的mp3源,傳輸數據並將其作為pcm數據傳遞到alsaaudio中。

我知道必須獲取icy-metaint,讀取那么多字節,獲取元數據長度的第一個字節,然后繼續讀取metaint字節。

不幸的是,我用完了所有的知識,下面的代碼導致播放白噪聲。

任何幫助都將是驚人的。 謝謝!

#!/usr/bin/env python
import socket
import sys
import alsaaudio
import time
import threading
import Queue

class Player(threading.Thread):

    def __init__(self, messageQueue, metaint):
        threading.Thread.__init__(self)

        self.metaint = metaint

        self.messageQueue = messageQueue
        self.device = alsaaudio.PCM()
        self.rate = 44100
        self.famesize = self.rate 
        self.device.setrate(self.rate)
        self.buffer = ""

    def sendPCM(self):
        print("Buffer length: " + str(len(self.buffer)))
        if len(self.buffer) > self.metaint + 255:
            pcmData = self.buffer[:self.metaint]
            self.device.write(pcmData)
            self.buffer = self.buffer[self.metaint:]
            print ("New buffer length 1: " + str(len(self.buffer)))
            metaDataLength = ord(self.buffer[:1]) * 16
            print ("Metadata length: " + str(metaDataLength))
            self.buffer = self.buffer[1:]
            print ("New buffer length 2: " + str(len(self.buffer)))
            metaData = self.buffer[:metaDataLength]
            print len(metaData)
            self.buffer = self.buffer[metaDataLength:]
            print ("New buffer length 3: " + str(len(self.buffer)))


    def run(self):
        self.sendPCM()
        while True:
            message = self.messageQueue.get()
            if message: self.buffer += message
            self.sendPCM()
            self.messageQueue.task_done()

def getResponseHeaders(socket):
    data = socket.recv(1024)

    while not "\r\n\r\n" in data:
        data = data + socket.recv(1024)

    return data

def getHeaders(response):
    headers = {}
    for line in response.splitlines():
        if line == '\r\n':
            break # end of headers
        if ':' in line:
            key, value = line.split(':', 1)
            headers[key] = value

    return headers


HOST = 'bbcmedia.ic.llnwd.net'
GET = '/stream/bbcmedia_lc1_radio1_p?s=1420917253&e=1420931653&h=1ff16ea945bd420669c48ae72d003c09'
PORT = 80

#create an INET, STREAMing socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((HOST, PORT))
client_socket.send("GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent:%s\r\nIcy-MetaData:%s\r\nRange:%s\r\n\r\n" % (GET, HOST,"VLC/2.0.5 LibVLC/2.0.5", "1", "bytes=0-"))

responseHeaders = getResponseHeaders(client_socket)
headers = getHeaders(responseHeaders)
metaint = int(headers['icy-metaint'])
br = int(headers['icy-br'])
print (metaint)



queue = Queue.Queue()

player = Player(queue, metaint)
player.daemon = True
player.start()

while 1:
    queue.put(client_socket.recv(4096))


client_socket.close()
sys.exit(0)

看起來您實際上不是在解碼音頻數據。

您正在嘗試從元數據中解復用音頻數據,但還必須通過編解碼器運行音頻數據以獲取PCM樣本。 SHOUTcast / Icecast服務器不發送原始PCM。 他們通常使用包裝在ADTS中的MP3或AAC。

我不是Python編碼員,所以我不知道您擁有什么。 一種簡單的解碼方法是使用FFmpeg。 它支持STDIO,因此您可以輕松地將數據傳輸到它,並讓它處理流並返回PCM樣本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM