py-tgcalls 2.0.1__py3-none-any.whl → 2.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {py_tgcalls-2.0.1.dist-info → py_tgcalls-2.0.3.dist-info}/METADATA +6 -6
- {py_tgcalls-2.0.1.dist-info → py_tgcalls-2.0.3.dist-info}/RECORD +22 -21
- {py_tgcalls-2.0.1.dist-info → py_tgcalls-2.0.3.dist-info}/WHEEL +1 -1
- pytgcalls/__version__.py +1 -1
- pytgcalls/ffmpeg.py +6 -1
- pytgcalls/handlers/handlers_holder.py +6 -0
- pytgcalls/media_devices/media_devices.py +4 -2
- pytgcalls/methods/calls/leave_call.py +10 -6
- pytgcalls/methods/stream/play.py +1 -1
- pytgcalls/methods/utilities/start.py +12 -2
- pytgcalls/mtproto/hydrogram_client.py +17 -12
- pytgcalls/mtproto/pyrogram_client.py +17 -12
- pytgcalls/mtproto/telethon_client.py +16 -11
- pytgcalls/types/calls/call.py +1 -9
- pytgcalls/types/chats/chat_update.py +1 -5
- pytgcalls/types/chats/group_call_participant.py +1 -1
- pytgcalls/types/flag.py +6 -0
- pytgcalls/types/raw/video_parameters.py +2 -0
- pytgcalls/types/stream/media_stream.py +5 -6
- pytgcalls/ytdlp.py +11 -2
- {py_tgcalls-2.0.1.dist-info → py_tgcalls-2.0.3.dist-info}/LICENSE +0 -0
- {py_tgcalls-2.0.1.dist-info → py_tgcalls-2.0.3.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py-tgcalls
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: Async client API for the Telegram Calls.
|
|
5
5
|
Author-email: Laky-64 <iraci.matteo@gmail.com>
|
|
6
6
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -186,17 +186,17 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
186
186
|
Requires-Python: >=3.8
|
|
187
187
|
Description-Content-Type: text/markdown
|
|
188
188
|
License-File: LICENSE
|
|
189
|
-
Requires-Dist: aiohttp
|
|
190
|
-
Requires-Dist: ntgcalls
|
|
189
|
+
Requires-Dist: aiohttp>=3.9.3
|
|
190
|
+
Requires-Dist: ntgcalls>=1.2.2
|
|
191
191
|
Requires-Dist: psutil
|
|
192
192
|
Requires-Dist: screeninfo
|
|
193
193
|
Requires-Dist: deprecation
|
|
194
194
|
Provides-Extra: hydrogram
|
|
195
|
-
Requires-Dist: hydrogram
|
|
195
|
+
Requires-Dist: hydrogram>=0.1.4; extra == "hydrogram"
|
|
196
196
|
Provides-Extra: pyrogram
|
|
197
|
-
Requires-Dist: pyrogram
|
|
197
|
+
Requires-Dist: pyrogram>=1.2.20; extra == "pyrogram"
|
|
198
198
|
Provides-Extra: telethon
|
|
199
|
-
Requires-Dist: telethon
|
|
199
|
+
Requires-Dist: telethon>=1.24.0; extra == "telethon"
|
|
200
200
|
|
|
201
201
|
<img src="https://raw.githubusercontent.com/pytgcalls/pytgcalls/master/.github/images/banner.png" alt="pytgcalls logo" />
|
|
202
202
|
<p align="center">
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
pytgcalls/__init__.py,sha256=TfZGf1enqqs50mBB406vygB6zYgn3vAjBYFUDO4Pviw,248
|
|
2
|
-
pytgcalls/__version__.py,sha256=
|
|
2
|
+
pytgcalls/__version__.py,sha256=fcRMgwI40iVFwre_3iKQA-N6sHUo3pAErXcKJS63DRg,22
|
|
3
3
|
pytgcalls/environment.py,sha256=ctCHACvG6l8SdpPewSBhOvc70kbwpv18maC0TwLvZ08,1924
|
|
4
4
|
pytgcalls/exceptions.py,sha256=0MmAktc53ajYAc7ThjD2tJ9PDyibUi0iHZMfUy2IoKs,4109
|
|
5
|
-
pytgcalls/ffmpeg.py,sha256=
|
|
5
|
+
pytgcalls/ffmpeg.py,sha256=uAqFDPwWoABW_WfubxeulpIh5vWpylxFARgYokn3ff8,8640
|
|
6
6
|
pytgcalls/filters.py,sha256=HFMBBbo_NCw6wqTtseHoDRsspJHQ49BUHBA1cxm7u4g,4852
|
|
7
7
|
pytgcalls/mtproto_required.py,sha256=6B-31p5qH_6oekUgypV4nK3hqPS6Nr-pA8S81wjnbaY,630
|
|
8
8
|
pytgcalls/mutex.py,sha256=Frjji5Ctzlk4AXEBuBLnDK-7HbtreoV6zuyKpFpMNI4,236
|
|
@@ -12,26 +12,26 @@ pytgcalls/scaffold.py,sha256=LihXRBl1kSqJSQvEoH5rAXJXrbnnIqSMBYrhXpW5hHs,958
|
|
|
12
12
|
pytgcalls/statictypes.py,sha256=CdlqgQNhTZ_uTE8-B8m01fJ7TlD2B42EI2QBPxDdAtA,3842
|
|
13
13
|
pytgcalls/sync.py,sha256=IsOH3TD7cxUg_-zdGt12HoS8sBlXvcGayPZAoxxKM48,3396
|
|
14
14
|
pytgcalls/version_manager.py,sha256=egeGgvb66zWlLTMuw2U-b0x8MfnRzMm1xAEVN87HF5c,296
|
|
15
|
-
pytgcalls/ytdlp.py,sha256=
|
|
15
|
+
pytgcalls/ytdlp.py,sha256=jRA-mKQEXleWvaoGv9wtMa77aRjxsyQxn6_0tXI3-sA,2435
|
|
16
16
|
pytgcalls/custom_api/__init__.py,sha256=ZT8d0lc2YrDuw_YSFAXXHHMewoXGFZ-ANOBIAr0vGFQ,60
|
|
17
17
|
pytgcalls/custom_api/custom_api.py,sha256=Ko3aS6psrwPmOhRPxvG0fepXt4STrA0StvINSxz4Cj8,1890
|
|
18
18
|
pytgcalls/handlers/__init__.py,sha256=pubbxI4pLqQpAKf8-toD6ija4cpSvbCJOQFjTiDjX1E,75
|
|
19
|
-
pytgcalls/handlers/handlers_holder.py,sha256=
|
|
19
|
+
pytgcalls/handlers/handlers_holder.py,sha256=ve83ydtKM5BjhsQmQ3mridD-3RnSVEi05-oDeiWv28w,1176
|
|
20
20
|
pytgcalls/media_devices/__init__.py,sha256=H6uUA6akUqp8WCiT2gLrqUtFdqpd9rcfqDviP5Vhrls,183
|
|
21
21
|
pytgcalls/media_devices/device_info.py,sha256=KueJCRVXXDcxQJzoGfkzcD2kL58pkMUn7Fr3aUwnNtQ,489
|
|
22
|
-
pytgcalls/media_devices/media_devices.py,sha256=
|
|
22
|
+
pytgcalls/media_devices/media_devices.py,sha256=KG4fKfubpeMQZVm9IuQmzDaLhsvKzKRdE3zIYRAhEHM,3227
|
|
23
23
|
pytgcalls/media_devices/screen_info.py,sha256=ARD5nQoYDUt1rU-kOK8G5O5byGXGeFbZWWdDswdCDHc,1107
|
|
24
24
|
pytgcalls/methods/__init__.py,sha256=hk1blAT5u_Isemdrg0nqInLsdRzTTZnak5NdAfkBPAk,217
|
|
25
25
|
pytgcalls/methods/calls/__init__.py,sha256=xg4DZZClEnxwaj-DAq3e8gSR-g-MiYBdUEBth64lSXA,214
|
|
26
26
|
pytgcalls/methods/calls/change_volume_call.py,sha256=viA3yHVxPJ421yE1dfFTh-kNEFTxMlaVFxVjC-PeX-0,719
|
|
27
27
|
pytgcalls/methods/calls/get_participants.py,sha256=gKUAzvha1RpvbtSI_n-GlBQkOONxzibCaCr4aA17Mag,567
|
|
28
|
-
pytgcalls/methods/calls/leave_call.py,sha256=
|
|
28
|
+
pytgcalls/methods/calls/leave_call.py,sha256=e3lYJKFD29Qg1qgolmLKUk9_X1uApOT1pGYF8ZgwMqQ,1369
|
|
29
29
|
pytgcalls/methods/decorators/__init__.py,sha256=TCGaEVZnHjtOwv-3PNfaCVm0kyFhJApUPUNntt6MwyM,78
|
|
30
30
|
pytgcalls/methods/decorators/on_update.py,sha256=ZTL4YcQk0N4Ru56a5WItUvkSN5SAqr6_RDZvXmZMIHs,316
|
|
31
31
|
pytgcalls/methods/stream/__init__.py,sha256=_4j-CEby4_2Kadva86tFMC4GSSzhBBjKLXfrgTk4gzo,343
|
|
32
32
|
pytgcalls/methods/stream/mute_stream.py,sha256=auo2aAazfEC90Ab6MzaiPdddiJ1w4fN_9HaORkAeOBY,570
|
|
33
33
|
pytgcalls/methods/stream/pause_stream.py,sha256=z_AIWABrQMHmTwvlah_PrH9EjXbro8gKxZni4Km5ICg,573
|
|
34
|
-
pytgcalls/methods/stream/play.py,sha256=
|
|
34
|
+
pytgcalls/methods/stream/play.py,sha256=38eWJSXFYgq7VRm4AH6e1NJfe6nYTyJ71PbK3mFijHs,7280
|
|
35
35
|
pytgcalls/methods/stream/played_time.py,sha256=IkUdyHrqpzpRl9uf0uZhg1COo4zsHnQOPu3nipjVatI,570
|
|
36
36
|
pytgcalls/methods/stream/resume_stream.py,sha256=z_DgP4cDExjEqEeX_ZL--50MXQ9lrATK876SIwE71PQ,576
|
|
37
37
|
pytgcalls/methods/stream/unmute_stream.py,sha256=KUMhfMbhsPmZsmpF4cGWC1FVW7YwXha2MmQnqrBhM8s,576
|
|
@@ -44,49 +44,50 @@ pytgcalls/methods/utilities/idle.py,sha256=MDdzHTv1ws2yBhsvhBUnssGdghkZ2KwR0HUCP
|
|
|
44
44
|
pytgcalls/methods/utilities/ping.py,sha256=hhIMSHk2BzMB-IKpwLdZFVrsEvGm2ftJwKLs1k4anh8,244
|
|
45
45
|
pytgcalls/methods/utilities/resolve_chat_id.py,sha256=92x2LHbUlnJMm-kS3fXOYmzYpY2TZbqtQD2rw3eBXDY,382
|
|
46
46
|
pytgcalls/methods/utilities/run.py,sha256=cnYQd2xB5Cr_WS0Q2cXJZPGiN6JOCULzj1r4xXVyrlg,152
|
|
47
|
-
pytgcalls/methods/utilities/start.py,sha256=
|
|
47
|
+
pytgcalls/methods/utilities/start.py,sha256=7mHp6RkfhuYC6i0JYmQvxK4KYRmkcvOs9kSrClPhNnk,9342
|
|
48
48
|
pytgcalls/methods/utilities/stream_params.py,sha256=hYcNxx__McmPeHgOUDEuNcN7ThgDjukejQYHrfmWm-A,1519
|
|
49
49
|
pytgcalls/mtproto/__init__.py,sha256=X4zvzFG7km7qHyE0fdvA550WcOVO_xl_p__gvIfDGmw,130
|
|
50
50
|
pytgcalls/mtproto/bridged_client.py,sha256=kK22n-CKjtfmtNE6bXCpuL6kWAUK2_Ul7cGgx_HNuHQ,4975
|
|
51
51
|
pytgcalls/mtproto/client_cache.py,sha256=1yA5CFAmWZUsWdpqk5vlaN3j1RV1rIN-X7EcqmsnlfY,5087
|
|
52
|
-
pytgcalls/mtproto/hydrogram_client.py,sha256=
|
|
52
|
+
pytgcalls/mtproto/hydrogram_client.py,sha256=x0s0ZmD_cVT_TtEUIT5qO0OueZg719TkfyraaUWJze0,21290
|
|
53
53
|
pytgcalls/mtproto/mtproto_client.py,sha256=LO71RqgxZ3bYxSFb6l9cc4ks6_peyqHN4i_z478c7yw,6883
|
|
54
|
-
pytgcalls/mtproto/pyrogram_client.py,sha256=
|
|
55
|
-
pytgcalls/mtproto/telethon_client.py,sha256=
|
|
54
|
+
pytgcalls/mtproto/pyrogram_client.py,sha256=oXKEoChpEpt3xS1NuM3rfXbmFcpWgBFyibgqm_Pp6D4,21479
|
|
55
|
+
pytgcalls/mtproto/telethon_client.py,sha256=j2Ybibhg67IL8M2LXBWXIJwpc6dTDMz5_9MRYsOVcuw,20373
|
|
56
56
|
pytgcalls/types/__init__.py,sha256=yJVJZoH9M9u9VgpZGUX-MF4NzE-vKp4KrId21YQbcGE,910
|
|
57
57
|
pytgcalls/types/browsers.py,sha256=47Kr5q96n4Q4WvVhA6IUlS2egEcA9GRLlDeFcQYyc9M,9545
|
|
58
58
|
pytgcalls/types/cache.py,sha256=FfsOcmYnsBGPlJoTPIXXYcUSpGE3rhx6cjIH77hyUL0,1059
|
|
59
59
|
pytgcalls/types/dict.py,sha256=lAo9hu4VlVJa9S7P8Y81BYmKtvz0rH7hwpGcH3ynHUw,78
|
|
60
|
+
pytgcalls/types/flag.py,sha256=dQPcQmTgTQzcOLTvGe8t_e9mY4qsVnCZFrrTk17b2Xw,132
|
|
60
61
|
pytgcalls/types/list.py,sha256=UjP_XxxMpPkLlu6yEy29JYqOM5VITFwwJcDm0wZni1c,78
|
|
61
62
|
pytgcalls/types/participant_list.py,sha256=LmGjU63MK1v3SS2_4xNbk04OOjmukNdAXYLRn2L-730,916
|
|
62
63
|
pytgcalls/types/py_object.py,sha256=VlazuMP0cFpExKimW8BtWR66LDewnNdQSLC7r_t7JIM,842
|
|
63
64
|
pytgcalls/types/update.py,sha256=wPCzWLhrsScZ3ksRTyt8IuDaaG5YI-ItG_Yw-OqzK2Y,157
|
|
64
65
|
pytgcalls/types/user_agent.py,sha256=sSfeGqUe0v0wqBgdVszNFK0iOC_0Tdyto9CglBXlY4U,1086
|
|
65
66
|
pytgcalls/types/calls/__init__.py,sha256=6O2wp7I3d2YGLNeMgXTRyG37Y6BESafneLdr9n37_4s,346
|
|
66
|
-
pytgcalls/types/calls/call.py,sha256=
|
|
67
|
+
pytgcalls/types/calls/call.py,sha256=wxa3L3nZnbTKtZbezCaA3iUt4rZ5IriQyMMrgRlp7GA,485
|
|
67
68
|
pytgcalls/types/calls/call_config.py,sha256=b6P43YTGF2t7E2CyD1mSYPJDUBvYYeHoxB3hSbTVyOY,120
|
|
68
69
|
pytgcalls/types/calls/call_data.py,sha256=-qPj2QhWv32Xs7LyFQY4hiWDqJ21B8VBvdzREK8bDvY,544
|
|
69
70
|
pytgcalls/types/calls/call_protocol.py,sha256=OVIQs1VgdY-DWbZbNr41hjLA4pGQvHx8Rgom1_NhJxQ,408
|
|
70
71
|
pytgcalls/types/calls/group_call_config.py,sha256=auKH-hZJWj8PhTkyeQ_VK2z9NpNvNC7Scl_IhEUMnQM,353
|
|
71
72
|
pytgcalls/types/calls/raw_call_update.py,sha256=hpNw6HrTW8Z36Lh2HinS-wzprryRtsIxyIFbIfjGgeI,795
|
|
72
73
|
pytgcalls/types/chats/__init__.py,sha256=v8pUp_vbr2kQpyHtAQc80N-YqzmXHe9SbllUsa6njkU,261
|
|
73
|
-
pytgcalls/types/chats/chat_update.py,sha256=
|
|
74
|
-
pytgcalls/types/chats/group_call_participant.py,sha256=
|
|
74
|
+
pytgcalls/types/chats/chat_update.py,sha256=wh8v2I-pZxJWGNBjIwWRbhY-ZCI4v8qGabDTpuJaHu0,619
|
|
75
|
+
pytgcalls/types/chats/group_call_participant.py,sha256=HQ2EVZKE1_uEjtUKdUA8yJemdc189IN4mioSP-KDEiY,1020
|
|
75
76
|
pytgcalls/types/chats/updated_group_call_participant.py,sha256=-KID-z-4e43fhYWQp0pNMKPfmZizbJHXyzn6yLtIGNg,291
|
|
76
77
|
pytgcalls/types/raw/__init__.py,sha256=ROHsKFeUMUtlFbx2rhfrdB-TuVm0zBuvNo29Ccn5614,308
|
|
77
78
|
pytgcalls/types/raw/audio_parameters.py,sha256=1DsBPwdn_Ukd2Tbkb3whP_ILo9xJY_3XNNmbO4_NO9Q,449
|
|
78
79
|
pytgcalls/types/raw/audio_stream.py,sha256=wEMa93hHt0VBUSuS6gPJlFIGZp5GdNU94O2C2u4AXnY,476
|
|
79
80
|
pytgcalls/types/raw/stream.py,sha256=jCvFUSAdHupqMqfG1E36CgKijKoy0o2LUbgcVjj5Mz0,491
|
|
80
|
-
pytgcalls/types/raw/video_parameters.py,sha256=
|
|
81
|
+
pytgcalls/types/raw/video_parameters.py,sha256=nUl9gkfYTVU0iLNGTtlZ5cZg8K6F7odIi9n8POJXCK4,639
|
|
81
82
|
pytgcalls/types/raw/video_stream.py,sha256=2Chrk7NFWF1H9V7hH71RZ5rF3iBhT53syFkHKw4-5gc,433
|
|
82
83
|
pytgcalls/types/stream/__init__.py,sha256=xfF-9ZulOLk3E6G1nw1Ky0ZRWXlFuER0Uj8HQn3650w,338
|
|
83
84
|
pytgcalls/types/stream/audio_quality.py,sha256=4X94ErmTeLP4TVcE3eLtPPdtluSPxgxbgTosuNJOVhc,141
|
|
84
|
-
pytgcalls/types/stream/media_stream.py,sha256=
|
|
85
|
+
pytgcalls/types/stream/media_stream.py,sha256=YoG-vISvDga1n4IHs4hdF03ldtqyojFMvwB3To_39kE,8931
|
|
85
86
|
pytgcalls/types/stream/stream_audio_ended.py,sha256=2_EFa98F0vWu0d0jBmLtzp4NH_xBkDO_6yP9UtyKuCs,164
|
|
86
87
|
pytgcalls/types/stream/stream_video_ended.py,sha256=9YFTTZPMDpB95eb815rGtgDrzBGfTeazJ5mZwP6Hvks,164
|
|
87
88
|
pytgcalls/types/stream/video_quality.py,sha256=HBfWq005kh-D19MaVE9VzVdnODzrXf4IJUimCfslfiU,231
|
|
88
|
-
py_tgcalls-2.0.
|
|
89
|
-
py_tgcalls-2.0.
|
|
90
|
-
py_tgcalls-2.0.
|
|
91
|
-
py_tgcalls-2.0.
|
|
92
|
-
py_tgcalls-2.0.
|
|
89
|
+
py_tgcalls-2.0.3.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
90
|
+
py_tgcalls-2.0.3.dist-info/METADATA,sha256=0uu5GSvIXH0bc_1fZt1N8WWlN8Hx_Kmn-v3z2V0hd3w,14349
|
|
91
|
+
py_tgcalls-2.0.3.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
|
92
|
+
py_tgcalls-2.0.3.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
|
|
93
|
+
py_tgcalls-2.0.3.dist-info/RECORD,,
|
pytgcalls/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.0.
|
|
1
|
+
__version__ = '2.0.3'
|
pytgcalls/ffmpeg.py
CHANGED
|
@@ -95,7 +95,10 @@ async def check_stream(
|
|
|
95
95
|
new_w = min(original_width, stream_parameters.width)
|
|
96
96
|
new_h = int(new_w / ratio)
|
|
97
97
|
|
|
98
|
-
if
|
|
98
|
+
if (
|
|
99
|
+
new_h > stream_parameters.height and
|
|
100
|
+
stream_parameters.adjust_by_height
|
|
101
|
+
):
|
|
99
102
|
new_h = stream_parameters.height
|
|
100
103
|
new_w = int(new_h * ratio)
|
|
101
104
|
|
|
@@ -282,6 +285,8 @@ def _build_ffmpeg_options(
|
|
|
282
285
|
options.extend([
|
|
283
286
|
'rawvideo',
|
|
284
287
|
'-r', str(stream_parameters.frame_rate),
|
|
288
|
+
'-pix_fmt',
|
|
289
|
+
'yuv420p',
|
|
285
290
|
'-vf',
|
|
286
291
|
f'scale={stream_parameters.width}:{stream_parameters.height}',
|
|
287
292
|
])
|
|
@@ -72,9 +72,11 @@ class MediaDevices:
|
|
|
72
72
|
except subprocess.TimeoutExpired:
|
|
73
73
|
return list_devices
|
|
74
74
|
if platform == 'win32':
|
|
75
|
-
list_raw = result.split('DirectShow audio devices')
|
|
75
|
+
list_raw = result.split('DirectShow audio devices')
|
|
76
|
+
if len(list_raw) < 2:
|
|
77
|
+
return list_devices
|
|
76
78
|
output = re.findall(
|
|
77
|
-
'\\[.*?].*?"(.*?)".*?\n\\[.*?].*?"(.*?)"', list_raw,
|
|
79
|
+
'\\[.*?].*?"(.*?)".*?\n\\[.*?].*?"(.*?)"', list_raw[1],
|
|
78
80
|
)
|
|
79
81
|
for device in output:
|
|
80
82
|
list_devices.append(
|
|
@@ -19,6 +19,15 @@ class LeaveCall(Scaffold):
|
|
|
19
19
|
chat_id: Union[int, str],
|
|
20
20
|
):
|
|
21
21
|
chat_id = await self.resolve_chat_id(chat_id)
|
|
22
|
+
is_p2p_waiting = (
|
|
23
|
+
chat_id in self._p2p_configs and
|
|
24
|
+
not self._p2p_configs[chat_id].wait_data.done()
|
|
25
|
+
)
|
|
26
|
+
if not is_p2p_waiting:
|
|
27
|
+
try:
|
|
28
|
+
await self._binding.stop(chat_id)
|
|
29
|
+
except ConnectionNotFound:
|
|
30
|
+
raise NotInCallError()
|
|
22
31
|
if chat_id < 0: # type: ignore
|
|
23
32
|
chat_call = await self._app.get_full_chat(
|
|
24
33
|
chat_id,
|
|
@@ -32,13 +41,8 @@ class LeaveCall(Scaffold):
|
|
|
32
41
|
)
|
|
33
42
|
else:
|
|
34
43
|
await self._app.discard_call(chat_id)
|
|
35
|
-
if
|
|
36
|
-
not self._p2p_configs[chat_id].outgoing:
|
|
44
|
+
if is_p2p_waiting:
|
|
37
45
|
self._p2p_configs.pop(chat_id)
|
|
38
46
|
return
|
|
39
|
-
try:
|
|
40
|
-
await self._binding.stop(chat_id)
|
|
41
|
-
except ConnectionNotFound:
|
|
42
|
-
raise NotInCallError()
|
|
43
47
|
if chat_id < 0: # type: ignore
|
|
44
48
|
self._need_unmute.discard(chat_id)
|
pytgcalls/methods/stream/play.py
CHANGED
|
@@ -90,7 +90,14 @@ class Start(Scaffold):
|
|
|
90
90
|
) == participant.user_id if chat_peer else False
|
|
91
91
|
if is_self:
|
|
92
92
|
if action == GroupCallParticipant.Action.LEFT:
|
|
93
|
-
await clear_call(chat_id)
|
|
93
|
+
if await clear_call(chat_id):
|
|
94
|
+
await self.propagate(
|
|
95
|
+
ChatUpdate(
|
|
96
|
+
chat_id,
|
|
97
|
+
ChatUpdate.Status.KICKED,
|
|
98
|
+
),
|
|
99
|
+
self,
|
|
100
|
+
)
|
|
94
101
|
if (
|
|
95
102
|
chat_id in self._need_unmute and
|
|
96
103
|
action == GroupCallParticipant.Action.UPDATED and
|
|
@@ -117,12 +124,15 @@ class Start(Scaffold):
|
|
|
117
124
|
self,
|
|
118
125
|
)
|
|
119
126
|
|
|
120
|
-
async def clear_call(chat_id):
|
|
127
|
+
async def clear_call(chat_id) -> bool:
|
|
128
|
+
res = False
|
|
121
129
|
try:
|
|
122
130
|
await self._binding.stop(chat_id)
|
|
131
|
+
res = True
|
|
123
132
|
except ConnectionNotFound:
|
|
124
133
|
pass
|
|
125
134
|
await clear_cache(chat_id)
|
|
135
|
+
return res
|
|
126
136
|
|
|
127
137
|
async def update_status(chat_id: int, state: MediaState):
|
|
128
138
|
try:
|
|
@@ -78,7 +78,7 @@ class HydrogramClient(BridgedClient):
|
|
|
78
78
|
self,
|
|
79
79
|
)
|
|
80
80
|
|
|
81
|
-
@self._app.on_raw_update()
|
|
81
|
+
@self._app.on_raw_update(group=-1)
|
|
82
82
|
async def on_update(_, update, __, chats):
|
|
83
83
|
if isinstance(
|
|
84
84
|
update,
|
|
@@ -353,19 +353,24 @@ class HydrogramClient(BridgedClient):
|
|
|
353
353
|
self,
|
|
354
354
|
input_call: InputGroupCall,
|
|
355
355
|
) -> List[GroupCallParticipant]:
|
|
356
|
+
participants = []
|
|
357
|
+
next_offset = ''
|
|
358
|
+
while True:
|
|
359
|
+
result = await self._app.invoke(
|
|
360
|
+
GetGroupParticipants(
|
|
361
|
+
call=input_call,
|
|
362
|
+
ids=[],
|
|
363
|
+
sources=[],
|
|
364
|
+
offset=next_offset,
|
|
365
|
+
limit=0,
|
|
366
|
+
),
|
|
367
|
+
)
|
|
368
|
+
participants.extend(result.participants)
|
|
369
|
+
if not (next_offset := result.next_offset):
|
|
370
|
+
break
|
|
356
371
|
return [
|
|
357
372
|
self.parse_participant(participant)
|
|
358
|
-
for participant in
|
|
359
|
-
await self._app.invoke(
|
|
360
|
-
GetGroupParticipants(
|
|
361
|
-
call=input_call,
|
|
362
|
-
ids=[],
|
|
363
|
-
sources=[],
|
|
364
|
-
offset='',
|
|
365
|
-
limit=500,
|
|
366
|
-
),
|
|
367
|
-
)
|
|
368
|
-
).participants
|
|
373
|
+
for participant in participants
|
|
369
374
|
]
|
|
370
375
|
|
|
371
376
|
async def join_group_call(
|
|
@@ -86,7 +86,7 @@ class PyrogramClient(BridgedClient):
|
|
|
86
86
|
self,
|
|
87
87
|
)
|
|
88
88
|
|
|
89
|
-
@self._app.on_raw_update()
|
|
89
|
+
@self._app.on_raw_update(group=-1)
|
|
90
90
|
async def on_update(_, update, __, chats):
|
|
91
91
|
if isinstance(
|
|
92
92
|
update,
|
|
@@ -361,19 +361,24 @@ class PyrogramClient(BridgedClient):
|
|
|
361
361
|
self,
|
|
362
362
|
input_call: InputGroupCall,
|
|
363
363
|
) -> List[GroupCallParticipant]:
|
|
364
|
+
participants = []
|
|
365
|
+
next_offset = ''
|
|
366
|
+
while True:
|
|
367
|
+
result = await self._app.send(
|
|
368
|
+
GetGroupParticipants(
|
|
369
|
+
call=input_call,
|
|
370
|
+
ids=[],
|
|
371
|
+
sources=[],
|
|
372
|
+
offset=next_offset,
|
|
373
|
+
limit=0,
|
|
374
|
+
),
|
|
375
|
+
)
|
|
376
|
+
participants.extend(result.participants)
|
|
377
|
+
if not (next_offset := result.next_offset):
|
|
378
|
+
break
|
|
364
379
|
return [
|
|
365
380
|
self.parse_participant(participant)
|
|
366
|
-
for participant in
|
|
367
|
-
await self._app.send(
|
|
368
|
-
GetGroupParticipants(
|
|
369
|
-
call=input_call,
|
|
370
|
-
ids=[],
|
|
371
|
-
sources=[],
|
|
372
|
-
offset='',
|
|
373
|
-
limit=500,
|
|
374
|
-
),
|
|
375
|
-
)
|
|
376
|
-
).participants
|
|
381
|
+
for participant in participants
|
|
377
382
|
]
|
|
378
383
|
|
|
379
384
|
async def join_group_call(
|
|
@@ -330,19 +330,24 @@ class TelethonClient(BridgedClient):
|
|
|
330
330
|
self,
|
|
331
331
|
input_call: InputGroupCall,
|
|
332
332
|
) -> List[GroupCallParticipant]:
|
|
333
|
+
participants = []
|
|
334
|
+
next_offset = ''
|
|
335
|
+
while True:
|
|
336
|
+
result = await self._app(
|
|
337
|
+
GetGroupParticipantsRequest(
|
|
338
|
+
call=input_call,
|
|
339
|
+
ids=[],
|
|
340
|
+
sources=[],
|
|
341
|
+
offset=next_offset,
|
|
342
|
+
limit=0,
|
|
343
|
+
),
|
|
344
|
+
)
|
|
345
|
+
participants.extend(result.participants)
|
|
346
|
+
if not (next_offset := result.next_offset):
|
|
347
|
+
break
|
|
333
348
|
return [
|
|
334
349
|
self.parse_participant(participant)
|
|
335
|
-
for participant in
|
|
336
|
-
await self._app(
|
|
337
|
-
GetGroupParticipantsRequest(
|
|
338
|
-
call=input_call,
|
|
339
|
-
ids=[],
|
|
340
|
-
sources=[],
|
|
341
|
-
offset='',
|
|
342
|
-
limit=500,
|
|
343
|
-
),
|
|
344
|
-
)
|
|
345
|
-
).participants
|
|
350
|
+
for participant in participants
|
|
346
351
|
]
|
|
347
352
|
|
|
348
353
|
async def join_group_call(
|
pytgcalls/types/calls/call.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from enum import auto
|
|
2
|
-
from enum import Flag
|
|
3
2
|
|
|
4
3
|
from ...types.py_object import PyObject
|
|
4
|
+
from ..flag import Flag
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Call(PyObject):
|
|
@@ -10,18 +10,10 @@ class Call(PyObject):
|
|
|
10
10
|
PAUSED = auto()
|
|
11
11
|
IDLE = auto()
|
|
12
12
|
|
|
13
|
-
def __repr__(self):
|
|
14
|
-
cls_name = self.__class__.__name__
|
|
15
|
-
return f'{cls_name}.{self.name}'
|
|
16
|
-
|
|
17
13
|
class Type(Flag):
|
|
18
14
|
GROUP = auto()
|
|
19
15
|
PRIVATE = auto()
|
|
20
16
|
|
|
21
|
-
def __repr__(self):
|
|
22
|
-
cls_name = self.__class__.__name__
|
|
23
|
-
return f'{cls_name}.{self.name}'
|
|
24
|
-
|
|
25
17
|
def __init__(
|
|
26
18
|
self,
|
|
27
19
|
chat_id: int,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from enum import auto
|
|
2
|
-
from enum import Flag
|
|
3
2
|
from typing import Any
|
|
4
3
|
|
|
4
|
+
from ..flag import Flag
|
|
5
5
|
from ..update import Update
|
|
6
6
|
|
|
7
7
|
|
|
@@ -15,10 +15,6 @@ class ChatUpdate(Update):
|
|
|
15
15
|
INCOMING_CALL = auto()
|
|
16
16
|
LEFT_CALL = KICKED | LEFT_GROUP | CLOSED_VOICE_CHAT | DISCARDED_CALL
|
|
17
17
|
|
|
18
|
-
def __repr__(self):
|
|
19
|
-
cls_name = self.__class__.__name__
|
|
20
|
-
return f'{cls_name}.{self.name}'
|
|
21
|
-
|
|
22
18
|
def __init__(
|
|
23
19
|
self,
|
|
24
20
|
chat_id: int,
|
pytgcalls/types/flag.py
ADDED
|
@@ -10,6 +10,7 @@ class VideoParameters(PyObject):
|
|
|
10
10
|
width: int = 640,
|
|
11
11
|
height: int = 360,
|
|
12
12
|
frame_rate: int = 20,
|
|
13
|
+
adjust_by_height: bool = True,
|
|
13
14
|
):
|
|
14
15
|
max_w, max_h, max_fps = max(
|
|
15
16
|
VideoQuality, key=lambda x: x.value[0],
|
|
@@ -17,3 +18,4 @@ class VideoParameters(PyObject):
|
|
|
17
18
|
self.width: int = min(width, max_w)
|
|
18
19
|
self.height: int = min(height, max_h)
|
|
19
20
|
self.frame_rate: int = min(frame_rate, max_fps)
|
|
21
|
+
self.adjust_by_height: bool = adjust_by_height
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from enum import auto
|
|
2
|
-
from enum import Flag
|
|
3
2
|
from pathlib import Path
|
|
4
3
|
from typing import Dict
|
|
5
4
|
from typing import Optional
|
|
@@ -17,6 +16,7 @@ from ...media_devices import DeviceInfo
|
|
|
17
16
|
from ...media_devices import ScreenInfo
|
|
18
17
|
from ...statictypes import statictypes
|
|
19
18
|
from ...ytdlp import YtDlp
|
|
19
|
+
from ..flag import Flag
|
|
20
20
|
from ..raw.audio_parameters import AudioParameters
|
|
21
21
|
from ..raw.audio_stream import AudioStream
|
|
22
22
|
from ..raw.stream import Stream
|
|
@@ -33,10 +33,6 @@ class MediaStream(Stream):
|
|
|
33
33
|
IGNORE = auto()
|
|
34
34
|
NO_LATENCY = auto()
|
|
35
35
|
|
|
36
|
-
def __repr__(self):
|
|
37
|
-
cls_name = self.__class__.__name__
|
|
38
|
-
return f'{cls_name}.{self.name}'
|
|
39
|
-
|
|
40
36
|
@statictypes
|
|
41
37
|
def __init__(
|
|
42
38
|
self,
|
|
@@ -66,7 +62,10 @@ class MediaStream(Stream):
|
|
|
66
62
|
if isinstance(video_parameters, VideoParameters):
|
|
67
63
|
self._video_parameters = video_parameters
|
|
68
64
|
elif isinstance(video_parameters, VideoQuality):
|
|
69
|
-
self._video_parameters = VideoParameters(
|
|
65
|
+
self._video_parameters = VideoParameters(
|
|
66
|
+
*video_parameters.value,
|
|
67
|
+
adjust_by_height=False,
|
|
68
|
+
)
|
|
70
69
|
|
|
71
70
|
self._media_path: Optional[str] = None
|
|
72
71
|
self._audio_path: Optional[str] = None
|
pytgcalls/ytdlp.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import logging
|
|
2
3
|
import re
|
|
3
4
|
import shlex
|
|
4
5
|
from typing import Optional
|
|
@@ -8,6 +9,8 @@ from .exceptions import YtDlpError
|
|
|
8
9
|
from .ffmpeg import cleanup_commands
|
|
9
10
|
from .types.raw import VideoParameters
|
|
10
11
|
|
|
12
|
+
py_logger = logging.getLogger('pytgcalls')
|
|
13
|
+
|
|
11
14
|
|
|
12
15
|
class YtDlp:
|
|
13
16
|
YOUTUBE_REGX = re.compile(
|
|
@@ -34,8 +37,10 @@ class YtDlp:
|
|
|
34
37
|
'yt-dlp',
|
|
35
38
|
'-g',
|
|
36
39
|
'-f',
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
'bestvideo[vcodec~=\'(vp09|avc1)\']+m4a/best',
|
|
41
|
+
'-S',
|
|
42
|
+
'res:'
|
|
43
|
+
f'{min(video_parameters.width, video_parameters.height)}',
|
|
39
44
|
'--no-warnings',
|
|
40
45
|
]
|
|
41
46
|
|
|
@@ -52,6 +57,10 @@ class YtDlp:
|
|
|
52
57
|
|
|
53
58
|
commands.append(link)
|
|
54
59
|
|
|
60
|
+
py_logger.log(
|
|
61
|
+
logging.DEBUG,
|
|
62
|
+
f'Running with "{" ".join(commands)}" command',
|
|
63
|
+
)
|
|
55
64
|
try:
|
|
56
65
|
proc = await asyncio.create_subprocess_exec(
|
|
57
66
|
*commands,
|
|
File without changes
|
|
File without changes
|