gm/teleoprtc/builder.py

80 lines
2.6 KiB
Python

import abc
from typing import List, Dict
import aiortc
from teleoprtc.stream import WebRTCBaseStream, WebRTCOfferStream, WebRTCAnswerStream, ConnectionProvider
from teleoprtc.tracks import TiciVideoStreamTrack, TiciTrackWrapper
class WebRTCStreamBuilder(abc.ABC):
@abc.abstractmethod
def stream(self) -> WebRTCBaseStream:
raise NotImplementedError
class WebRTCOfferBuilder(WebRTCStreamBuilder):
def __init__(self, connection_provider: ConnectionProvider):
self.connection_provider = connection_provider
self.requested_camera_types: List[str] = []
self.requested_audio = False
self.audio_tracks: List[aiortc.MediaStreamTrack] = []
self.messaging_enabled = False
def offer_to_receive_video_stream(self, camera_type: str):
assert camera_type in ["driver", "wideRoad", "road"]
self.requested_camera_types.append(camera_type)
def offer_to_receive_audio_stream(self):
self.requested_audio = True
def add_audio_stream(self, track: aiortc.MediaStreamTrack):
assert len(self.audio_tracks) == 0
self.audio_tracks = [track]
def add_messaging(self):
self.messaging_enabled = True
def stream(self) -> WebRTCBaseStream:
return WebRTCOfferStream(
self.connection_provider,
consumed_camera_types=self.requested_camera_types,
consume_audio=self.requested_audio,
video_producer_tracks=[],
audio_producer_tracks=self.audio_tracks,
should_add_data_channel=self.messaging_enabled,
)
class WebRTCAnswerBuilder(WebRTCStreamBuilder):
def __init__(self, offer_sdp: str):
self.offer_sdp = offer_sdp
self.video_tracks: Dict[str, aiortc.MediaStreamTrack] = dict()
self.requested_audio = False
self.audio_tracks: List[aiortc.MediaStreamTrack] = []
def offer_to_receive_audio_stream(self):
self.requested_audio = True
def add_video_stream(self, camera_type: str, track: aiortc.MediaStreamTrack):
assert camera_type not in self.video_tracks
assert camera_type in ["driver", "wideRoad", "road"]
if not isinstance(track, TiciVideoStreamTrack):
track = TiciTrackWrapper(camera_type, track)
self.video_tracks[camera_type] = track
def add_audio_stream(self, track: aiortc.MediaStreamTrack):
assert len(self.audio_tracks) == 0
self.audio_tracks = [track]
def stream(self) -> WebRTCBaseStream:
description = aiortc.RTCSessionDescription(sdp=self.offer_sdp, type="offer")
return WebRTCAnswerStream(
description,
consumed_camera_types=[],
consume_audio=self.requested_audio,
video_producer_tracks=list(self.video_tracks.values()),
audio_producer_tracks=self.audio_tracks,
should_add_data_channel=False,
)