我在尝试使用 Python 将音频数据从文件正确发送到 Icecast 服务器时遇到一些问题。
这是我的课:
import requests
from base64 import b64encode
class IcecastClient:
def __init__(self, host, port, mount, user, password, audio_info):
self.host = host
self.port = port
self.mount = mount
self.user = user
self.password = password
self.audio_info = audio_info # Additional audio information
self.stream_url = f"http://{host}:{port}{mount}"
def connect(self):
# Basic Auth Header
auth_header = b64encode(f"{self.user}:{self.password}".encode()).decode("ascii")
self.headers = {
'Authorization': f'Basic {auth_header}',
'Content-Type': 'audio/mpeg',
'Ice-Public': '1',
'Ice-Name': 'Auralyra Stream',
'Ice-Description': 'Streaming with Auralyra',
'Ice-Genre': 'Various',
'Ice-Audio-Info': self.audio_info
}
def stream_audio_file(self, file_path, chunk_size=4096):
with requests.Session() as session:
session.headers = self.headers
with open(file_path, 'rb') as audio_file:
while True:
chunk = audio_file.read(chunk_size)
if not chunk:
break # End of file
try:
response = session.put(self.stream_url, data=chunk)
if response.status_code != 200:
print(f"Streaming failed: {response.status_code} - {response.reason}")
break
except requests.RequestException as e:
print(f"Error while sending audio chunk: {e}")
break
if response.status_code == 200:
print("Streaming successful")
def send_audio(self, audio_chunk):
try:
# Send the chunk using the session with predefined headers
response = self.session.put(self.stream_url, data=audio_chunk)
if response.status_code != 200:
print(f"Streaming failed: {response.status_code} - {response.reason}")
except Exception as e:
print(f"Error while sending audio chunk: {e}")
问题在于,虽然 Icecast 可以识别流并且挂载点的状态看起来不错,但尝试监听流根本不起作用。我的猜测是,这与我如何将数据发送到服务器有关。
PS:我试图避免使用像“shout”这样的库来做到这一点
您不能以任意速度将音频发送到服务器。您必须以播放速度发送它。
服务器并不真正了解或关心流中的计时信息。它只是缓冲一点,当客户端连接时,它会从缓冲区读取数据,并向它们发送新的数据。因此,如果您将一个小时的音频以最快的速度通过服务器,那么只会有一个客户端连接时可以使用几秒钟的缓冲区。
我知道你说你不想为此使用其他库,但你可能应该这样做。您实际上需要创建连续的流,而不仅仅是一个又一个地发送文件。这意味着您所有分类的音频文件都会以正确的速率“播放”到 PCM 到编解码器,并将来自编解码器的编码数据发送到服务器。这是相当需要重新发明的。至少,您必须以正确的速率发送预编码文件,并且这些文件必须不含 ID3 标签,并且需要具有相同的采样率和通道格式。