1

I am learning Python these days for data-science, ML and network programming amongst other things. I am trying to implement a simple Icecast client to stream live audio to Icecast server such as RadioKing and Caster.fm. My code is as here.

import pyaudio
from pydub import AudioSegment
import requests
import base64

FORMAT = pyaudio.paInt16
CHANNELS = 1
SAMPLERATE = 44100
CHUNK = 1024
#
audio = pyaudio.PyAudio()
stream = audio.open(format=FORMAT, channels=CHANNELS,
                    rate=SAMPLERATE, input=True,
                    frames_per_buffer=CHUNK)
#
raw_audio_data = stream.read(CHUNK)

audio_segment = AudioSegment(
    data=raw_audio_data,
    sample_width=audio.get_sample_size(FORMAT),
    frame_rate=SAMPLERATE,
    channels=CHANNELS
)
encoded_audio_bytes = audio_segment.export(format="ogg").read()

#
ICECAST_HOST = "https://sapircast.caster.fm"
ICECAST_PORT = 15754
MOUNT_POINT = "/iCVJp"
USERNAME = "source"
PASSWORD = "m5auo6W0vP"
#
enc_pw = base64.b64encode(f"{USERNAME}:{PASSWORD}".encode()).decode("iso-8859-1")
plain_pw = f"{USERNAME}:{PASSWORD}"
#
stream_url = f"{ICECAST_HOST}:{ICECAST_PORT}{MOUNT_POINT}"
session = requests.Session()
session.auth = (f"{USERNAME}", f"{PASSWORD}")
ice_headers = {
    "User-Agent": "python-requests/2.24.0",
    "Accept-Encoding": "gzip, deflate",
    "Accept": "*/*",
    "Connection": "keep-alive",
    "Authorization": f"Basic {enc_pw}",
    "Content-Type": "audio/opus",
    "icy-pub": "1",
    "icy-genre": "*",
    "ice-name": "Test",
    "ice-description": "Test stream",
    "ice-url": f"{ICECAST_HOST}",
    "ice-bitrate": "96",
    "ice-audio-info": "ice-channels=2;ice-bitrate=96;ice-samplerate=44100;",
}
#
while True:
    try:
        response = session.put(stream_url, data=encoded_audio_bytes, timeout=120, headers=ice_headers, stream=True)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print(f"Error sending audio to Icecast: {e}")
    except requests.exceptions.HTTPError as e:
        print(f"Error sending audio to Icecast: {e}")

When I run the programme with Caster.fm server running, the programme fails to make connection. What am I doing wrong? Please, help. A typical output is as below: -

/usr/bin/python3 /Users/awaismushtaq/PycharmProjects/IcecastSender/icastsender.py 
/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning:

urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020

Error sending audio to Icecast: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error sending audio to Icecast: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error sending audio to Icecast: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error sending audio to Icecast: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Error sending audio to Icecast: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Traceback (most recent call last):
  File "/Users/awaismushtaq/PycharmProjects/IcecastSender/icastsender.py", line 57, in <module>
    response = session.put(stream_url, data=encoded_audio_bytes, timeout=120, headers=ice_headers, stream=True)
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/requests/sessions.py", line 649, in put
    return self.request("PUT", url, data=data, **kwargs)
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/requests/adapters.py", line 644, in send
    resp = conn.urlopen(
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    response = self._make_request(
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/connectionpool.py", line 464, in _make_request
    self._validate_conn(conn)
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/connectionpool.py", line 1093, in _validate_conn
    conn.connect()
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/connection.py", line 753, in connect
    self.sock = sock = self._new_conn()
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/connection.py", line 198, in _new_conn
    sock = connection.create_connection(
  File "/Users/awaismushtaq/Library/Python/3.9/lib/python/site-packages/urllib3/util/connection.py", line 73, in create_connection
    sock.connect(sa)
KeyboardInterrupt

Process finished with exit code 130 (interrupted by signal 2:SIGINT)
1
  • Based on quick review. Use http:// not https:// for Icecast streams, send one continuous PUT/SOURCE request, not one per chunk, use socket or python-shout, not requests. Commented Oct 23 at 18:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.