Mercurial > libervia-backend
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 |
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 ) |