"""
Video service entry point that switches between:
1. Unified event-driven service (SE_VIDEO_EVENT_DRIVEN=true)
2. Traditional shell-based polling (SE_VIDEO_EVENT_DRIVEN=false or unset)
When event-driven mode is enabled, this launches a single unified service
that handles both recording and uploading with shared state management.
After the video service exits for any reason (normal drain, session end, or
supervisord-initiated shutdown), this controller signals supervisord so the
container shuts down. Centralising this here means both shell and event-driven
modes have identical container-lifecycle behaviour without video.sh needing to
know about supervisord.
"""
import os
import signal
import subprocess
import sys
import time
def _signal_supervisord() -> None:
"""Signal supervisord to initiate a container-wide shutdown.
Safe to call even when supervisord is already shutting down — it will
simply ignore a repeated SIGTERM if it is already in SHUTDOWN state.
"""
pid_file = os.environ.get("SE_SUPERVISORD_PID_FILE", "")
if not pid_file:
return
try:
with open(pid_file) as f:
pid = int(f.read().strip())
os.kill(pid, signal.SIGTERM)
print("[video.recorder] - Signaled supervisord to shut down")
except (OSError, ValueError, FileNotFoundError):
pass
def main():
event_driven = os.environ.get("SE_VIDEO_EVENT_DRIVEN", "false").lower() == "true"
if event_driven:
print("Starting unified event-driven video service...")
print("This service handles both recording and uploading with shared state.")
_external_shutdown = [False]
def _mark_external_shutdown(signum, frame):
_external_shutdown[0] = True
sys.exit(0)
signal.signal(signal.SIGTERM, _mark_external_shutdown)
signal.signal(signal.SIGINT, _mark_external_shutdown)
try:
import asyncio
from video_service import main as service_main
asyncio.run(service_main())
except ImportError as e:
print(f"Failed to import video service: {e}")
print("Ensure pyzmq is installed: pip install pyzmq")
print("Falling back to shell-based recording...")
_run_shell_recorder()
return
if not _external_shutdown[0]:
_signal_supervisord()
else:
print("Starting shell-based video recording...")
_run_shell_recorder()
def _run_shell_recorder():
record_video = os.environ.get("SE_RECORD_VIDEO", "true").lower() == "true"
per_session_mode = os.environ.get("SE_VIDEO_FILE_NAME", "") == "auto"
if not record_video and not per_session_mode:
print("[video.recorder] - SE_RECORD_VIDEO is disabled and SE_VIDEO_FILE_NAME is not 'auto', idling.")
try:
while True:
time.sleep(60)
except KeyboardInterrupt:
pass
return
proc = subprocess.Popen(["/opt/bin/video.sh"])
_external_shutdown = False
def forward_signal(signum, frame):
nonlocal _external_shutdown
if not _external_shutdown:
_external_shutdown = True
try:
proc.send_signal(signum)
except ProcessLookupError:
pass
signal.signal(signal.SIGTERM, forward_signal)
signal.signal(signal.SIGINT, forward_signal)
rc = proc.wait()
if not _external_shutdown and rc == 0:
_signal_supervisord()
if rc != 0:
sys.exit(rc)
if __name__ == "__main__":
main()