Mercurial > libervia-web
comparison libervia/web/pages/calls/_browser/__init__.py @ 1564:bd3c880f4a47
browser (calls): add camera switching:
- devices are listed on startup, and a `has_multiple_cameras` boolean is set
- based on this data, switch camera button is hidden or not
- a click/touch on the button will switch to the next available camera, and loop back to
first one at the end
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 18 Aug 2023 17:43:01 +0200 |
parents | e3449beac8d8 |
children | d282dbdd5ffd |
comparison
equal
deleted
inserted
replaced
1563:e3449beac8d8 | 1564:bd3c880f4a47 |
---|---|
32 SCREEN_OFF_CLASS = "screen-off" | 32 SCREEN_OFF_CLASS = "screen-off" |
33 | 33 |
34 | 34 |
35 class CallUI: | 35 class CallUI: |
36 def __init__(self): | 36 def __init__(self): |
37 self.webrtc = WebRTC() | 37 self.webrtc = WebRTC( |
38 self.webrtc.screen_sharing_cb = self.on_sharing_screen | 38 screen_sharing_cb=self.on_sharing_screen, |
39 self.webrtc.on_connection_established_cb = self.on_connection_established | 39 on_connection_established_cb=self.on_connection_established, |
40 self.webrtc.on_reconnect_cb = self.on_reconnect | 40 on_reconnect_cb=self.on_reconnect, |
41 self.webrtc.on_connection_lost_cb = self.on_connection_lost | 41 on_connection_lost_cb=self.on_connection_lost, |
42 on_video_devices=self.on_video_devices, | |
43 ) | |
42 self.mode = "search" | 44 self.mode = "search" |
43 self._status = None | 45 self._status = None |
44 self._callee = None | 46 self._callee = None |
45 self.contacts_elt = document["contacts"] | 47 self.contacts_elt = document["contacts"] |
46 self.search_container_elt = document["search_container"] | 48 self.search_container_elt = document["search_container"] |
69 document["exit_full_screen_btn"].bind( | 71 document["exit_full_screen_btn"].bind( |
70 "click", lambda __: self.toggle_fullscreen() | 72 "click", lambda __: self.toggle_fullscreen() |
71 ) | 73 ) |
72 document["mute_audio_btn"].bind("click", self.toggle_audio_mute) | 74 document["mute_audio_btn"].bind("click", self.toggle_audio_mute) |
73 document["mute_video_btn"].bind("click", self.toggle_video_mute) | 75 document["mute_video_btn"].bind("click", self.toggle_video_mute) |
74 self.share_desktop_btn_elt = document["share_desktop_btn"] | 76 self.share_desktop_col_elt = document["share_desktop_column"] |
75 if hasattr(window.navigator.mediaDevices, "getDisplayMedia"): | 77 if hasattr(window.navigator.mediaDevices, "getDisplayMedia"): |
76 self.share_desktop_btn_elt.classList.remove("is-hidden-touch") | 78 self.share_desktop_col_elt.classList.remove("is-hidden-touch") |
77 # screen sharing is supported | 79 # screen sharing is supported |
78 self.share_desktop_btn_elt.bind("click", self.toggle_screen_sharing) | 80 document["share_desktop_btn"].bind("click", self.toggle_screen_sharing) |
79 else: | 81 else: |
80 self.share_desktop_btn_elt.classList.add("is-hidden") | 82 self.share_desktop_col_elt.classList.add("is-hidden") |
83 document["switch_camera_btn"].bind("click", self.on_switch_camera) | |
81 | 84 |
82 # search | 85 # search |
83 self.search_elt = document["search"] | 86 self.search_elt = document["search"] |
84 self.jid_search = JidSearch( | 87 self.jid_search = JidSearch( |
85 self.search_elt, | 88 self.search_elt, |
307 self.status = "reconnecting" | 310 self.status = "reconnecting" |
308 | 311 |
309 def on_connection_lost(self): | 312 def on_connection_lost(self): |
310 self.status = "connection-lost" | 313 self.status = "connection-lost" |
311 | 314 |
315 def on_video_devices(self, has_multiple_cameras: bool) -> None: | |
316 switch_camera_col_elt = document["switch_camera_column"] | |
317 if has_multiple_cameras: | |
318 switch_camera_col_elt.classList.remove("is-hidden", "is-hidden-desktop") | |
319 else: | |
320 switch_camera_col_elt.classList.add("is-hidden") | |
321 | |
312 async def make_call(self, audio: bool = True, video: bool = True) -> None: | 322 async def make_call(self, audio: bool = True, video: bool = True) -> None: |
313 """Start a WebRTC call | 323 """Start a WebRTC call |
314 | 324 |
315 @param audio: True if an audio flux is required | 325 @param audio: True if an audio flux is required |
316 @param video: True if a video flux is required | 326 @param video: True if a video flux is required |
442 @param ev: the event object from the button click. | 452 @param ev: the event object from the button click. |
443 """ | 453 """ |
444 if not self.search_elt.value: | 454 if not self.search_elt.value: |
445 return | 455 return |
446 # clear the search field | 456 # clear the search field |
447 self.search_elt.value = '' | 457 self.search_elt.value = "" |
448 # and dispatch the input event so items are updated | 458 # and dispatch the input event so items are updated |
449 self.search_elt.dispatchEvent(window.Event.new("input")) | 459 self.search_elt.dispatchEvent(window.Event.new("input")) |
450 | 460 |
451 def toggle_fullscreen(self, fullscreen: bool | None = None): | 461 def toggle_fullscreen(self, fullscreen: bool | None = None): |
452 """Toggle fullscreen mode for video elements. | 462 """Toggle fullscreen mode for video elements. |
508 def toggle_screen_sharing(self, evt): | 518 def toggle_screen_sharing(self, evt): |
509 aio.run(self.webrtc.toggle_screen_sharing()) | 519 aio.run(self.webrtc.toggle_screen_sharing()) |
510 | 520 |
511 def on_sharing_screen(self, sharing: bool) -> None: | 521 def on_sharing_screen(self, sharing: bool) -> None: |
512 """Called when screen sharing state changes""" | 522 """Called when screen sharing state changes""" |
513 share_desktop_btn_elt = self.share_desktop_btn_elt | 523 share_desktop_btn_elt = document["share_desktop_btn"] |
514 if sharing: | 524 if sharing: |
515 share_desktop_btn_elt.classList.add("is-danger") | 525 share_desktop_btn_elt.classList.add("is-danger") |
516 share_desktop_btn_elt.classList.remove(INACTIVE_CLASS, SCREEN_OFF_CLASS) | 526 share_desktop_btn_elt.classList.remove(INACTIVE_CLASS, SCREEN_OFF_CLASS) |
517 else: | 527 else: |
518 share_desktop_btn_elt.classList.remove("is-danger") | 528 share_desktop_btn_elt.classList.remove("is-danger") |
519 share_desktop_btn_elt.classList.add(INACTIVE_CLASS, SCREEN_OFF_CLASS) | 529 share_desktop_btn_elt.classList.add(INACTIVE_CLASS, SCREEN_OFF_CLASS) |
530 | |
531 def on_switch_camera(self, __) -> None: | |
532 aio.run(self.webrtc.switch_camera()) | |
520 | 533 |
521 def _on_entity_click(self, item: dict) -> None: | 534 def _on_entity_click(self, item: dict) -> None: |
522 aio.run(self.on_entity_click(item)) | 535 aio.run(self.on_entity_click(item)) |
523 | 536 |
524 async def on_entity_click(self, item: dict) -> None: | 537 async def on_entity_click(self, item: dict) -> None: |