Mercurial > libervia-backend
diff libervia/cli/cmd_call.py @ 4206:0f8ea0768a3b
cli (call): implement GUI output:
``call`` commands now handle various output. Beside the original one (now named
``simple``), a new ``gui`` one display a full featured GUI (make with Qt).
PyQt 6 or more needs to be installed.
rel 427
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 11 Feb 2024 23:20:24 +0100 |
parents | 849721e1563b |
children | 9218d4331bb2 |
line wrap: on
line diff
--- a/libervia/cli/cmd_call.py Thu Jan 18 23:29:25 2024 +0100 +++ b/libervia/cli/cmd_call.py Sun Feb 11 23:20:24 2024 +0100 @@ -20,9 +20,12 @@ from argparse import ArgumentParser import asyncio +from dataclasses import dataclass from functools import partial import logging import os +from pathlib import Path +from typing import Callable from prompt_toolkit.input import create_input from prompt_toolkit.keys import Keys @@ -42,14 +45,27 @@ __commands__ = ["Call"] +@dataclass +class CallData: + callee: jid.JID + sid: str|None = None + action_id: str|None = None + + class WebRTCCall: - def __init__(self, host, profile: str, callee: jid.JID): + def __init__(self, host, profile: str, callee: jid.JID, **kwargs): + """Create and setup a webRTC instance + + @param profile: profile making or receiving the call + @param callee: peer jid + @param kwargs: extra kw args to use when instantiating WebRTC + """ from libervia.frontends.tools import webrtc aio.install_glib_asyncio_iteration() self.host = host self.profile = profile - self.webrtc = webrtc.WebRTC(host.bridge, profile) + self.webrtc = webrtc.WebRTC(host.bridge, profile, **kwargs) self.webrtc.callee = callee host.bridge.register_signal( "ice_candidates_new", self.on_ice_candidates_new, "plugin" @@ -197,6 +213,19 @@ class Common(base.CommandBase): + + def __init__(self, *args, **kwargs): + super().__init__( + *args, + use_output=C.OUTPUT_CUSTOM, + extra_outputs={ + "default": self.auto_output, + "simple": self.simple_output, + "gui": self.gui_output, + }, + **kwargs + ) + def add_parser_options(self): self.parser.add_argument( "--no-ui", action="store_true", help=_("disable user interface") @@ -214,11 +243,51 @@ if self.verbosity >= 2: root_logger.setLevel(logging.DEBUG) - async def start_ui(self, webrtc_call): + async def make_webrtc_call(self, call_data: CallData, **kwargs) -> WebRTCCall: + """Create the webrtc_call instance + + @param call_data: Call data of the command + @param kwargs: extra args used to instanciate WebRTCCall + + """ + webrtc_call = WebRTCCall(self.host, self.profile, call_data.callee, **kwargs) + if call_data.sid is None: + # we are making the call + await webrtc_call.start() + else: + # we are receiving the call + webrtc_call.sid = call_data.sid + if call_data.action_id is not None: + await self.host.bridge.action_launch( + call_data.action_id, + data_format.serialise({"cancelled": False}), + self.profile + ) + return webrtc_call + + async def auto_output(self, call_data: CallData): + """Make a guess on the best output to use on current platform""" + # For now we just use simple output + await self.simple_output(call_data) + + async def simple_output(self, call_data: CallData): + """Run simple output, with GStreamer ``autovideosink``""" + webrtc_call = await self.make_webrtc_call(call_data) if not self.args.no_ui: ui = UI(self.host, webrtc_call.webrtc) await ui.start() + async def gui_output(self, call_data: CallData): + """Run GUI output""" + media_dir = Path(await self.host.bridge.config_get("", "media_dir")) + icons_path = media_dir / "fonts/fontello/svg" + try: + from .call_gui import AVCallGUI + await AVCallGUI.run(self, call_data, icons_path) + except Exception as e: + self.disp(f"Error starting GUI: {e}", error=True) + self.host.quit(C.EXIT_ERROR) + class Make(Common): def __init__(self, host): @@ -239,10 +308,9 @@ async def start(self): await super().start() - callee = jid.JID(self.args.entity) - webrtc_call = WebRTCCall(self.host, self.profile, callee) - await webrtc_call.start() - await super().start_ui(webrtc_call) + await super().output(CallData( + callee=jid.JID(self.args.entity), + )) class Receive(Common): @@ -297,12 +365,11 @@ self.disp(_("✅ Incoming call from {caller} accepted.").format(caller=caller)) - webrtc_call = WebRTCCall(self.host, self.profile, peer_jid) - webrtc_call.sid = action_data["session_id"] - await self.host.bridge.action_launch( - action_id, data_format.serialise({"cancelled": False}), profile - ) - await super().start_ui(webrtc_call) + await super().output(CallData( + callee=peer_jid, + sid=action_data["session_id"], + action_id=action_id + )) async def start(self): await super().start()