mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-01 05:33:49 +08:00
webrtc: fix livestream request compatibility
Fix StreamRequestBody initialization for legacy and multi-camera clients, ignore unknown request fields, and use the supported nonblocking Params API for keyframe requests. Add regression coverage for request normalization. Based on PR #101 by inauner: https://github.com/firestar5683/StarPilot/pull/101
This commit is contained in:
@@ -64,7 +64,7 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack):
|
||||
self._seen_keyframe = False
|
||||
|
||||
def request_keyframe(self) -> None:
|
||||
self.params.put("LivestreamRequestKeyframe", True, block=False)
|
||||
self.params.put_nonblocking("LivestreamRequestKeyframe", True)
|
||||
|
||||
def _build_frame_data(self, msg) -> bytes:
|
||||
encode_data = getattr(msg, msg.which())
|
||||
@@ -91,7 +91,7 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack):
|
||||
if msg is not None:
|
||||
if not self._seen_keyframe and (getattr(msg, msg.which()).idx.flags & V4L2_BUF_FLAG_KEYFRAME):
|
||||
self._seen_keyframe = True
|
||||
self.params.put("LivestreamRequestKeyframe", False, block=False)
|
||||
self.params.put_nonblocking("LivestreamRequestKeyframe", False)
|
||||
break
|
||||
await asyncio.sleep(0.005)
|
||||
|
||||
|
||||
@@ -9,11 +9,21 @@ WEBRTCD_PORT = 5001
|
||||
@dataclass
|
||||
class StreamRequestBody:
|
||||
sdp: str
|
||||
init_camera: str
|
||||
enabled: bool
|
||||
init_camera: str = ""
|
||||
enabled: bool = True
|
||||
cameras: list[str] = field(default_factory=list)
|
||||
bridge_services_in: list[str] = field(default_factory=list)
|
||||
bridge_services_out: list[str] = field(default_factory=list)
|
||||
|
||||
def __post_init__(self):
|
||||
if not self.cameras:
|
||||
if self.init_camera:
|
||||
self.cameras = [self.init_camera]
|
||||
else:
|
||||
self.cameras = ["road"]
|
||||
if not self.init_camera and self.cameras:
|
||||
self.init_camera = self.cameras[0]
|
||||
|
||||
|
||||
def post_stream_request(body: StreamRequestBody) -> dict:
|
||||
t_start = time.monotonic()
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
from dataclasses import asdict
|
||||
|
||||
from openpilot.system.webrtc.helpers import StreamRequestBody
|
||||
|
||||
|
||||
def test_stream_request_body_defaults_legacy_clients_to_road():
|
||||
body = StreamRequestBody(sdp="offer")
|
||||
|
||||
assert body.init_camera == "road"
|
||||
assert body.enabled is True
|
||||
assert body.cameras == ["road"]
|
||||
assert body.bridge_services_in == []
|
||||
assert body.bridge_services_out == []
|
||||
|
||||
|
||||
def test_stream_request_body_maps_legacy_camera_to_new_camera_list():
|
||||
body = StreamRequestBody(sdp="offer", init_camera="driver", enabled=False)
|
||||
|
||||
assert body.init_camera == "driver"
|
||||
assert body.cameras == ["driver"]
|
||||
assert body.enabled is False
|
||||
|
||||
|
||||
def test_stream_request_body_preserves_explicit_multi_camera_request():
|
||||
body = StreamRequestBody(sdp="offer", cameras=["road", "driver"])
|
||||
|
||||
assert body.init_camera == "road"
|
||||
assert body.cameras == ["road", "driver"]
|
||||
assert asdict(body)["cameras"] == ["road", "driver"]
|
||||
@@ -397,7 +397,10 @@ def _text_response(text: str, status: int = 200) -> tuple[int, bytes, str]:
|
||||
|
||||
async def handle_get_stream(state: ServerState, raw_body: bytes) -> tuple[int, bytes, str]:
|
||||
stream_dict = state.streams
|
||||
body = StreamRequestBody(**json.loads(raw_body))
|
||||
parsed_dict = json.loads(raw_body)
|
||||
valid_fields = {f.name for f in StreamRequestBody.__dataclass_fields__.values()}
|
||||
filtered_dict = {k: v for k, v in parsed_dict.items() if k in valid_fields}
|
||||
body = StreamRequestBody(**filtered_dict)
|
||||
|
||||
async with state.stream_lock:
|
||||
# don't remove existing connection on prewarm request
|
||||
|
||||
Reference in New Issue
Block a user