annotate libervia/frontends/tools/webrtc_remote_control.py @ 4242:8acf46ed7f36

frontends: remote control implementation: This is the frontends common part of remote control implementation. It handle the creation of WebRTC session, and management of inputs. For now the reception use freedesktop.org Desktop portal, and works mostly with Wayland based Desktop Environments. rel 436
author Goffi <goffi@goffi.org>
date Sat, 11 May 2024 13:52:43 +0200
parents
children 0d7bb4df2343
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4242
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia Remote-Control via WebRTC implementation.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 import asyncio
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from functools import partial
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 import logging
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from typing import Any, Awaitable, Callable
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
24
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 import gi
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from gi.overrides.Gst import GLib
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from gi.repository import GstWebRTC
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
28
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 import cbor2
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from libervia.backend.core.i18n import _
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from libervia.backend.tools.common import data_format
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from libervia.frontends.tools import aio, jid, webrtc
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 from libervia.frontends.tools.webrtc_models import (
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 CallData,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 SourcesNone,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 SourcesPipeline,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 gi.require_versions({"Gst": "1.0", "GstWebRTC": "1.0"})
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 OnOpenCbType = Callable[["WebRTCRemoteController"], None|Awaitable[None]]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 MOUSE_BTN_LEFT = 0x110
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 MOUSE_BTN_RIGHT = 0x111
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 MOUSE_BTN_MIDDLE = 0x112
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 MOUSE_BTN_FORWARD = 0x115
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 MOUSE_BTN_BACK = 0x116
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
46
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 log = logging.getLogger(__name__)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 class WebRTCRemoteController:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 def __init__(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 self,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 bridge,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 profile: str,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 on_call_start_cb: Callable[[dict], Any] | None = None,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 end_call_cb: Callable[[], Any] | None = None,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 ) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 """Initializes the File Sender.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 @param bridge: An async Bridge instance.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 @param profile: The profile name to be used.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 @param on_call_start_cb: A blocking or async callable that accepts a dict as its
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 only argument.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 @param end_call_cb: A callable to be invoked at the end of a call.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
68
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 self.bridge = bridge
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 self.profile = profile
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 self.on_call_start_cb = on_call_start_cb
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 self.end_call_cb = end_call_cb
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 self.loop = asyncio.get_event_loop()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 self.data_channel: GstWebRTC.WebRTCDataChannel|None = None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
75
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 def send_input(self, input_data: dict) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 """Send an input data to controlled device
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
78
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 @param input_data: data of the input event.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 assert self.data_channel is not None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 self.data_channel.send_data(GLib.Bytes(cbor2.dumps(input_data)))
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
83
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 async def _on_webrtc_call_start(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 options: dict,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 callee: str,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 call_data: dict,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 profile: str,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 ) -> str:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 rc_data = {
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 "webrtc": True,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 "call_data": call_data,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 }
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 rc_data.update(options)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 remote_control_data_s = await self.bridge.remote_control_start(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 str(callee),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 data_format.serialise(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 rc_data
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 ),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 profile,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 remote_control_data = data_format.deserialise(remote_control_data_s)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
104
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 if self.on_call_start_cb is not None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 await aio.maybe_async(self.on_call_start_cb(remote_control_data))
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 return remote_control_data["session_id"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
108
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 def _on_dc_close(self, webrtc_call, data_channel: GstWebRTC.WebRTCDataChannel):
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 if webrtc_call is not None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 aio.run_from_thread(self._end_call_and_quit, webrtc_call, loop=self.loop)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
112
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 async def _end_call_and_quit(self, webrtc_call):
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 await webrtc_call.webrtc.end_call()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 if self.end_call_cb is not None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 await aio.maybe_async(self.end_call_cb())
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
117
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 def _on_dc_open(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 self, on_open_cb: OnOpenCbType, data_channel: GstWebRTC.WebRTCDataChannel
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 ) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 """Called when datachannel is open"""
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 self.data_channel = data_channel
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 aio.run_from_thread(self.on_dc_opened, on_open_cb, loop=self.loop)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
124
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 async def on_dc_opened(self, on_open_cb: OnOpenCbType) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 await aio.maybe_async(on_open_cb(self))
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
127
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 async def start(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 self,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 callee: jid.JID,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 options: dict,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 on_open_cb: OnOpenCbType
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 ) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 """Start a remote control session with ``callee``
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
135
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 @param callee: The JID of the recipient to send the file to.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 @param options: Options such as which devices to control.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 @param on_open_cb: Method to call when the Data Channel is open.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 The WebRTCRemoteController instance used as argument can then be used to send
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 input events to received.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 call_data = CallData(callee=callee)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 self.webrtc_call = await webrtc.WebRTCCall.make_webrtc_call(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 self.bridge,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 self.profile,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 call_data,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 sources_data=webrtc.SourcesDataChannel(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 dc_open_cb=partial(self._on_dc_open, on_open_cb),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 ),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 call_start_cb=partial(self._on_webrtc_call_start, options),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
152
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
153
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 class WebRTCRemoteControlReceiver:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
155
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 def __init__(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 self, bridge, profile: str, on_close_cb: Callable[[], Any] | None = None,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 verbose: bool = False
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 ) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 """Initializes the File Receiver.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
161
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 @param bridge: An async Bridge instance.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 @param profile: The profile name to be used.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 @param on_close_cb: Called when the Data Channel is closed.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 @param verbose: if True, print input events.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 self.bridge = bridge
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 self.profile = profile
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 self.on_close_cb = on_close_cb
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 self.loop = asyncio.get_event_loop()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 self.desktop_portal = None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 self.remote_desktop_data: dict|None = None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 self.stream_node_id: int|None = None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 self.verbose = verbose
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
175
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 async def do_input(self, data: dict) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 assert self.desktop_portal is not None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 try:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 type_ = data["type"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 if type_.startswith("mouse"):
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 try:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 try:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 x, y = data["x"], data["y"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 except KeyError:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 dx, dy = data["movementX"], data["movementY"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 await self.desktop_portal.notify_pointer_motion(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 dx, dy
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 else:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 assert self.stream_node_id is not None
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 await self.desktop_portal.notify_pointer_motion_absolute(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 self.stream_node_id, x, y
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 except Exception:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 log.exception("Can't send input")
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 if type_ in ("mouseup", "mousedown"):
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 buttons = data["buttons"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 state = 1 if type_ == "mousedown" else 0
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 # see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#value
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 if buttons & 1:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 await self.desktop_portal.notify_pointer_button(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 MOUSE_BTN_LEFT,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 state
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 if buttons & 2:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 await self.desktop_portal.notify_pointer_button(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 MOUSE_BTN_RIGHT,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 state
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 if buttons & 4:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 await self.desktop_portal.notify_pointer_button(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 MOUSE_BTN_MIDDLE,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 state
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 if buttons & 8:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 await self.desktop_portal.notify_pointer_button(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 MOUSE_BTN_BACK,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 state
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 if buttons & 16:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 await self.desktop_portal.notify_pointer_button(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 MOUSE_BTN_FORWARD,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 state
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 elif type_ == "wheel":
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 dx = data.get("deltaX", 0)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 dy = data.get("deltaY", 0)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 delta_mode = data["deltaMode"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 if delta_mode == 0:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 # deltas are in pixels
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 await self.desktop_portal.notify_pointer_axis(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 dx,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 dy
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 else:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 # deltas are in steps (see
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 # https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event#event_properties)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 if dx:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 await self.desktop_portal.notify_pointer_axis(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 1,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 dx
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 if dy:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 await self.desktop_portal.notify_pointer_axis(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 0,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 dy
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 elif type_.startswith("key"):
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 # FIXME: this is a really naive implementation, it needs tot be improved.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 key = data["key"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 if data.get("shiftKey", False):
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 key = key.upper()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 await self.desktop_portal.notify_keyboard_keysym(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
255 ord(key), 1 if type_ == "keydown" else 0
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
257
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 except Exception:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 log.exception(f"Can't handle input {data}")
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
260
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
261
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
262 def _on_dc_message_data(self, data_channel, glib_data) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 """A data chunk of the file has been received."""
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 raw = glib_data.get_data()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 data = cbor2.loads(raw)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 if self.verbose:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
267 print(data)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 aio.run_from_thread(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 self.do_input,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 data,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 loop=self.loop
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
273
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 def _on_dc_close(self, data_channel) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
275 """Data channel is closed
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
276
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
277 The file download should be complete, we close it.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
278 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
279 aio.run_from_thread(self._on_close, loop=self.loop)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
280
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
281 async def _on_close(self) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
282 if self.on_close_cb is not None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
283 await aio.maybe_async(self.on_close_cb())
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
284
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
285 def _on_data_channel(self, webrtcbin, data_channel) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
286 """The data channel has been opened."""
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
287 data_channel.connect(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
288 "on-message-data", self._on_dc_message_data
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
289 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
290 data_channel.connect("on-close", self._on_dc_close)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
291
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
292 async def request_remote_desktop(self, with_screen_sharing: bool) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 """Request autorisation to remote control desktop.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
294
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 @param with_screen_sharing: True if screen must be shared.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
296 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
297 from .portal_desktop import DesktopPortal
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 self.desktop_portal = DesktopPortal()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 self.remote_desktop_data = await self.desktop_portal.request_remote_desktop(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 with_screen_sharing
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
301 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 print(self.remote_desktop_data)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
303
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
304 async def start_receiving(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
305 self,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 from_jid: jid.JID,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 session_id: str,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
308 screenshare: dict
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
309 ) -> None:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
310 """Receives a file via WebRTC and saves it to the specified path.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
311
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
312 @param from_jid: The JID of the entity sending the file.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
313 @param session_id: The Jingle FT Session ID.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
314 @param file_path: The local path where the received file will be saved.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
315 If a file already exists at this path, it will be overwritten.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
316 @param file_data: Additional data about the file being transferred.
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
317 """
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
318 call_data = CallData(callee=from_jid, sid=session_id)
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
319 if "video" in screenshare and self.remote_desktop_data:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
320 try:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
321 stream_data = self.remote_desktop_data["stream_data"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
322 log.debug(f"{stream_data=}")
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
323 self.stream_node_id = stream_data["node_id"]
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
324
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
325 sources_data = SourcesPipeline(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
326 video_pipeline="pipewiresrc",
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
327 audio_pipeline="",
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
328 video_properties={
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
329 "path": str(self.stream_node_id),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
330 "do-timestamp": 1,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
331 }
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
332 )
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
333 except KeyError:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
334 sources_data = SourcesNone()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
335 else:
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
336 sources_data = SourcesNone()
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
337
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
338 await webrtc.WebRTCCall.make_webrtc_call(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
339 self.bridge,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
340 self.profile,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
341 call_data,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
342 sources_data = sources_data,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
343 sinks_data=webrtc.SinksNone(),
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
344 dc_data_list=[webrtc.SinksDataChannel(
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
345 dc_on_data_channel=self._on_data_channel,
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
346 )],
8acf46ed7f36 frontends: remote control implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 )