ddeb91f77d
Replacing both bottle and liquidsoap with a native TCPServer.
69 lines
2.0 KiB
Python
69 lines
2.0 KiB
Python
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()
|