- Remove TURN decks (3/4), clean up MIDI, layout - Single cart player with 3-item autoload queue + continue toggle - Event logging (SessionLogger), mic tracking, large mic timer widget - LUFS metering moved from external ports to internal master mix - Master output WAV recording with top-bar REC toggle - Music mix output (ch 3-8 only, no mics) - Preview bar for playlist auditioning - Merged show log with [SONG][CART][TALK] prefixes - Live CSV writer for OBS song display (~/live_songs.csv) - Misc fixes: preview race condition, datetime import for recording
72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
# event_logger.py
|
|
|
|
import json
|
|
import os
|
|
import threading
|
|
import time
|
|
from datetime import datetime
|
|
|
|
LOG_DIR = os.path.expanduser("~/.gti_radiostudio/sessions")
|
|
|
|
|
|
class SessionLogger:
|
|
def __init__(self):
|
|
self._lock = threading.Lock()
|
|
self._log_path = None
|
|
self._start_new_session()
|
|
|
|
def _start_new_session(self):
|
|
os.makedirs(LOG_DIR, exist_ok=True)
|
|
ts = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
|
self._log_path = os.path.join(LOG_DIR, f"{ts}.jsonl")
|
|
self._write_raw({
|
|
"event": "session_start",
|
|
"timestamp": time.time(),
|
|
"iso": datetime.now().isoformat(),
|
|
})
|
|
|
|
def _write_raw(self, entry: dict):
|
|
with self._lock:
|
|
try:
|
|
with open(self._log_path, 'a') as f:
|
|
f.write(json.dumps(entry) + "\n")
|
|
except Exception:
|
|
pass
|
|
|
|
def log_cart_trigger(self, track_name: str):
|
|
self._write_raw({
|
|
"event": "cart_trigger",
|
|
"timestamp": time.time(),
|
|
"iso": datetime.now().isoformat(),
|
|
"track": track_name,
|
|
})
|
|
|
|
def log_mic_on(self, channel: int):
|
|
self._write_raw({
|
|
"event": "mic_on",
|
|
"timestamp": time.time(),
|
|
"iso": datetime.now().isoformat(),
|
|
"channel": channel,
|
|
})
|
|
|
|
def log_mic_off(self, channel: int, duration_sec: float):
|
|
self._write_raw({
|
|
"event": "mic_off",
|
|
"timestamp": time.time(),
|
|
"iso": datetime.now().isoformat(),
|
|
"channel": channel,
|
|
"duration_sec": round(duration_sec, 3),
|
|
})
|
|
|
|
def log_deck_play(self, deck_key: str, track_name: str):
|
|
self._write_raw({
|
|
"event": "deck_play",
|
|
"timestamp": time.time(),
|
|
"iso": datetime.now().isoformat(),
|
|
"deck": deck_key,
|
|
"track": track_name,
|
|
})
|
|
|
|
@property
|
|
def log_path(self):
|
|
return self._log_path |