如何在Python中将音频流发送到Icecast服务器

问题描述 投票:0回答:1

我在尝试使用 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”这样的库来做到这一点

python http python-requests icecast icecast2
1个回答
0
投票

您不能以任意速度将音频发送到服务器。您必须以播放速度发送它。

服务器并不真正了解或关心流中的计时信息。它只是缓冲一点,当客户端连接时,它会从缓冲区读取数据,并向它们发送新的数据。因此,如果您将一个小时的音频以最快的速度通过服务器,那么只会有一个客户端连接时可以使用几秒钟的缓冲区。

我知道你说你不想为此使用其他库,但你可能应该这样做。您实际上需要创建连续的流,而不仅仅是一个又一个地发送文件。这意味着您所有分类的音频文件都会以正确的速率“播放”到 PCM 到编解码器,并将来自编解码器的编码数据发送到服务器。这是相当需要重新发明的。至少,您必须以正确的速率发送预编码文件,并且这些文件必须不含 ID3 标签,并且需要具有相同的采样率和通道格式。

© www.soinside.com 2019 - 2024. All rights reserved.