P6-R1: Audio/video streaming pipeline
Lint & Validate / lint (push) Has been cancelled

- src/streaming/ module: camera detection (USB webcam + Pi Camera Module via
  v4l2/libcamera), GStreamer pipeline builder with V4L2/OMX/x264 h264 encoders,
  platform presets (YouTube, Twitch, Facebook, custom RTMP), streamer lifecycle
  manager with auto-reconnect, scene management, stream statistics
- Keyboard shortcut controller (evdev + pynput fallback) for stream control:
  Ctrl+Shift+S (start/stop), Ctrl+Shift+1-9 (scene switch), Ctrl+Shift+R (reconnect)
- REST API: /api/v1/stream/* endpoints for start/stop/status, scenes, cameras,
  platforms, and hotkey listing — integrated into NetworkServer
- StreamStateProvider bridging layer connects REST routes to Streamer instance
- GStreamer pipeline supports ALSA/JACK/PulseAudio audio capture and
  V4L2/libcamera video capture with H.264 hardware encoding on RPi4B
- Low-latency streaming settings for live performance (zerolatency, no B-frames)
- 89 streaming tests (709 total project tests pass)
This commit is contained in:
2026-05-19 22:13:29 -04:00
parent d6480a35ed
commit cdf04bd8eb
21 changed files with 7119 additions and 34 deletions
+5
View File
@@ -43,6 +43,7 @@ from .screens.mixer import MixerScreen
from .screens.routing import RoutingScreen
from .screens.plugins import PluginScreen
from .screens.settings import SettingsScreen
from .screens.sessions import SessionsScreen
logger = logging.getLogger(__name__)
@@ -88,6 +89,7 @@ class TabBar(BoxLayout):
("mixer", "MIX"),
("routing", "RTG"),
("plugins", "PLG"),
("sessions", "SES"),
("settings", "SET"),
]
for name, label in tabs:
@@ -173,11 +175,13 @@ class MixerRoot(BoxLayout):
self.mixer_screen = MixerScreen(name="mixer")
self.routing_screen = RoutingScreen(name="routing")
self.plugin_screen = PluginScreen(name="plugins")
self.sessions_screen = SessionsScreen(name="sessions")
self.settings_screen = SettingsScreen(name="settings")
self.screen_manager.add_widget(self.mixer_screen)
self.screen_manager.add_widget(self.routing_screen)
self.screen_manager.add_widget(self.plugin_screen)
self.screen_manager.add_widget(self.sessions_screen)
self.screen_manager.add_widget(self.settings_screen)
# Tab bar (bottom)
@@ -192,6 +196,7 @@ class MixerRoot(BoxLayout):
self.mixer_screen.client = client
self.routing_screen.client = client
self.plugin_screen.client = client
self.sessions_screen.client = client
self.settings_screen.client = client
def update_status(self, connected: bool, info: str = ""):