annotate libervia/backend/plugins/plugin_comp_conferences/__init__.py @ 4306:94e0968987cd

plugin XEP-0033: code modernisation, improve delivery, data validation: - Code has been rewritten using Pydantic models and `async` coroutines for data validation and cleaner element parsing/generation. - Delivery has been completely rewritten. It now works even if server doesn't support multicast, and send to local multicast service first. Delivering to local multicast service first is due to bad support of XEP-0033 in server (notably Prosody which has an incomplete implementation), and the current impossibility to detect if a sub-domain service handles fully multicast or only for local domains. This is a workaround to have a good balance between backward compatilibity and use of bandwith, and to make it work with the incoming email gateway implementation (the gateway will only deliver to entities of its own domain). - disco feature checking now uses `async` corountines. `host` implementation still use Deferred return values for compatibility with legacy code. rel 450
author Goffi <goffi@goffi.org>
date Thu, 26 Sep 2024 16:12:01 +0200
parents a0ed5c976bf8
children
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
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
20 import os
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 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
22 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
23
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 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
25 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
26 import treq
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 import defer, reactor
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 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
29 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
30 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
31 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
32 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
33 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
34 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
35 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
36 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
37 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
38
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 import exceptions
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.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
41 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
42 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
43 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
44 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
45 from libervia.backend.plugins.plugin_xep_0166 import XEP_0166
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
46 from libervia.backend.plugins.plugin_xep_0167 import XEP_0167, mapping, NS_AV_CONFERENCES
4278
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.plugins.plugin_xep_0176 import XEP_0176
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
48 from libervia.backend.plugins.plugin_xep_0298 import XEP_0298
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 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
50
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 log = getLogger(__name__)
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 IMPORT_NAME = "conferences"
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
55 NAME = "Libervia A/V Conferences"
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 PLUGIN_INFO = {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 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
59 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
60 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
61 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
62 C.PI_PROTOCOLS: [],
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
63 C.PI_DEPENDENCIES: ["XEP-0106", "XEP-0166", "XEP-0167", "XEP-0176", "XEP-0298"],
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 C.PI_RECOMMENDATIONS: [],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 C.PI_MAIN: "ConferencesComponent",
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
66 C.PI_HANDLER: C.BOOL_TRUE,
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 C.PI_DESCRIPTION: _(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 "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
69 "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
70 ),
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 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
74
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
75
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 class Conference:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
77
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 def __init__(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 parent: "ConferencesComponent",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 group_name: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 data_file: Path,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 endpoint: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 status_url: str,
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
85 session: dict,
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 self.parent = parent
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 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
89 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
90 self.endpoint = endpoint
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 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
92 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
93 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
94 self.ready = defer.Deferred()
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
95 self.session = session
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
96
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 def __str__(self):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 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
99
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 @property
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) -> "GaleneProtocol":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 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
103 return self._protocol
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 @protocol.setter
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 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
107 self._protocol = protocol
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 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
109
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 @property
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
111 def client_id(self) -> str:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
112 return self.protocol.client_id
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
113
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
114 @property
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 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
116 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
117
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 @property
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
119 def _rtp(self) -> XEP_0167:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
120 return self.parent._rtp
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
121
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
122 @property
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 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
124 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
125
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 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
128 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
129 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
130 return client
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
131
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
132 @property
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
133 def galene_id(self) -> str:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
134 """ID to use with Galène API."""
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
135 return f"{self.client_id}-{self.session['id']}"
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
136
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
137 async def on_call_setup(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
138 self,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
139 client: SatXMPPEntity,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
140 session: dict,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
141 call_data: dict,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
142 ) -> None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
143 if call_data["role"] == self._j.ROLE_INITIATOR:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
144 self.send_answer(session["id"], call_data["sdp"])
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
145 else:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
146 raise exceptions.InternalError(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
147 '"role" should be "{self._j.ROLE_INITIATOR}" here.'
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
148 )
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
149
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 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
151 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
152 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 "type": "join",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 "kind": "join",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 "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
156 "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
157 "password": "",
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
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
161 def send_request(self, requested: dict | None = None) -> None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
162 if requested is None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
163 requested = {"": ["audio", "video"]}
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
164 self.protocol.send_data({"type": "request", "request": requested})
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
165
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
166 def send_offer(self, sdp: str) -> None:
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 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
168 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 "type": "offer",
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
170 "id": self.galene_id,
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 "label": "camera",
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
172 "username": self.session["peer_jid"].userhost(),
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 "sdp": sdp,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 }
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
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
177 def send_answer(self, session_id: str, sdp: str) -> None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
178 data_id = session_id[len(self.client_id) + 1 :]
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
179 self.protocol.send_data(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
180 {
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
181 "type": "answer",
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
182 "id": data_id,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
183 "label": "camera",
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
184 "username": self.session["peer_jid"].userhost(),
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
185 "sdp": sdp,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
186 }
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
187 )
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
188
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
189 def add_candidate(self, candidate: dict, sdp_mid: str, sdp_mline_index: int) -> None:
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 """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
191
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 @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
193 """
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 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
195 {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 "type": "ice",
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
197 "id": self.galene_id,
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 "candidate": {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 "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
200 "sdpMid": sdp_mid,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 "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
202 },
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
205
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 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
207 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
208 match data["kind"]:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 case "join":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 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
211 case "fail":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 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
213 case "change":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 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
215 case "leave":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 log.info(f"{user_jid} has left {self}.")
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
217 self.send_request()
4278
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 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
220 """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
221
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 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
223 """
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 try:
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
225 answer_sdp_d = self.session.pop("answer_sdp_d")
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 except KeyError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 raise exceptions.InternalError(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 '"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
229 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 else:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 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
232
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
233 def on_offer(self, data: dict) -> None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
234 """Called when a new SFP offer has been received"""
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
235 defer.ensureDeferred(self.a_on_offer(data))
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
236
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
237 async def a_on_offer(self, data: dict) -> None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
238 client: SatXMPPEntity = self.client.get_virtual_client(self.session["local_jid"])
4294
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
239 call_data = {"sdp": data["sdp"]}
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
240 try:
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
241 # FIXME: This assume that all username are coming from XMPP, "source" should
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
242 # be used instead to be sure to match XMPP users, and other ones should use
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
243 # a non "xmpp:" URL scheme.
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
244 user_jid = jid.JID(data["username"])
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
245 if not user_jid.user:
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
246 raise ValueError("Missing user part.")
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
247 except Exception as e:
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
248 log.warning("Username is not a JID: {data['username']=}, {e}")
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
249 else:
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
250 call_data["metadata"] = {"user": user_jid}
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
251 sid = await self._rtp.call_start(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
252 client,
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
253 self.session["peer_jid"],
4294
a0ed5c976bf8 component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
Goffi <goffi@goffi.org>
parents: 4286
diff changeset
254 call_data,
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
255 session_id=f"{self.client_id}-{data['id']}",
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
256 )
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
257 session = self._j.get_session(client, sid)
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
258 session["call_setup_cb"] = self.on_call_setup
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
259
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
260 def on_ice(self, data: dict) -> None:
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
261 if data["id"] == self.galene_id:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
262 session = self.session
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
263 else:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
264 session = self._j.get_session(self.client, f"{self.client_id}-{data['id']}")
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
265 log.debug(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
266 f"ICE candidate for session {session['id']}, peer_jid={session['peer_jid']}."
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
267 )
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 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
269 contents = session["contents"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 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
272 except IndexError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 log.error(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 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
275 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
277 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
278 local_ice_data = content["transport_data"]["local_ice_data"]
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
279
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
280 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
281 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
282 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
283 defer.ensureDeferred(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
284 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
285 client,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
286 session["id"],
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 media: {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
289 "candidates": [candidate],
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
290 "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
291 "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
292 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 },
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
294 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
296
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
297
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 class GaleneClientFactory(WebSocketClientFactory):
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 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
301 self.conference = conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 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
303
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
304
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
305 class GaleneProtocol(WebSocketClientProtocol):
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
306
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
307 def __init__(self, *args, **kwargs):
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
308 super().__init__(*args, **kwargs)
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
309 self.client_id = str(uuid())
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
310
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
311 @property
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
312 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
313 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
314 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
315 return conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
316
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
317 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
318 super().connectionMade()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
319 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
320
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
321 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
322 super().connectionLost(reason)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
323
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
324 def onOpen(self):
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
325 handshake_data = {"type": "handshake", "version": ["2"], "id": self.client_id}
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
326 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
327
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
328 def send_data(self, data: dict) -> None:
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
329 if ConferencesComponent.verbose:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
330 log.debug(f"=> DATA SENT [{self.client_id}]: {data}")
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
331 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
332
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
333 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
334 if isBinary:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
335 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
336 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
337 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
338 except json.JSONDecodeError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
339 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
340 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
341
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
342 if ConferencesComponent.verbose:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
343 log.debug(f"<= DATA RECEIVED [{self.client_id}]: {data}")
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
344 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
345 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
346 case None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
347 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
348 case "handshake":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
349 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
350
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
351 log.debug(
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
352 f"Handshake for group {self.conference.group_name!r}. Galène "
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
353 f"protocol v{version}."
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
354 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
355 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
356 case "ping":
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
357 log.debug("pong")
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
358 self.send_data({"type": "pong"})
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
359 case "joined" | "answer" | "ice" | "offer" as data_type:
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
360 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
361 method(data)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
362 case _:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
363 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
364 except (KeyError, IndexError):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
365 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
366
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
367
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
368 class ConferencesComponent:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
369 IMPORT_NAME = IMPORT_NAME
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
370 verbose = 0
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
371
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
372 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
373 self.host = host
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
374 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
375 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
376 self._j: XEP_0166 = host.plugins["XEP-0166"]
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
377 self._rtp: XEP_0167 = host.plugins["XEP-0167"]
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
378 self._ice_udp: XEP_0176 = host.plugins["XEP-0176"]
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
379 self._coin: XEP_0298 = host.plugins["XEP-0298"]
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
380 host.trigger.add("XEP-0167_jingle_handler", self._jingle_handler_trigger)
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
381 self.initalized = False
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
382
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
383 def _init(self) -> None:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
384 """Initialisation done after profile is connected"""
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
385 assert self.client is not None
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
386 self.client.identities.append(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
387 disco.DiscoIdentity("conference", "audio-video", NAME)
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
388 )
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
389
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
390 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
391 galene_path = Path(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
392 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
393 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
394 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
395 except IndexError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
396 raise exceptions.NotFound(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
397 '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
398 "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
399 '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
400 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 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
402 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
403 )
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
404 galene_data_path = self.host.memory.get_cache_path(IMPORT_NAME, "galene")
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
405 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
406 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
407 self.galene_group_path.mkdir(0o700, parents=True, exist_ok=True)
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
408 env = os.environ
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
409 if self.verbose >= 2:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
410 # We activate Galène debug logs on ICE candidates.
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
411 env["PION_LOG_TRACE"] = "ice"
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
412
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
413 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
414 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
415 str(galene_path),
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
416 "-static",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
417 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
418 "-http",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
419 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
420 # 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
421 "-insecure",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
422 path=str(galene_data_path),
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
423 verbose=bool(self.verbose),
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
424 env=env,
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
425 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
426 except Exception:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
427 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
428 else:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
429 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
430 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
431
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
432 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
433 return ConferencesHandler()
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
434
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
435 def profile_connecting(self, client: SatXMPPEntity) -> None:
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
436 self.client = client
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
437 if not self.initalized:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
438 self._init()
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
439 self.initalized = True
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
440
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
441 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
442 """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
443
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
444 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
445 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
446
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
447 @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
448 @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
449 @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
450 """
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
451 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
452 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
453 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
454 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
455 group_data = {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
456 "wildcard-user": {
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
457 "password": {"type": "wildcard"},
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
458 "permissions": "present",
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
459 },
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
460 }
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
461 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
462 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
463 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
464
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
465 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
466 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
467
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
468 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
469 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
470 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
471 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
472 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
473 conference = Conference(
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
474 parent=self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
475 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
476 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
477 endpoint=endpoint,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
478 status_url=status_url,
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
479 session=session,
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
480 )
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
481
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
482 factory = GaleneClientFactory(conference)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
483 # 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
484 factory.protocol = GaleneProtocol
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
485 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
486
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
487 return conference
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
488
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
489 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
490 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
491 client: SatXMPPEntity,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
492 action: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
493 session: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
494 content_name: str,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
495 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
496 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
497 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
498 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
499 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
500 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
501 # 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
502 return
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
503 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
504 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
505 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
506 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
507
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
508 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
509 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
510 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
511 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
512
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
513 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
514 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
515 client: SatXMPPEntity,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
516 session: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
517 call_data: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
518 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
519 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
520 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
521 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
522 conference = session["conference"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
523 except KeyError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
524 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
525
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
526 if call_data["role"] == self._j.ROLE_RESPONDER:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
527 await conference.ready
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
528 conference.join(session["peer_jid"])
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
529 conference.send_offer(call_data["sdp"])
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
530 else:
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
531 raise exceptions.InternalError(
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
532 '"role" should be "{self._j.ROLE_RESPONDER}" here.'
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
533 )
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
534
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
535 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
536 self,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
537 client: SatXMPPEntity,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
538 session: dict,
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
539 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
540 ) -> None:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
541 try:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
542 conference = session["conference"]
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
543 except KeyError:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
544 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
545 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
546 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
547 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
548 break
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
549 else:
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
550 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
551 continue
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
552 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
553 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
554
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
555 for candidate in media_data["candidates"]:
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
556 conference.add_candidate(candidate, sdp_mid, sdp_mline_index)
4278
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
557
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
558 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
559 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
560
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
561
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
562 @implementer(iwokkel.IDisco)
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
563 class ConferencesHandler(XMPPHandler):
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
564
240d8b7ad906 component Conferences: implementation of SFU component to make multi-party A/V conferences:
Goffi <goffi@goffi.org>
parents:
diff changeset
565 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
4286
96fdf4891747 component conferences: fix session management and init:
Goffi <goffi@goffi.org>
parents: 4278
diff changeset
566 return [disco.DiscoFeature(NS_AV_CONFERENCES)]