Files
2025-06-30 20:24:59 -05:00

68 lines
2.0 KiB
Python

import yaml # type: ignore
import sys
import jack # type: ignore
import socket
import numpy as np # type: ignore
import time
import threading
def load_config():
with open("config.yaml", "r") as f:
return yaml.safe_load(f)
def run_zone(zone_name: str, zone_config: dict):
jack_input = zone_config["jack_input"]
ip = zone_config["ip"]
port = zone_config["port"]
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client = jack.Client(jack_input)
client.inports.register("in_l")
client.inports.register("in_r")
def send_pcm_frames(frames: np.ndarray):
int16 = (frames * 32767.0).astype(np.int16)
interleaved = np.column_stack(int16).ravel()
sock.sendto(interleaved.tobytes(), (ip, port))
@client.set_process_callback
def process(frames):
l = client.inports[0].get_array()
r = client.inports[1].get_array()
data = np.vstack((l, r))
send_pcm_frames(data)
with client:
print(f"🎧 Streaming {zone_name} to {ip}:{port}")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print(f"🛑 {zone_name} stopped")
if __name__ == "__main__":
config = load_config()
zones = config.get("zones", {})
if len(sys.argv) > 1:
zone_name = sys.argv[1]
zone = zones.get(zone_name)
if not zone:
print(f"[!] Zone '{zone_name}' not found in config")
sys.exit(1)
if not zone.get("active", True):
print(f"[!] Zone '{zone_name}' is inactive in config")
sys.exit(1)
run_zone(zone_name, zone)
else:
threads = []
for zone_name, zone_config in zones.items():
if zone_config.get("active", True):
t = threading.Thread(target=run_zone, args=(zone_name, zone_config), daemon=True)
t.start()
threads.append(t)
for t in threads:
t.join()