diff libervia/web/pages/calls/_browser/webrtc.py @ 1604:4a9679369856

browser (call): implements group calls: rel 430
author Goffi <goffi@goffi.org>
date Wed, 15 May 2024 17:40:33 +0200
parents 6feac4a25e60
children 6bfeb9f0fb84
line wrap: on
line diff
--- a/libervia/web/pages/calls/_browser/webrtc.py	Sat May 11 14:02:54 2024 +0200
+++ b/libervia/web/pages/calls/_browser/webrtc.py	Wed May 15 17:40:33 2024 +0200
@@ -285,6 +285,9 @@
         on_reset_cb=None,
         file_only: bool = False,
         extra_data: dict | None = None,
+        local_video_elt = None,
+        remote_video_elt = None,
+        local_stream = None
     ):
         """Initialise WebRTC instance.
 
@@ -324,11 +327,14 @@
             aio.run(self._populate_video_devices())
 
             # video elements
-            self.local_video_elt = document["local_video"]
-            self.remote_video_elt = document["remote_video"]
+            self.local_video_elt = local_video_elt
+            assert remote_video_elt is not None
+            self.remote_video_elt = remote_video_elt
         else:
             self.file_sender = None
 
+        self.local_stream = local_stream
+
         # muting
         self.is_audio_muted = None
         self.is_video_muted = None
@@ -650,15 +656,19 @@
         @param video: True if a video flux is required.
         """
         media_constraints = {"audio": audio, "video": video}
-        local_stream = await window.navigator.mediaDevices.getUserMedia(media_constraints)
+        if self.local_stream is None:
+            self.local_stream = await window.navigator.mediaDevices.getUserMedia(
+                media_constraints
+            )
 
-        if not local_stream:
+        if not self.local_stream:
             log.error("Failed to get the media stream.")
             return
 
-        self.local_video_elt.srcObject = local_stream
+        if self.local_video_elt is not None:
+            self.local_video_elt.srcObject = self.local_stream
 
-        for track in local_stream.getTracks():
+        for track in self.local_stream.getTracks():
             self._peer_connection.addTrack(track)
 
     async def _replace_user_video(
@@ -676,7 +686,7 @@
                 media_constraints
             )
         else:
-            if self.local_video_elt.srcObject:
+            if self.local_video_elt is not None and self.local_video_elt.srcObject:
                 for track in self.local_video_elt.srcObject.getTracks():
                     if track.kind == "video":
                         track.stop()
@@ -704,7 +714,10 @@
             return None
 
         # Retrieve the current local stream's video track.
-        local_stream = self.local_video_elt.srcObject
+        if self.local_video_elt is None:
+            local_stream = None
+        else:
+            local_stream = self.local_video_elt.srcObject
         if local_stream:
             local_video_tracks = [
                 track for track in local_stream.getTracks() if track.kind == "video"
@@ -778,7 +791,10 @@
             return
 
         # Update local video element's stream
-        local_stream = self.local_video_elt.srcObject
+        if self.local_video_elt is None:
+            local_stream = None
+        else:
+            local_stream = self.local_video_elt.srcObject
         if local_stream:
             local_video_tracks = [
                 track for track in local_stream.getTracks() if track.kind == "video"
@@ -979,6 +995,23 @@
             )
             self.local_candidates_buffer.clear()
 
+    async def prepare_call(
+        self,
+        audio: bool = True,
+        video: bool = True
+    ) -> dict:
+        """Prepare a call.
+
+        Create RTCPeerConnection instance, and get use media.
+
+        @param audio: True if an audio flux is required
+        @param video: True if a video flux is required
+        @return: Call Data
+        """
+        await self._create_peer_connection()
+        await self._get_user_media(audio, video)
+        return await self._get_call_data()
+
     async def make_call(
         self, callee_jid: jid.JID, audio: bool = True, video: bool = True
     ) -> None:
@@ -986,9 +1019,7 @@
         @param audio: True if an audio flux is required
         @param video: True if a video flux is required
         """
-        await self._create_peer_connection()
-        await self._get_user_media(audio, video)
-        call_data = await self._get_call_data()
+        call_data = await self.prepare_call(audio, video)
         log.info(f"calling {callee_jid!r}")
         self.sid = await bridge.call_start(str(callee_jid), json.dumps(call_data))
         log.debug(f"Call SID: {self.sid}")
@@ -1098,12 +1129,13 @@
                 "lEQVR42mP8/wcAAwAB/uzNq7sAAAAASUVORK5CYII="
             )
 
+            remote_video = self.remote_video_elt
             local_video = self.local_video_elt
-            remote_video = self.remote_video_elt
-            if local_video.srcObject:
-                for track in local_video.srcObject.getTracks():
-                    track.stop()
-            local_video.src = black_image_data
+            if local_video is not None:
+                if local_video.srcObject:
+                    for track in local_video.srcObject.getTracks():
+                        track.stop()
+                local_video.src = black_image_data
 
             if remote_video.srcObject:
                 for track in remote_video.srcObject.getTracks():
@@ -1124,7 +1156,7 @@
         local_video = self.local_video_elt
         is_muted_attr = f"is_{media_type}_muted"
 
-        if local_video.srcObject:
+        if local_video is not None and local_video.srcObject:
             track_getter = getattr(
                 local_video.srcObject, f"get{media_type.capitalize()}Tracks"
             )