annotate libervia/cli/call_tui.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 0d7bb4df2343
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia CLI
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 import asyncio
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from functools import partial
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 import sys
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from PIL import Image
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 import gi
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from rich.padding import Padding
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from term_image import image as t_image
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
28
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from libervia.cli.constants import Const as C
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
30 from libervia.frontends.tools import aio, webrtc
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
31 from libervia.frontends.tools.webrtc import CallData, WebRTCCall
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
32
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 from .call_simple import BaseAVTUI
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
34
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 gi.require_versions({"Gst": "1.0", "GstWebRTC": "1.0"})
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 from gi.repository import Gst
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
40 aio.install_glib_asyncio_iteration()
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
41
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
42
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 class AVCallUI(BaseAVTUI):
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 def __init__(self, parent):
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 super().__init__(parent.host, align="center")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 self.parent = parent
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 self.image_rows = 0
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 self.buffer = None
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 self._processing = False
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 self.render_class: t_image.ImageMeta | None = None
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 self.target_size
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 self.fps = 25
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 for oo in parent.args.output_opts:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 if oo.startswith("renderer="):
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 renderer = oo[9:].lower().strip()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 match renderer:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 case "auto":
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 # we let None as it will auto-detect best option later
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 pass
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 case "block":
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 self.render_class = t_image.BlockImage
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 case "iterm2":
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 self.render_class = t_image.ITerm2Image
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 case "kitty":
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 self.render_class = t_image.KittyImage
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 case _:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 parent.parser.error(f"Invalid renderer: {renderer!r}")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 elif oo.startswith("fps="):
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 try:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 self.fps = int(oo[4:])
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 except ValueError:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 parent.parser.error(f"Invalid FPS: {oo[4:]!r}")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
73
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 async def init_call(self, call_data):
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 kwargs = self.parse_output_opts(self.parent)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 if "target_size" not in kwargs:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 # we use low res by default for performance reason
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 kwargs["target_size"] = (640, 380)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 webrtc_call = await WebRTCCall.make_webrtc_call(
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
80 self.parent.host.bridge,
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 self.parent.profile,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 call_data,
4240
79c8a70e1813 backend, frontend: prepare remote control:
Goffi <goffi@goffi.org>
parents: 4233
diff changeset
83 sinks_data=webrtc.SinksApp(
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 local_video_cb=partial(self.on_new_sample, video_stream="local"),
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 remote_video_cb=None,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 ),
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 merge_pip=True,
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
88 # we want to be sure that call is ended if user presses `Ctrl + c` or anything
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
89 # else stops the session.
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
90 on_call_setup_cb=lambda sid, profile: self.parent.host.add_on_quit_callback(
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
91 self.parent.host.bridge.call_end, sid, "", profile
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
92 ),
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4210
diff changeset
93 on_call_ended_cb=lambda sid, profile: self.parent.host.a_quit(),
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 **kwargs,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 )
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 self.webrtc = webrtc_call.webrtc
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
97
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 async def start(self, call_data):
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 term_rows = self.host.console.size.height
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 if term_rows < 20:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 self.host.disp(
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 "Your terminal must have a height of a least 20 rows.", error=True
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 )
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 self.host.a_quit(C.EXIT_ERROR)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 self.image_rows = term_rows - 6
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 self.image_cols = self.host.console.size.width
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 await self.init_call(call_data)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 assert self.webrtc is not None
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
109
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 idx = 0
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 self.buffer = ""
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
112
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 # we detect render
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 if self.render_class is None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 self.render_class = t_image.auto_image_class()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
116
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4240
diff changeset
117 loop_sleep = 1 / self.fps
4210
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
118
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 with self.input.raw_mode():
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 # for whatever reason, using self.input.attach is breaking KittyImage and uses
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 # a BlockImage style rendering instead. So we don't use it and we call
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 # ``self.keys_ready()`` ourself in the loop, below.
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 # cursor is not restored despite the ``screen`` context if peer is hanging up,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 # so we reactivate cursor here
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 self.host.add_on_quit_callback(self.host.console.show_cursor, True)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 with self.host.console.screen():
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 while True:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 idx += 1
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 if self.buffer is not None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 sys.stdout.write(self.buffer)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 sys.stdout.write("\n")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 self.parent.console.print(
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 # the padding avoid artifact when toggling buttons
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 Padding(self.generate_control_bar(), (0, 2, 0, 0))
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 )
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 sys.stdout.flush()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 rendered = True
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 else:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 rendered = False
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 await asyncio.sleep(loop_sleep)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 self.keys_ready()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 if self.done.is_set():
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 break
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 if rendered:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 # we put cursor back at the top of image to print the next frame
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 # FIXME: we use +4 for the controls because we know the height of the
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 # renderable, but it would be better to measure it dynamically.
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 sys.stdout.write(f"\033[{self.image_rows+4}A")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
149
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 await self.webrtc.end_call()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 await self.host.a_quit()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
152
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 @classmethod
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 async def run(cls, parent, call_data: CallData) -> None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 ui = cls(parent)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 await ui.start(call_data)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
157
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 def on_new_sample(self, video_sink, video_stream: str) -> bool:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 if self._processing:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 # image encoding for terminal is slow, if one is already processing, we don't
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 # bother going further
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 return False
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 sample = video_sink.emit("pull-sample")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 if sample is None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 return False
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
166
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 video_pad = video_sink.get_static_pad("sink")
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 assert video_pad is not None
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 s = video_pad.get_current_caps().get_structure(0)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 stream_size = (s.get_value("width"), s.get_value("height"))
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 buf = sample.get_buffer()
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 result, mapinfo = buf.map(Gst.MapFlags.READ)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 if result and self.render_class is not None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 self._processing = True
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 image_data = mapinfo.data
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 image = Image.frombuffer("RGB", stream_size, image_data, "raw", "RGB", 0, 1)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 img_renderer = self.render_class(image, height=self.image_rows)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 img_fmt = f"<{self.image_cols}.^1"
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 if self.render_class == t_image.KittyImage:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 # we don't do compression to speed up things
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 img_fmt += "+Wc0"
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 self.host.loop.loop.call_soon_threadsafe(
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 self.update_sample,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 sample,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 stream_size,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 video_stream,
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 format(img_renderer, img_fmt),
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 )
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 self._processing = False
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
190
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 buf.unmap(mapinfo)
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 return False
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
194
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 def update_sample(self, sample, stream_size, video_stream: str, buffer) -> None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 if sample is None:
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 return
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
198
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 if video_stream == "remote":
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 return
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201
9218d4331bb2 cli (call): `tui` output implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 self.buffer = buffer