jamendo_obs/lib/player.py

65 lines
2.3 KiB
Python

import threading
from queue import Queue, Empty
import miniaudio
import logging
from lib.renderer import Renderer
class Player:
def __init__(self, renderer: Renderer, play_finished_handler):
self._queue = Queue()
self._next_event = threading.Event()
self._exit_event = threading.Event()
self._logger = logging.getLogger('Jamendo Player')
self._renderer = renderer
self._play_finished_handler = play_finished_handler
threading.Thread(target=self.worker, args=()).start()
def worker(self):
while True:
try:
item = self._queue.get(block=True, timeout=1)
if item:
self._renderer.render(item['cover_file'], item['artist'], item['album'], item['title'])
self._logger.info('playing {artist}, {album}, {title}...'.format(artist=item['artist'], album=item['album'], title=item['title']))
file_stream = miniaudio.stream_file(item['audio_file'])
callback_stream = miniaudio.stream_with_callbacks(file_stream, end_callback=self.stream_end_callback)
next(callback_stream)
with miniaudio.PlaybackDevice() as device:
device.start(callback_stream)
self._next_event.wait()
self._next_event.clear()
self._queue.task_done()
self._play_finished_handler(item['audio_file'], item['cover_file'])
except Empty:
pass
if self._exit_event.is_set():
break
def stream_end_callback(self):
self.next()
def add_file(self, audio_file, artist: str, album: str, title: str, cover_file):
self._queue.put(
{
'audio_file': audio_file,
'artist': artist,
'album': album,
'title': title,
'cover_file': cover_file
}
)
@property
def queue_size(self):
return self._queue.qsize()
def next(self):
self._next_event.set()
def quit(self):
self._exit_event.set()
self.next()
while not self._queue.empty():
item = self._queue.get()
self._play_finished_handler(item['audio_file'], item['cover_file'])