annotate libervia/backend/plugins/plugin_comp_conferences/__init__.py @ 4278:240d8b7ad906

component Conferences: implementation of SFU component to make multi-party A/V conferences: This component wrap `Galène` SFU and translate its signaling to XMPP Jingle in both direction. rel 445
author Goffi <goffi@goffi.org>
date Fri, 05 Jul 2024 17:18:37 +0200
parents
children 96fdf4891747
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia A/V Conferences Component
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import json
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from pathlib import Path
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from urllib.parse import quote
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
22
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from autobahn.twisted.websocket import WebSocketClientFactory, WebSocketClientProtocol
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from shortuuid import uuid
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 import treq
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.internet import defer, reactor
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from twisted.internet.error import ConnectionDone
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from twisted.python import failure
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from twisted.python.failure import Failure
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from twisted.python.procutils import which
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from twisted.words.protocols.jabber import jid
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from twisted.words.protocols.jabber.error import StanzaError
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 from twisted.words.xish import domish
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 from wokkel import disco, iwokkel
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 from zope.interface import implementer
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 from libervia.backend.core import exceptions
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 from libervia.backend.core.constants import Const as C
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 from libervia.backend.core.core_types import SatXMPPEntity
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 from libervia.backend.core.i18n import _
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 from libervia.backend.core.log import getLogger
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 from libervia.backend.plugins.plugin_xep_0106 import XEP_0106
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 from libervia.backend.plugins.plugin_xep_0166 import XEP_0166
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 from libervia.backend.plugins.plugin_xep_0167 import mapping
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 from libervia.backend.plugins.plugin_xep_0176 import XEP_0176
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 from libervia.backend.tools.common import async_process, regex
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
49
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 log = getLogger(__name__)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
51
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 IMPORT_NAME = "conferences"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
53
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 PLUGIN_INFO = {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 C.PI_NAME: "A/V Conferences Component",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 C.PI_IMPORT_NAME: IMPORT_NAME,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 C.PI_MODES: [C.PLUG_MODE_COMPONENT],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 C.PI_PROTOCOLS: [],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 C.PI_DEPENDENCIES: ["XEP-0106", "XEP-0166", "XEP-0167", "XEP-0176"],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 C.PI_RECOMMENDATIONS: [],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 C.PI_MAIN: "ConferencesComponent",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 C.PI_HANDLER: C.BOOL_FALSE,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 C.PI_DESCRIPTION: _(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 "Handle multiparty audio/video conferences, using a Selective Forwarding Unit.\n"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 "The Galène project (https://galene.org) is currently the only supported backend."
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 ),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
69
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 CONF_SECTION = f"component {IMPORT_NAME}"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
71
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
72
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 class Conference:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
74
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 def __init__(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 parent: "ConferencesComponent",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 group_name: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 data_file: Path,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 endpoint: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 status_url: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 self.parent = parent
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 self.group_name = group_name
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self.data_file = data_file
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 self.endpoint = endpoint
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 self.status_url = status_url
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 self._protocol: "GaleneProtocol|None" = None
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 self.connected = defer.Deferred()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 self.ready = defer.Deferred()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
91
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 def __str__(self):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 return f"conference {self.group_name!r}"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
94
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 def protocol(self) -> "GaleneProtocol":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 assert self._protocol is not None
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 return self._protocol
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
99
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 @protocol.setter
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 def protocol(self, protocol: "GaleneProtocol") -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 self._protocol = protocol
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 self.connected.callback(None)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
104
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 def _j(self) -> XEP_0166:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 return self.parent._j
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
108
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 def _ice_udp(self) -> XEP_0176:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 return self.parent._ice_udp
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
112
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 def client(self) -> SatXMPPEntity:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 client = self.parent.client
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 assert client is not None
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 return client
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
118
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 def join(self, user_jid: jid.JID) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 self.protocol.send_data(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 "type": "join",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 "kind": "join",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 "group": self.data_file.stem,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 "username": user_jid.userhost(),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 "password": "",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
129
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 def send_offer(self, session: dict, sdp: str) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 self.protocol.send_data(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 "type": "offer",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 "id": session["id"],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 "label": "camera",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 "username": session["peer_jid"].userhost(),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 "sdp": sdp,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
140
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 def add_candidate(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 self, session: dict, candidate: dict, sdp_mid: str, sdp_mline_index: int
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 """Add an ICE candidate.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
145
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 @param session: Jingle session.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 @param candidate: ICE candidate, SDP format.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 """
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 self.protocol.send_data(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 "type": "ice",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 "id": session["id"],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 "candidate": {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 "candidate": mapping.generate_candidate_line(candidate),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 "sdpMid": sdp_mid,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 "sdpMLineIndex": sdp_mline_index,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 },
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
160
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 def on_joined(self, data: dict) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 user_jid = jid.JID(data["username"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 match data["kind"]:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 case "join":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 log.info(f"{user_jid} has joined {self}.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 case "fail":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 log.warning(f"{user_jid} can't join {self}: {data}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 case "change":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 log.debug(f"Change for {user_jid} in {self}.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 case "leave":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 log.info(f"{user_jid} has left {self}.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
172
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 def on_answer(self, data: dict) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 """Called when SDP answer has been received
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
175
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 Send the SDP to ``answer_sdp_d`` to continue workflow.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 """
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 session = self._j.get_session(self.client, data["id"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 answer_sdp_d = session.pop("answer_sdp_d")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 except KeyError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 raise exceptions.InternalError(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 '"answer_sdp_d" should be available in session.'
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 else:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 answer_sdp_d.callback(data["sdp"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
187
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 def on_ice(self, data: dict) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 log.debug(f"ICE candidate: {data}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 session = self._j.get_session(self.client, data["id"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 candidate_data = data["candidate"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 contents = session["contents"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 content_id = list(contents)[candidate_data["sdpMLineIndex"]]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 except IndexError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 log.error(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 f"Can't find any content at index {candidate_data['sdpMLineIndex']}."
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 content = contents[content_id]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 local_ice_data = content["transport_data"]["local_ice_data"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 media = content["application_data"]["media"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 client: SatXMPPEntity = self.client.get_virtual_client(session["local_jid"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 candidate = mapping.parse_candidate(candidate_data["candidate"][10:].split())
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 defer.ensureDeferred(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 self._ice_udp.ice_candidates_add(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 client,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 session["id"],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 media: {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 "candidates": [candidate],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 "ufrag": local_ice_data["ufrag"],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 "pwd": local_ice_data["pwd"],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 },
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
218
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
219
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 class GaleneClientFactory(WebSocketClientFactory):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
221
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 def __init__(self, conference: Conference) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 self.conference = conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 super().__init__(conference.endpoint)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
225
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
226
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 class GaleneProtocol(WebSocketClientProtocol):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 verbose = True
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
229
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 def conference(self) -> Conference:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 conference: Conference = self.factory.conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 assert conference is not None
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 return conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
235
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 def connectionMade(self) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 super().connectionMade()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 self.conference.protocol = self
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
239
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 def connectionLost(self, reason: failure.Failure = ConnectionDone) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 super().connectionLost(reason)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
242
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 def onOpen(self):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 handshake_data = {"type": "handshake", "version": ["2"], "id": str(uuid())}
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 self.send_data(handshake_data)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
246
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 def send_data(self, data: dict) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 if self.verbose:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 log.debug(f"DATA SENT: {data}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 self.sendMessage(json.dumps(data).encode())
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
251
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 def onMessage(self, payload, isBinary):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 if isBinary:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 raise exceptions.DataError("Unexpected binary payload: {payload!r}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
255 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 data = json.loads(payload)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
257 except json.JSONDecodeError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 log.warning(f"Can't decode data: {payload!r}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
260
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
262 match data.get("type"):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 case None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 log.warning(f'"type" is missing in data: {data!r}')
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 case "handshake":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 version = data["version"][0]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
267
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 log.debug(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 f"Handshake for group {self.conference.group_name!r}. Galène protocol "
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 f" v{version}."
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 self.conference.ready.callback(None)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 case "ping":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 log.debug("pong")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
275 self.send_data({"type": "pong"})
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 case "joined" | "answer" | "ice" as data_type:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
277 method = getattr(self.conference, f"on_{data_type}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
278 method(data)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
279 case _:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
280 log.debug(f"Unhandled message: {data}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
281 except (KeyError, IndexError):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
282 log.exception(f"Unexpected data format: {data!r}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
283
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
284
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
285 class ConferencesComponent:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
286 IMPORT_NAME = IMPORT_NAME
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
287
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
288 def __init__(self, host):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
289 self.host = host
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
290 self.client: SatXMPPEntity | None = None
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
291 self._e: XEP_0106 = host.plugins["XEP-0106"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
292 self._j: XEP_0166 = host.plugins["XEP-0166"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 self._ice_udp: XEP_0176 = host.plugins["XEP-0176"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
294 host.trigger.add("XEP-0167_jingle_handler", self._jingle_handler_trigger)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
296 galene_path = Path(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
297 self.host.memory.config_get(CONF_SECTION, "galene_path")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 or which("galene")[0]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 except IndexError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
301 raise exceptions.NotFound(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 'Can\'t find "galene" executable, "conferences" component can\'t be '
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
303 "started without it. Please install it in location accessible in PATH, "
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
304 'or use "galene_path" setting.'
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
305 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 self.galene_http_port = self.host.memory.config_get(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 CONF_SECTION, "http_port", "9443"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
308 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
309 galene_data_path = host.memory.get_cache_path(IMPORT_NAME, "galene")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
310 galene_static_path = galene_path.parent / "static"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
311 self.galene_group_path = galene_data_path / "groups"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
312 self.galene_group_path.mkdir(0o700, parents=True, exist_ok=True)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
313 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
314 d = self._process = async_process.run(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
315 str(galene_path),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
316 "-static",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
317 str(galene_static_path),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
318 "-http",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
319 f"127.0.0.1:{self.galene_http_port}",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
320 # We don't want HTTPS here, it's only used for local interactions
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
321 "-insecure",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
322 path=str(galene_data_path),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
323 verbose=True,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
324 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
325 except Exception:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
326 log.exception("Can't start Galene.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
327 else:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
328 d.addErrback(self._galene_process_errback)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
329 log.info(f"Galene instance started on port {self.galene_http_port}.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
330
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
331 def get_handler(self, __):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
332 return ConferencesHandler()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
333
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
334 def profile_connecting(self, client):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
335 self.client = client
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
336
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
337 async def attach_to_group(self, session: dict, group_name: str) -> Conference:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
338 """Attach to a Galène group.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
339
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
340 Create a group data file if it doesn't exist.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
341 Create and attach a Galene client.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
342
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
343 @param session: Jingle session data.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
344 @param group_name: name of the conference group.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
345 @return conference: Data of the conference.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
346 """
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 stem = regex.path_escape(group_name)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
348 filename = f"{stem}.json"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
349 data_file = self.galene_group_path / filename
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
350 if not data_file.exists():
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
351 group_data = {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
352 "wildcard-user": {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
353 "password": {"type": "wildcard"},
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
354 "permissions": "present",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
355 },
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
356 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
357 with data_file.open("w") as f:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
358 json.dump(group_data, f)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
359 log.debug(f"Conference data for {group_name!r} created at " f"{data_file} .")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
360
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
361 url = f"http://localhost:{self.galene_http_port}/group/{quote(stem)}"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
362 status_url = f"{url}/.status"
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
363
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
364 log.debug(f"Attaching to Galene.\n{url=}\n{status_url=}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
365 resp = await treq.get(status_url)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
366 group_status = await resp.json()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
367 log.debug(f"{group_status=}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
368 endpoint = group_status["endpoint"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
369 conference = Conference(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
370 parent=self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
371 group_name=group_name,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
372 data_file=data_file,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
373 endpoint=endpoint,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
374 status_url=status_url,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
375 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
376
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
377 factory = GaleneClientFactory(conference)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
378 # factory.setProtocolOptions(logOctets=True)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
379 factory.protocol = GaleneProtocol
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
380 reactor.connectTCP("127.0.0.1", int(self.galene_http_port), factory)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
381
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
382 return conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
383
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
384 async def _jingle_handler_trigger(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
385 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
386 client: SatXMPPEntity,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
387 action: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
388 session: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
389 content_name: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
390 desc_elt: domish.Element,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
391 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
392 if client != self.client:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
393 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
394 if action == self._j.A_PREPARE_CONFIRMATION:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
395 if "conference" in session:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
396 # We have already set up the conference.
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
397 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
398 local_jid: jid.JID = session["local_jid"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
399 if not local_jid.user:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
400 raise StanzaError("forbidden", "A room name must be specified.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 group_name = self._e.unescape(local_jid.user)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
402
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
403 session["conference"] = await self.attach_to_group(session, group_name)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
404 session["pre_accepted"] = True
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
405 session["call_setup_cb"] = self.on_call_setup
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
406 session["ice_candidates_new_cb"] = self.on_ice_candidates_new
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
407
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
408 async def on_call_setup(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
409 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
410 client: SatXMPPEntity,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
411 session: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
412 call_data: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
413 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
414 if self.client is None or client != self.client:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
415 raise exceptions.InternalError(f"Unexpected client: {client}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
416 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
417 conference = session["conference"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
418 except KeyError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
419 raise exceptions.InternalError("Conference data is missing.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
420
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
421 await conference.ready
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
422 conference.join(session["peer_jid"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
423 conference.send_offer(session, call_data["sdp"])
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
424
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
425 def on_ice_candidates_new(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
426 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
427 client: SatXMPPEntity,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
428 session: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
429 ice_candidates_data: dict[str, dict],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
430 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
431 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
432 conference = session["conference"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
433 except KeyError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
434 raise exceptions.InternalError("Conference data is missing.")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
435 for media, media_data in ice_candidates_data.items():
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
436 for idx, (content_id, content) in enumerate(session["contents"].items()):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
437 if content["application_data"]["media"] == media:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
438 break
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
439 else:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
440 log.error(f"Can't find corresponding content for {media!r}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
441 continue
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
442 sdp_mline_index: int = idx
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
443 sdp_mid: str = content_id
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
444
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
445 for candidate in media_data["candidates"]:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
446 conference.add_candidate(session, candidate, sdp_mid, sdp_mline_index)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
447
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
448 def _galene_process_errback(self, failure_: Failure) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
449 log.error(f"Can't run Galene process: {failure_.value}")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
450
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
451
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
452 @implementer(iwokkel.IDisco)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
453 class ConferencesHandler(XMPPHandler):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
454
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
455 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
456 return [disco.DiscoIdentity("conference", "audio-video")]