dnd-music-console/croaker/streamer.py

69 lines
2.0 KiB
Python
Raw Normal View History

import os
import logging
import threading
from pathlib import Path
from functools import cached_property
import shout
from time import sleep
class AudioStreamer(threading.Thread):
def __init__(self, queue, skip_event, stop_event):
super().__init__()
self.queue = queue
self.skip_requested = skip_event
self.stop_requested = stop_event
@cached_property
def _shout(self):
s = shout.Shout()
s.name = 'Croaker Radio'
s.url = os.environ['ICECAST_URL']
s.mount = os.environ['ICECAST_MOUNT']
s.host = os.environ['ICECAST_HOST']
s.port = int(os.environ['ICECAST_PORT'])
s.password = os.environ['ICECAST_PASSWORD']
s.protocol = 'http'
s.format = 'mp3'
s.audio_info = {
shout.SHOUT_AI_BITRATE: '192',
shout.SHOUT_AI_SAMPLERATE: '44100',
shout.SHOUT_AI_CHANNELS: '5'
}
return s
def run(self):
logging.debug("Initialized")
self._shout.open()
while not self.stop_requested.is_set():
self._shout.get_connected()
track = self.queue.get()
logging.debug(f"Received: {track = }")
if track:
self.play(Path(track.decode()))
continue
sleep(1)
self._shout.close()
def play(self, track: Path):
with track.open('rb') as fh:
self._shout.get_connected()
logging.debug(f"Streaming {track.stem = }")
self._shout.set_metadata({'song': track.stem})
input_buffer = fh.read(4096)
while not self.skip_requested.is_set():
if self.stop_requested.is_set():
self.stop_requested.clear()
return
buf = input_buffer
input_buffer = fh.read(4096)
if len(buf) == 0:
break
self._shout.send(buf)
self._shout.sync()
if self.skip_requested.is_set():
self.skip_requested.clear()