Skip to content

Commit

Permalink
update to miniaudio 0.11.14 , added ssl_context to IceCastClient
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Mar 30, 2023
1 parent 9851563 commit 9185502
Show file tree
Hide file tree
Showing 4 changed files with 4,415 additions and 2,471 deletions.
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,13 @@ this generator as a stream source. The data can be provided in ``array`` type o
the audio data has, and the sample with in bytes.


*function* ``stream_with_callbacks (sample_stream: Generator[Union[bytes, array.array], int, NoneType], progress_callback: Optional[Callable[[int], NoneType]] = None, frame_process_method: Union[Callable[[array.array], array.array], None] = None, end_callback: Optional[Callable] = None) -> Generator[Union[bytes, array.array], int, NoneType]``
> Convenience generator function to add callback and processing functionality to another stream. You can specify:
A callback function that gets called during play and takes an ``int``
for the number of frames played.
A function that can be used to process raw data frames before they are yielded back
(takes an ``array.array`` and returns an ``array.array``)
*Note: if the processing method is slow it will result in audio glitchiness*
A callback function that gets called when the stream ends playing.
*function* ``stream_with_callbacks (sample_stream: Generator[Union[bytes, array.array], int, NoneType], progress_callback: Optional[Callable[[int], NoneType]] = None, frame_process_method: Optional[Callable[[Union[bytes, array.array]], Union[bytes, array.array]]] = None, end_callback: Optional[Callable] = None) -> Generator[Union[bytes, array.array], int, NoneType]``
> Convenience generator function to add callback and processing functionality to another stream. You
can specify : > A callback function that gets called during play and takes an int for the number of
frames played. > A function that can be used to process raw data frames before they are yielded
back (takes an array.array or bytes, returns an array.array or bytes) *Note: if the processing
method is slow it will result in audio glitchiness > A callback function that gets called when the
stream ends playing.


*function* ``vorbis_get_file_info (filename: str) -> miniaudio.SoundFileInfo``
Expand Down Expand Up @@ -419,12 +418,14 @@ already be started before passing it in)

*class* ``IceCastClient``

``IceCastClient (self, url: str, update_stream_title: Callable[[ForwardRef('IceCastClient'), str], NoneType] = None) ``
``IceCastClient (self, url: str, update_stream_title: Callable[[ForwardRef('IceCastClient'), str], NoneType] = None, ssl_context: 'ssl.SSLContext' = None) ``
> A simple client for IceCast audio streams as miniaudio streamable source. If the stream has Icy
Meta Data, the stream_title attribute will be updated with the actual title taken from the meta
data. You can also provide a callback to be called when a new stream title is available. The
downloading of the data from the internet is done in a background thread and it tries to keep a
(small) buffer filled with available data to read.
MetaData, the stream_title attribute will be updated with the actual title taken from the metadata.
You can also provide a callback to be called when a new stream title is available. The downloading
of the data from the internet is done in a background thread and it tries to keep a (small) buffer
filled with available data to read. You can optionally provide a custom ssl.SSLContext in the
ssl_context parameter, if you need to change the way SSL connections are configured (certificates,
checks, etc).

> *method* ``close (self) ``
> > Stop the stream, aborting the background downloading.
Expand Down Expand Up @@ -464,7 +465,7 @@ The generator should already be started before passing it in.

*class* ``SoundFileInfo``

``SoundFileInfo (self, name: str, file_format: miniaudio.FileFormat, nchannels: int, sample_rate: int, sample_format: miniaudio.SampleFormat, duration: float, num_frames: int) ``
``SoundFileInfo (self, name: str, file_format: miniaudio.FileFormat, nchannels: int, sample_rate: int, sample_format: miniaudio.SampleFormat, duration: float, num_frames: int, sub_format: int = None) ``
> Contains various properties of an audio file.

Expand Down
10 changes: 9 additions & 1 deletion examples/internetradio.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@
def title_printer(client: miniaudio.IceCastClient, new_title: str) -> None:
print("Stream title: ", new_title)

source = miniaudio.IceCastClient(url, update_stream_title=title_printer)
# you can optionally pass a SSL context in the 'ssl_context' keyword argument,
# to configure the SSL connection.
# For instance, to disable the SSL certificate check:
# import ssl
# ctx = ssl.create_default_context()
# ctx.check_hostname = False
# ctx.verify_mode = ssl.CERT_NONE
# and then create the IceCastClient with ssl_context=ctx
source = miniaudio.IceCastClient(url, update_stream_title=title_printer, ssl_context=None)
print("Connected to internet stream, audio format:", source.audio_format.name)
print("Station name: ", source.station_name)
print("Station genre: ", source.station_genre)
Expand Down
13 changes: 8 additions & 5 deletions miniaudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Software license: "MIT software license". See http://opensource.org/licenses/MIT
"""

__version__ = "1.55"
__version__ = "1.56"


import abc
Expand Down Expand Up @@ -1130,17 +1130,20 @@ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
class IceCastClient(StreamableSource):
"""
A simple client for IceCast audio streams as miniaudio streamable source.
If the stream has Icy Meta Data, the stream_title attribute will be updated
with the actual title taken from the meta data.
If the stream has Icy MetaData, the stream_title attribute will be updated
with the actual title taken from the metadata.
You can also provide a callback to be called when a new stream title is available.
The downloading of the data from the internet is done in a background thread
and it tries to keep a (small) buffer filled with available data to read.
You can optionally provide a custom ssl.SSLContext in the ssl_context parameter,
if you need to change the way SSL connections are configured (certificates, checks, etc).
"""

BLOCK_SIZE = 8*1024
BUFFER_SIZE = 64*1024

def __init__(self, url: str, update_stream_title: Callable[['IceCastClient', str], None] = None) -> None:
def __init__(self, url: str, update_stream_title: Callable[['IceCastClient', str], None] = None,
ssl_context: "ssl.SSLContext" = None) -> None:
self.url = url
self.stream_title = "???"
self.station_genre = "???"
Expand All @@ -1152,7 +1155,7 @@ def __init__(self, url: str, update_stream_title: Callable[['IceCastClient', str
self._buffer_lock = threading.Lock()
self._update_title = update_stream_title
req = urllib.request.Request(url, headers={"icy-metadata": "1"})
with urllib.request.urlopen(req) as result:
with urllib.request.urlopen(req, context=ssl_context) as result:
self.station_genre = result.headers["icy-genre"]
self.station_name = result.headers["icy-name"]
stream_format = result.headers["Content-Type"]
Expand Down
Loading

0 comments on commit 9185502

Please sign in to comment.