From 7033b06aa0abaa4d07dac1ea465d6f1ec25dfa43 Mon Sep 17 00:00:00 2001 From: Arslaan Pathan Date: Tue, 6 Oct 2026 10:14:14 +1300 Subject: music controls better --- backend.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- main.py | 6 +++++- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/backend.py b/backend.py index f9ba73a..2b9ed9a 100644 --- a/backend.py +++ b/backend.py @@ -10,6 +10,8 @@ import os app = Flask(__name__) print_lock = threading.Lock() +music_process = None + load_dotenv("/srv/automation/remote-automation/.env") @app.get("/automate/hack_this_club") @@ -45,10 +47,12 @@ def print_queue(): @app.get("/automate/music") def music(): - NAVIDROME_URL = os.environ.get("NAVIDROME_URL", "127.0.0.1") - USERNAME = os.environ.get("NAVIDROME_USER", "user") - PASSWORD = os.environ.get("NAVIDROME_PASSWORD", "password123") - PLAYLIST_ID = os.environ.get("NAVIDROME_PLAYLIST_ID", "6767baldniko67") + global music_process + + NAVIDROME_URL = os.environ["NAVIDROME_URL"] + USERNAME = os.environ["NAVIDROME_USER"] + PASSWORD = os.environ["NAVIDROME_PASSWORD"] + PLAYLIST_ID = os.environ["NAVIDROME_PLAYLIST_ID"] params = { "u": USERNAME, @@ -60,12 +64,22 @@ def music(): "id": PLAYLIST_ID, } - response = requests.get(f"{NAVIDROME_URL}/rest/getPlaylist.view", params=params) + response = requests.get( + f"{NAVIDROME_URL}/rest/getPlaylist.view", + params=params, + ) response.raise_for_status() - songs = response.json()["subsonic-response"]["playlist"]["entry"] + data = response.json()["subsonic-response"] + + if data["status"] != "ok": + return {"status": "error", "message": data.get("error", {})}, 500 + + songs = data["playlist"]["entry"] song = random.choice(songs) + stream_url = f"{NAVIDROME_URL}/rest/stream.view" + stream_params = { "u": USERNAME, "p": PASSWORD, @@ -75,19 +89,46 @@ def music(): "id": song["id"], } - stream_url = f"{NAVIDROME_URL}/rest/stream.view" + stream_request = requests.Request( + "GET", + stream_url, + params=stream_params, + ).prepare() - subprocess.Popen([ + # Stop previous song + if music_process and music_process.poll() is None: + music_process.terminate() + + music_process = subprocess.Popen([ "mpv", "--no-video", "--audio-device=pipewire", "--", - requests.Request("GET", stream_url, params=stream_params).prepare().url, - ]) + stream_request.url, + ]) print(f"Playing: {song['title']} - {song.get('artist', 'Unknown Artist')}") - return f"Playing: {song['title']} - {song.get('artist', 'Unknown Artist')}" + return { + "status": "playing", + "title": song["title"], + "artist": song.get("artist", "Unknown Artist"), + } + +@app.get("/automate/music/next") +def music_next(): + return music() + +@app.get("/automate/music/stop") +def music_stop(): + global music_process + + if music_process and music_process.poll() is None: + music_process.terminate() + music_process = None + return {"status": "stopped"} + + return {"status": "not_playing"} if __name__ == "__main__": app.run(host="0.0.0.0", port=6732) diff --git a/main.py b/main.py index 0a201b9..33d92f1 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ from evdev import InputDevice, list_devices, ecodes from urllib.request import urlopen from urllib.error import HTTPError, URLError -SCANCODES = {0x11A: "up", 0x148: "down", 0x147: "left", 0x107: "right", 0x106: "ok", 0x141: "play/pause", 0x11c: "power", 0x103: "vol+", 0x142: "vol-", 0x101: "app", 0x154: "1"} +SCANCODES = {0x11A: "up", 0x148: "down", 0x147: "left", 0x107: "right", 0x106: "ok", 0x141: "play/pause", 0x11c: "power", 0x103: "vol+", 0x142: "vol-", 0x101: "app", 0x154: "1", 0x110: "stop", 0x14b: "skip"} device = None last = 0x00 @@ -29,6 +29,10 @@ def do_action(action: str): homelab_request("music") elif action == "1": homelab_request("print_queue") + elif action == "stop": + homelab_request("music/stop") + elif action == "skip": + homelab_request("music/next") for path in list_devices(): candidate = InputDevice(path) -- cgit v1.2.3