diff --git a/libervia/cli/call_no_ui.py b/libervia/cli/call_no_ui.py new file mode 100644 index 00000000..2e1bbe0c --- /dev/null +++ b/libervia/cli/call_no_ui.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +# Libervia CLI +# Copyright (C) 2009-2025 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 . + +from typing import TYPE_CHECKING + +from libervia.frontends.tools import aio +from libervia.frontends.tools.webrtc import CallData, WebRTCCall +from libervia.frontends.tools.webrtc_models import SinksPipeline + +aio.install_glib_asyncio_iteration() + +if TYPE_CHECKING: + from .cmd_call import Common + + +class AVCallUI: + """This class doesn't create any UI.""" + + def __init__(self, host, webrtc=None) -> None: + self.host = host + self.webrtc = webrtc + + @staticmethod + def parse_output_opts(parent: "Common") -> dict: + """Parse output options. + + @return: keyword argument to use to instanciate WebRTCCall + """ + kwargs = {} + for oo in parent.args.output_opts: + if oo.startswith("audio="): + kwargs["audio_pipeline"] = oo[6:].strip() + elif oo.startswith("video="): + kwargs["video_pipeline"] = oo[6:].strip() + else: + parent.parser.error(f"Unknown output option: {oo!r}") + return kwargs + + @classmethod + async def run(cls, parent: "Common", call_data: CallData) -> None: + sinks_kwargs = cls.parse_output_opts(parent) + if ( + call_data.kwargs.get("record_fd") is not None + and not "audio_pipeline" in sinks_kwargs + and not "video_pipeline" in sinks_kwargs + ): + # If we have `record_fd` set, we are piping out the stream. If no pipeline is + # explictely specified, we disable the UI by using empty string. + sinks_kwargs["audio_pipeline"] = sinks_kwargs["video_pipeline"] = "" + call_data.kwargs["sinks_data"] = SinksPipeline(**sinks_kwargs) + + webrtc_call = await WebRTCCall.make_webrtc_call( + parent.host.bridge, + parent.profile, + call_data, + merge_pip=False, + on_call_setup_cb=lambda sid, profile: parent.host.add_on_quit_callback( + parent.host.bridge.call_end, sid, "", profile + ), + on_call_ended_cb=lambda sid, profile: parent.host.a_quit(), + ) + + cls(parent.host, webrtc_call.webrtc) diff --git a/libervia/cli/call_simple.py b/libervia/cli/call_simple.py index 71992600..4d43eaa0 100644 --- a/libervia/cli/call_simple.py +++ b/libervia/cli/call_simple.py @@ -175,6 +175,5 @@ class AVCallUI(BaseAVTUI): on_call_ended_cb=lambda sid, profile: parent.host.a_quit(), **kwargs, ) - if not parent.args.no_ui: - ui = cls(parent.host, webrtc_call.webrtc) - await ui.start() + ui = cls(parent.host, webrtc_call.webrtc) + await ui.start() diff --git a/libervia/cli/cmd_call.py b/libervia/cli/cmd_call.py index 1406935f..4330381a 100644 --- a/libervia/cli/cmd_call.py +++ b/libervia/cli/cmd_call.py @@ -23,7 +23,6 @@ import importlib import logging from typing import Any import sys -import select from libervia.backend.core.i18n import _ @@ -52,14 +51,13 @@ class Common(base.CommandBase): "gui": partial(self.use_output, "gui"), #: experimental TUI output "tui": partial(self.use_output, "tui"), + #: No UI is created. + "no_ui": partial(self.use_output, "no_ui"), }, **kwargs, ) def add_parser_options(self): - self.parser.add_argument( - "--no-ui", action="store_true", help=_("disable user interface") - ) self.parser.add_argument( "-s", "--sources",