mirror of
https://github.com/correl/turntable.git
synced 2024-12-27 11:09:53 +00:00
Add a basic GUI
This commit is contained in:
parent
d8a175c358
commit
4a035ec5b6
6 changed files with 147 additions and 76 deletions
14
poetry.lock
generated
14
poetry.lock
generated
|
@ -289,6 +289,14 @@ optional = false
|
|||
python-versions = "*"
|
||||
version = "0.23.1"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Cross-platform windowing and multimedia library"
|
||||
name = "pyglet"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "1.5.7"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
description = "Python parsing module"
|
||||
|
@ -414,7 +422,7 @@ secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0
|
|||
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
|
||||
|
||||
[metadata]
|
||||
content-hash = "7145f097b34f0bbe62825427b4ecc8c916fa48c8255a9b5da539edf6b990540f"
|
||||
content-hash = "3af542607f4ccaa3afe08d275174f664cdacedac31ce8278e059d4aca2b9edeb"
|
||||
lock-version = "1.0"
|
||||
python-versions = "^3.8"
|
||||
|
||||
|
@ -626,6 +634,10 @@ pydub = [
|
|||
{file = "pydub-0.23.1-py2.py3-none-any.whl", hash = "sha256:d29901a486fb421c5d7b0f3d5d3a60527179204d8ffb20e74e1ae81c17e81b46"},
|
||||
{file = "pydub-0.23.1.tar.gz", hash = "sha256:c362fa02da1eebd1d08bd47aa9b0102582dff7ca2269dbe9e043d228a0c1ea93"},
|
||||
]
|
||||
pyglet = [
|
||||
{file = "pyglet-1.5.7-py3-none-any.whl", hash = "sha256:9832442d59ee06acbeff12e128cf6d5aee271e94c09386040db8f0feae277013"},
|
||||
{file = "pyglet-1.5.7.zip", hash = "sha256:3faac2dad34946aecbce79a8658f89155436fe5c07332229160c6eba302ff40d"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
|
||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||
|
|
|
@ -10,6 +10,7 @@ python = "^3.8"
|
|||
pyalsaaudio = "^0.9.0"
|
||||
pydejavu = {git = "https://github.com/worldveil/dejavu.git"}
|
||||
requests = "^2.24.0"
|
||||
pyglet = "^1.5.7"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
black = "^20.8b1"
|
||||
|
@ -17,7 +18,8 @@ mypy = "^0.782"
|
|||
pytest = "^6.0.1"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
turntable = "turntable.cli:main"
|
||||
turntable = "turntable.gui:main"
|
||||
turntable-cli = "turntable.cli:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
|
|
74
turntable/application.py
Normal file
74
turntable/application.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
import argparse
|
||||
from contextlib import contextmanager
|
||||
import importlib.metadata
|
||||
import json
|
||||
import logging
|
||||
from multiprocessing import Queue
|
||||
import os
|
||||
from typing import Any, Dict, Iterator
|
||||
|
||||
from dejavu import Dejavu # type: ignore
|
||||
|
||||
from turntable.audio import Listener
|
||||
from turntable.icecast import Icecast
|
||||
from turntable.models import PCM
|
||||
from turntable.turntable import (
|
||||
Event,
|
||||
NewMetadata,
|
||||
StartedPlaying,
|
||||
StoppedPlaying,
|
||||
Turntable,
|
||||
)
|
||||
|
||||
VERSION = importlib.metadata.version("turntable")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@contextmanager
|
||||
def run() -> "Iterator[Queue[Event]]":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--config", default=os.path.expanduser("~/.config/turntable.json")
|
||||
)
|
||||
args = parser.parse_args()
|
||||
with open(args.config, "r") as config_file:
|
||||
config: Dict[str, Any] = json.load(config_file)
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG if config.get("debug") else logging.INFO)
|
||||
logger.info("Turntable version %s", VERSION)
|
||||
|
||||
|
||||
pcm_in: "Queue[PCM]" = Queue()
|
||||
events: "Queue[Event]" = Queue()
|
||||
|
||||
audio_config = config.get("audio", dict())
|
||||
listener = Listener(
|
||||
pcm_in,
|
||||
audio_config.get("device", "default"),
|
||||
framerate=audio_config.get("framerate", 44100),
|
||||
channels=audio_config.get("channels", 2),
|
||||
period_size=audio_config.get("period_size", 4096),
|
||||
)
|
||||
|
||||
dejavu = Dejavu(config.get("dejavu", dict()))
|
||||
|
||||
player = Turntable(listener.framerate, listener.channels, dejavu, pcm_in, events)
|
||||
|
||||
icecast_config = config.get("icecast", dict())
|
||||
icecast = Icecast(
|
||||
host=icecast_config.get("host", "localhost"),
|
||||
port=icecast_config.get("port", 8000),
|
||||
mountpoint=icecast_config.get("mountpoint", "stream.mp3"),
|
||||
user=icecast_config.get("admin_user", "admin"),
|
||||
password=icecast_config.get("admin_password", "hackme"),
|
||||
)
|
||||
|
||||
processes = [listener, player]
|
||||
for process in processes:
|
||||
process.daemon = True
|
||||
process.start()
|
||||
try:
|
||||
yield events
|
||||
except:
|
||||
for process in processes:
|
||||
if process.is_alive():
|
||||
process.terminate()
|
|
@ -1,80 +1,9 @@
|
|||
import argparse
|
||||
import importlib.metadata
|
||||
import json
|
||||
import logging
|
||||
from multiprocessing import Queue
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
|
||||
from dejavu import Dejavu # type: ignore
|
||||
|
||||
from turntable.audio import Listener
|
||||
from turntable.icecast import Icecast
|
||||
from turntable.models import PCM
|
||||
from turntable.turntable import (
|
||||
Event,
|
||||
NewMetadata,
|
||||
StartedPlaying,
|
||||
StoppedPlaying,
|
||||
Turntable,
|
||||
)
|
||||
|
||||
VERSION = importlib.metadata.version("turntable")
|
||||
from turntable import application
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print(f"Turntable {VERSION}")
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--config", default=os.path.expanduser("~/.config/turntable.json")
|
||||
)
|
||||
args = parser.parse_args()
|
||||
with open(args.config, "r") as config_file:
|
||||
config: Dict[str, Any] = json.load(config_file)
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG if config.get("debug") else logging.INFO)
|
||||
|
||||
pcm_in: "Queue[PCM]" = Queue()
|
||||
events: "Queue[Event]" = Queue()
|
||||
|
||||
audio_config = config.get("audio", dict())
|
||||
listener = Listener(
|
||||
pcm_in,
|
||||
audio_config.get("device", "default"),
|
||||
framerate=audio_config.get("framerate", 44100),
|
||||
channels=audio_config.get("channels", 2),
|
||||
period_size=audio_config.get("period_size", 4096),
|
||||
)
|
||||
|
||||
dejavu = Dejavu(config.get("dejavu", dict()))
|
||||
|
||||
player = Turntable(listener.framerate, listener.channels, dejavu, pcm_in, events)
|
||||
|
||||
icecast_config = config.get("icecast", dict())
|
||||
icecast = Icecast(
|
||||
host=icecast_config.get("host", "localhost"),
|
||||
port=icecast_config.get("port", 8000),
|
||||
mountpoint=icecast_config.get("mountpoint", "stream.mp3"),
|
||||
user=icecast_config.get("admin_user", "admin"),
|
||||
password=icecast_config.get("admin_password", "hackme"),
|
||||
)
|
||||
|
||||
processes = [listener, player]
|
||||
for process in processes:
|
||||
process.daemon = True
|
||||
process.start()
|
||||
try:
|
||||
icecast.set_title("<Idle>")
|
||||
with application.run() as events:
|
||||
while event := events.get():
|
||||
logging.info("Event: %s", event)
|
||||
if isinstance(event, StartedPlaying):
|
||||
icecast.set_title("<Record starting...>")
|
||||
elif isinstance(event, StoppedPlaying):
|
||||
icecast.set_title("<Idle>")
|
||||
elif isinstance(event, NewMetadata):
|
||||
icecast.set_title(event.title)
|
||||
except KeyboardInterrupt:
|
||||
for process in processes:
|
||||
if process.is_alive():
|
||||
process.terminate()
|
||||
|
|
52
turntable/gui.py
Normal file
52
turntable/gui.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
import logging
|
||||
import queue
|
||||
|
||||
import pyglet # type: ignore
|
||||
import pyglet.clock # type: ignore
|
||||
|
||||
from turntable import application, turntable
|
||||
|
||||
def main():
|
||||
window = pyglet.window.Window(fullscreen=True)
|
||||
with application.run() as events:
|
||||
label = pyglet.text.Label(
|
||||
"<Idle>",
|
||||
font_name='Noto Sans',
|
||||
font_size=36,
|
||||
x = window.width // 2,
|
||||
y = window.height // 2,
|
||||
anchor_x = 'center',
|
||||
anchor_y = 'center')
|
||||
|
||||
@window.event
|
||||
def on_draw():
|
||||
window.clear()
|
||||
label.draw()
|
||||
|
||||
def check_events(dt):
|
||||
try:
|
||||
event = events.get(False)
|
||||
logging.info("Event: %s", event)
|
||||
logging.info("Label: %s", label)
|
||||
if isinstance(event, turntable.StartedPlaying):
|
||||
label.text = "<Record starting...>"
|
||||
elif isinstance(event, turntable.StoppedPlaying):
|
||||
label.text = "<Idle>"
|
||||
elif isinstance(event, turntable.NewMetadata):
|
||||
label.text = event.title
|
||||
except queue.Empty:
|
||||
...
|
||||
except:
|
||||
logging.exception("Oops")
|
||||
|
||||
pyglet.clock.schedule_interval_soft(check_events, 0.5)
|
||||
pyglet.app.run()
|
||||
# icecast.set_title("<Idle>")
|
||||
# while event := events.get():
|
||||
# logging.info("Event: %s", event)
|
||||
# if isinstance(event, StartedPlaying):
|
||||
# icecast.set_title("<Record starting...>")
|
||||
# elif isinstance(event, StoppedPlaying):
|
||||
# icecast.set_title("<Idle>")
|
||||
# elif isinstance(event, NewMetadata):
|
||||
# icecast.set_title(event.title)
|
|
@ -122,7 +122,9 @@ class Turntable(Process):
|
|||
>= FINGERPRINT_DELAY + FINGERPRINT_IDENTIFY_SECONDS
|
||||
and self.identified == False
|
||||
):
|
||||
startframe = self.buffer.framerate * FINGERPRINT_DELAY
|
||||
startframe = self.buffer.framerate * (
|
||||
FINGERPRINT_DELAY + FINGERPRINT_IDENTIFY_DELAY
|
||||
)
|
||||
endframe = (
|
||||
startframe + self.buffer.framerate * FINGERPRINT_IDENTIFY_SECONDS
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue