Files
rewind/rewind/daemon.py

111 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
import os
import datetime
import signal
import time
import obsws_python as obs
import subprocess
from rewind.core import get_duration
from rewind.paths import load_state, write_state, load_config
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
INTERVAL = 10
MAX_AGE_SECONDS = 60 * 60 * 1
running = True
def open_obs():
subprocess.Popen(["obs", "--minimize-to-tray"])
def open_obs_connection(host: str, port: int, password: str) -> obs.ReqClient | None:
try:
con = obs.ReqClient(host=host, port=port, password=password)
return con
except ConnectionRefusedError:
print("Could not connect to OBS. Is it running and is the WebSocket server enabled?")
return None
def start_recording(con: obs.ReqClient) -> None:
con.start_record()
print("Started recording")
def stop_recording(con: obs.ReqClient) -> None:
con.stop_record()
print("Stopped recording")
def cleanup_old_files(directory: str, max_age_seconds: int) -> None:
for filename in os.listdir(directory):
file_path = os.path.join(directory, filename)
if os.path.isfile(file_path):
file_age = datetime.datetime.now().timestamp() - os.path.getmtime(file_path)
if file_age > max_age_seconds and filename.endswith(".ts"):
os.remove(file_path)
print(f"Removed old file: {file_path}")
def create_state_file() -> None:
state = {"files": []}
write_state(state)
def add_file_to_state(file_path: str) -> None:
state = load_state()
files = state.get("files", [])
if files and len(files) > 0:
last_file = files[-1]
last_file["e_timestamp"] = datetime.datetime.now().timestamp()
files.append({
"path": file_path,
"timestamp": datetime.datetime.now().timestamp(),
})
state["files"] = files
write_state(state)
def handle_shutdown(signum, frame):
global running
running = False
class Handler(FileSystemEventHandler):
def on_created(self, event):
if not event.is_directory and event.src_path.endswith(".ts"):
add_file_to_state(event.src_path)
print(f"Added new file to state: {event.src_path}")
def main() -> None:
signal.signal(signal.SIGINT, handle_shutdown)
signal.signal(signal.SIGTERM, handle_shutdown)
open_obs()
time.sleep(5)
config = load_config()
con = None
for _ in range(10):
con = open_obs_connection(config["obs"]["host"], config["obs"]["port"], config["obs"]["password"])
if con is not None:
break
time.sleep(2)
recording_dir = con.get_record_directory().record_directory
start_recording(con)
create_state_file()
try:
event_handler = Handler()
observer = Observer()
observer.schedule(event_handler, path=recording_dir, recursive=False)
observer.start()
while running:
cleanup_old_files(recording_dir, config["record"]["max_record_time"])
time.sleep(INTERVAL)
finally:
stop_recording(con)
con.disconnect()
print("Daemon stopped")
if __name__ == "__main__":
main()