libervia-backend/libervia/frontends/tools/webrtc_models.py
Goffi de7260bfb9 backend, frontend: prepare remote control:
This is a series of changes necessary to prepare the implementation of remote control
feature:

- XEP-0166: add a `priority` attribute to `ApplicationData`: this is needed when several
  applications are working in a same session, to know which one must be handled first.
  Will be used to make Remote Control have precedence over Call content.
- XEP-0166: `_call_plugins` is now async and is not used with `DeferredList` anymore: the
  benefit to have methods called in parallels is very low, and it cause a lot of trouble
  as we can't predict order. Methods are now called sequentially so workflow can be
  predicted.
- XEP-0167: fix `senders` XMPP attribute <=> SDP mapping
- XEP-0234: preflight acceptance key is now `pre-accepted` instead of `file-accepted`, so
  the same key can be used with other jingle applications.
- XEP-0167, XEP-0343: move some method to XEP-0167
- XEP-0353: use new `priority` feature to call preflight methods of applications according
  to it.
- frontend (webrtc): refactor the sources/sink handling with a more flexible mechanism
  based on Pydantic models. It is now possible to have has many Data Channel as necessary,
  to have them in addition to A/V streams, to specify manually GStreamer sources and
  sinks, etc.
- frontend (webrtc): rework of the pipeline to reduce latency.
- frontend: new `portal_desktop` method. Screenshare portal handling has been moved there,
  and RemoteDesktop portal has been added.
- frontend (webrtc): fix `extract_ufrag_pwd` method.

rel 436
2024-05-11 13:52:41 +02:00

116 lines
3.3 KiB
Python

#!/usr/bin/env python3
# Libervia WebRTC implementation
# Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from collections.abc import Awaitable
from dataclasses import dataclass, field
from typing import Any, Callable
import uuid
import gi
gi.require_versions({"Gst": "1.0", "GstWebRTC": "1.0"})
from gi.repository import GstWebRTC
from pydantic import BaseModel, Field
from libervia.frontends.tools import jid
@dataclass
class CallData:
callee: jid.JID
sid: str | None = None
action_id: str | None = None
kwargs: dict[str, Any] = field(default_factory=dict)
class SourcesData(BaseModel):
"""Data for Sources"""
class SourcesNone(SourcesData):
"""No source is used.
This is used when the WebRTC connection will be used for data channels only."""
class SourcesAuto(SourcesData):
"""Automatic Sources (webcam/microphone)"""
class SourcesTest(SourcesData):
"""Test Sources (pattern)"""
class SourcesDataChannel(SourcesData):
"""Sources for transmitting data over Data Channel
@param dc_open_cb: Called when Data Channel is open.
This callback will be run in a GStreamer thread.
"""
name: str = Field(default_factory=lambda: str(uuid.uuid4()))
dc_open_cb: Callable[[GstWebRTC.WebRTCDataChannel], None]
class SourcesPipeline(SourcesData):
"""Use custom pipeline description as a source.
@param video_pipeline: pipeline description of video source.
None to use automatic video source (same as SourcesAuto).
Empty string to disable video.
@param audio_pipeline: pipeline description of audio source.
None to use automatic audio source (same as SourcesAuto).
Empty string to disable audio.
@param video_properties: Elements properties to set.
@param audio_properties: Elements properties to set.
"""
video_pipeline: str|None = None
audio_pipeline: str|None = None
video_properties: dict = Field(default_factory=lambda: {})
audio_properties: dict = Field(default_factory=lambda: {})
class SinksData(BaseModel):
"""Data for Sinks"""
class SinksNone(SinksData):
"""No sink is used.
This is used when the WebRTC connection will be used for data channels only."""
class SinksAuto(SinksData):
"""Automatic Sinks (create windows/default audio)"""
class SinksApp(SinksData):
local_video_cb: Callable
remote_video_cb: Callable | None
class SinksDataChannel(SinksData):
"""Sinks for transmitting data over Data Channel
@param dc_on_data_channel: Called when Data Channel is created.
This callback will be run in a GStreamer thread.
"""
dc_on_data_channel: (
Callable[[GstWebRTC.WebRTCDataChannel], Awaitable[None]] | None
) = None