py-tgcalls 2.0.6__py3-none-any.whl → 2.1.0.dev2__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.
Files changed (44) hide show
  1. {py_tgcalls-2.0.6.dist-info → py_tgcalls-2.1.0.dev2.dist-info}/METADATA +6 -8
  2. {py_tgcalls-2.0.6.dist-info → py_tgcalls-2.1.0.dev2.dist-info}/RECORD +41 -35
  3. {py_tgcalls-2.0.6.dist-info → py_tgcalls-2.1.0.dev2.dist-info}/WHEEL +1 -1
  4. pytgcalls/__init__.py +2 -0
  5. pytgcalls/__version__.py +1 -1
  6. pytgcalls/filters.py +46 -6
  7. pytgcalls/media_devices/__init__.py +6 -2
  8. pytgcalls/media_devices/device_info.py +8 -15
  9. pytgcalls/media_devices/input_device.py +11 -0
  10. pytgcalls/media_devices/media_devices.py +41 -92
  11. pytgcalls/media_devices/screen_device.py +10 -0
  12. pytgcalls/media_devices/speaker_device.py +10 -0
  13. pytgcalls/methods/stream/__init__.py +4 -2
  14. pytgcalls/methods/stream/play.py +73 -11
  15. pytgcalls/methods/stream/record.py +41 -0
  16. pytgcalls/methods/stream/{played_time.py → time.py} +5 -3
  17. pytgcalls/methods/utilities/call_holder.py +5 -2
  18. pytgcalls/methods/utilities/start.py +118 -13
  19. pytgcalls/methods/utilities/stream_params.py +63 -22
  20. pytgcalls/mtproto/bridged_client.py +34 -2
  21. pytgcalls/mtproto/client_cache.py +46 -16
  22. pytgcalls/mtproto/hydrogram_client.py +53 -11
  23. pytgcalls/mtproto/mtproto_client.py +30 -4
  24. pytgcalls/mtproto/pyrogram_client.py +53 -11
  25. pytgcalls/mtproto/telethon_client.py +61 -19
  26. pytgcalls/scaffold.py +6 -0
  27. pytgcalls/types/__init__.py +10 -4
  28. pytgcalls/types/calls/call.py +5 -3
  29. pytgcalls/types/chats/group_call_participant.py +21 -0
  30. pytgcalls/types/raw/audio_stream.py +3 -3
  31. pytgcalls/types/raw/stream.py +8 -4
  32. pytgcalls/types/raw/video_stream.py +5 -4
  33. pytgcalls/types/stream/__init__.py +10 -4
  34. pytgcalls/types/stream/device.py +24 -0
  35. pytgcalls/types/stream/direction.py +18 -0
  36. pytgcalls/types/stream/media_stream.py +126 -102
  37. pytgcalls/types/stream/record_stream.py +93 -0
  38. pytgcalls/types/stream/stream_ended.py +32 -0
  39. pytgcalls/types/stream/stream_frame.py +35 -0
  40. pytgcalls/media_devices/screen_info.py +0 -45
  41. pytgcalls/types/stream/stream_audio_ended.py +0 -9
  42. pytgcalls/types/stream/stream_video_ended.py +0 -9
  43. {py_tgcalls-2.0.6.dist-info → py_tgcalls-2.1.0.dev2.dist-info}/LICENSE +0 -0
  44. {py_tgcalls-2.0.6.dist-info → py_tgcalls-2.1.0.dev2.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.6
3
+ Version: 2.1.0.dev2
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
@@ -178,18 +178,16 @@ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGP
178
178
  Classifier: Operating System :: OS Independent
179
179
  Classifier: Programming Language :: Python :: 3
180
180
  Classifier: Programming Language :: Python :: 3 :: Only
181
- Classifier: Programming Language :: Python :: 3.8
182
181
  Classifier: Programming Language :: Python :: 3.9
183
182
  Classifier: Programming Language :: Python :: 3.10
184
183
  Classifier: Programming Language :: Python :: 3.11
185
184
  Classifier: Programming Language :: Python :: 3.12
186
- Requires-Python: >=3.8
185
+ Classifier: Programming Language :: Python :: 3.13
186
+ Requires-Python: >=3.9
187
187
  Description-Content-Type: text/markdown
188
188
  License-File: LICENSE
189
189
  Requires-Dist: aiohttp>=3.9.3
190
- Requires-Dist: ntgcalls<1.3.0,>=1.2.0
191
- Requires-Dist: psutil
192
- Requires-Dist: screeninfo
190
+ Requires-Dist: ntgcalls<1.4.0,>=1.3.0b3
193
191
  Requires-Dist: deprecation
194
192
  Provides-Extra: hydrogram
195
193
  Requires-Dist: hydrogram>=0.1.4; extra == "hydrogram"
@@ -223,7 +221,7 @@ Requires-Dist: telethon>=1.24.0; extra == "telethon"
223
221
  </a>
224
222
  </p>
225
223
 
226
- # PyTgCalls [![PyPI](https://img.shields.io/pypi/v/py-tgcalls.svg?logo=python&logoColor=%23959DA5&label=pypi&labelColor=%23282f37)](https://pypi.org/project/py-tgcalls/) [![Downloads](https://pepy.tech/badge/py-tgcalls)](https://pepy.tech/project/py-tgcalls)
224
+ # PyTgCalls [![PyPI](https://img.shields.io/pypi/v/py-tgcalls.svg?logo=python&logoColor=%23959DA5&label=pypi&labelColor=%23282f37)](https://pypi.org/project/py-tgcalls/) [![Downloads](https://img.shields.io/pepy/dt/py-tgcalls?logoColor=%23959DA5&labelColor=%23282f37&color=%2328A745)](https://pepy.tech/project/py-tgcalls)
227
225
  This project allows making Telegram call using MtProto and WebRTC, this is possible thanks to the power of [NTgCalls] library and [@evgeny-nadymov]
228
226
 
229
227
  #### Example Usage
@@ -252,7 +250,7 @@ idle()
252
250
  - Mute/unmute, pause/resume, stop/play, volume control and more...
253
251
 
254
252
  ## Requirements
255
- - Python 3.8 or higher.
253
+ - Python 3.9 or higher.
256
254
  - An MTProto Client
257
255
  - A [Telegram API key](https://docs.pyrogram.org/intro/setup#api-keys).
258
256
 
@@ -1,14 +1,14 @@
1
- pytgcalls/__init__.py,sha256=TfZGf1enqqs50mBB406vygB6zYgn3vAjBYFUDO4Pviw,248
2
- pytgcalls/__version__.py,sha256=_rdDXO0eF8Rb-UlqwwfOrLeR0p4mNliGj-gv5nXgbms,22
1
+ pytgcalls/__init__.py,sha256=qbfwN7rYwIdCegMOzdcbvwazeNjDzgmowgcqLFNqKIM,308
2
+ pytgcalls/__version__.py,sha256=wNJAWxZJ5nqnvr7CcRnjak-Pcnydu3AaK30sXJNnIZU,27
3
3
  pytgcalls/environment.py,sha256=ctCHACvG6l8SdpPewSBhOvc70kbwpv18maC0TwLvZ08,1924
4
4
  pytgcalls/exceptions.py,sha256=0MmAktc53ajYAc7ThjD2tJ9PDyibUi0iHZMfUy2IoKs,4109
5
5
  pytgcalls/ffmpeg.py,sha256=uAqFDPwWoABW_WfubxeulpIh5vWpylxFARgYokn3ff8,8640
6
- pytgcalls/filters.py,sha256=dyKGOz2zFIDuh3bs_PLqvP72xAXtMp3lkgHZWFR482s,4859
6
+ pytgcalls/filters.py,sha256=dHRXgxhQoLaLsSAsYYaq4jCwVran9sBWBG1txKWIOjY,6039
7
7
  pytgcalls/mtproto_required.py,sha256=6B-31p5qH_6oekUgypV4nK3hqPS6Nr-pA8S81wjnbaY,630
8
8
  pytgcalls/mutex.py,sha256=Frjji5Ctzlk4AXEBuBLnDK-7HbtreoV6zuyKpFpMNI4,236
9
9
  pytgcalls/pytgcalls.py,sha256=oBcWgBwusnXmjHrLEE99VVXARReVyrXdn9SyeBWHbVo,1479
10
10
  pytgcalls/pytgcalls_session.py,sha256=_BGJWvf7t3mki2DhlEPjh9cypvYuSFkMSxzTsfepwUk,2719
11
- pytgcalls/scaffold.py,sha256=LihXRBl1kSqJSQvEoH5rAXJXrbnnIqSMBYrhXpW5hHs,958
11
+ pytgcalls/scaffold.py,sha256=cOG1_-MtGhBuyJmUXPmThC0VUF65TmdwnMCbgIozJoY,1159
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
@@ -17,10 +17,12 @@ pytgcalls/custom_api/__init__.py,sha256=ZT8d0lc2YrDuw_YSFAXXHHMewoXGFZ-ANOBIAr0v
17
17
  pytgcalls/custom_api/custom_api.py,sha256=Ko3aS6psrwPmOhRPxvG0fepXt4STrA0StvINSxz4Cj8,1890
18
18
  pytgcalls/handlers/__init__.py,sha256=pubbxI4pLqQpAKf8-toD6ija4cpSvbCJOQFjTiDjX1E,75
19
19
  pytgcalls/handlers/handlers_holder.py,sha256=ve83ydtKM5BjhsQmQ3mridD-3RnSVEi05-oDeiWv28w,1176
20
- pytgcalls/media_devices/__init__.py,sha256=H6uUA6akUqp8WCiT2gLrqUtFdqpd9rcfqDviP5Vhrls,183
21
- pytgcalls/media_devices/device_info.py,sha256=KueJCRVXXDcxQJzoGfkzcD2kL58pkMUn7Fr3aUwnNtQ,489
22
- pytgcalls/media_devices/media_devices.py,sha256=KG4fKfubpeMQZVm9IuQmzDaLhsvKzKRdE3zIYRAhEHM,3227
23
- pytgcalls/media_devices/screen_info.py,sha256=ARD5nQoYDUt1rU-kOK8G5O5byGXGeFbZWWdDswdCDHc,1107
20
+ pytgcalls/media_devices/__init__.py,sha256=QC7OccjY-YkcJ1xF9d1VRfM9hdgExWbInMYW92YBJ_s,309
21
+ pytgcalls/media_devices/device_info.py,sha256=AleyVRXvZ0ylr03JQq8gPm5L-f5ySDwokDtW_Czcg50,266
22
+ pytgcalls/media_devices/input_device.py,sha256=-Z5hjhdc1Y68mZQpVW-QgMePKGe_c5zJcYJHIzYElOY,225
23
+ pytgcalls/media_devices/media_devices.py,sha256=ZgRF8j4jCJNWrW1HCUUWZMcZ9V7LOcvm_jJmy8g7ieQ,1333
24
+ pytgcalls/media_devices/screen_device.py,sha256=B1MCpcqW-QXKcVafNdPQfd2Es6-ejkX2NdwbfuYmhv4,201
25
+ pytgcalls/media_devices/speaker_device.py,sha256=39aAE2oEvlhRiUwHlIJCrSUPWIy-8J9_oq1TmCq5IjA,200
24
26
  pytgcalls/methods/__init__.py,sha256=hk1blAT5u_Isemdrg0nqInLsdRzTTZnak5NdAfkBPAk,217
25
27
  pytgcalls/methods/calls/__init__.py,sha256=xg4DZZClEnxwaj-DAq3e8gSR-g-MiYBdUEBth64lSXA,214
26
28
  pytgcalls/methods/calls/change_volume_call.py,sha256=viA3yHVxPJ421yE1dfFTh-kNEFTxMlaVFxVjC-PeX-0,719
@@ -28,32 +30,33 @@ pytgcalls/methods/calls/get_participants.py,sha256=gKUAzvha1RpvbtSI_n-GlBQkOONxz
28
30
  pytgcalls/methods/calls/leave_call.py,sha256=e3lYJKFD29Qg1qgolmLKUk9_X1uApOT1pGYF8ZgwMqQ,1369
29
31
  pytgcalls/methods/decorators/__init__.py,sha256=TCGaEVZnHjtOwv-3PNfaCVm0kyFhJApUPUNntt6MwyM,78
30
32
  pytgcalls/methods/decorators/on_update.py,sha256=ZTL4YcQk0N4Ru56a5WItUvkSN5SAqr6_RDZvXmZMIHs,316
31
- pytgcalls/methods/stream/__init__.py,sha256=_4j-CEby4_2Kadva86tFMC4GSSzhBBjKLXfrgTk4gzo,343
33
+ pytgcalls/methods/stream/__init__.py,sha256=EeB0SHvnrOMQELZMAX0ex8_lbdRcW_S4E7epsb5epkw,363
32
34
  pytgcalls/methods/stream/mute_stream.py,sha256=auo2aAazfEC90Ab6MzaiPdddiJ1w4fN_9HaORkAeOBY,570
33
35
  pytgcalls/methods/stream/pause_stream.py,sha256=z_AIWABrQMHmTwvlah_PrH9EjXbro8gKxZni4Km5ICg,573
34
- pytgcalls/methods/stream/play.py,sha256=38eWJSXFYgq7VRm4AH6e1NJfe6nYTyJ71PbK3mFijHs,7280
35
- pytgcalls/methods/stream/played_time.py,sha256=IkUdyHrqpzpRl9uf0uZhg1COo4zsHnQOPu3nipjVatI,570
36
+ pytgcalls/methods/stream/play.py,sha256=w88pp2LeYd8qjejGJYwtzHRsAKAaEd-Pk48nFlzPX4E,10097
37
+ pytgcalls/methods/stream/record.py,sha256=toW1LtgUMiaw-KGe9DnWTRsGYLhoKlG0r8eJphMhGIA,1212
36
38
  pytgcalls/methods/stream/resume_stream.py,sha256=z_DgP4cDExjEqEeX_ZL--50MXQ9lrATK876SIwE71PQ,576
39
+ pytgcalls/methods/stream/time.py,sha256=5y9TMBf_d6YPLbMcGx3yMZQUZdo8zb5fQb9STsh7R3Y,656
37
40
  pytgcalls/methods/stream/unmute_stream.py,sha256=KUMhfMbhsPmZsmpF4cGWC1FVW7YwXha2MmQnqrBhM8s,576
38
41
  pytgcalls/methods/utilities/__init__.py,sha256=JcKwqNo6fFXXfuab94fNEraKF1P9fnSSgr0WQDRjF2w,339
39
42
  pytgcalls/methods/utilities/cache_peer.py,sha256=Ylt0wCCJOoNKf1wZEXjfE8aBZKUIIgdRUFOMTGA5DfE,140
40
- pytgcalls/methods/utilities/call_holder.py,sha256=MQxAYL3fDDWhf3UFRyLhJD_FVYOeWUNkr8pAII46htQ,972
43
+ pytgcalls/methods/utilities/call_holder.py,sha256=MhIbwCG6DROd9_bHGa6aqu-rB0y4sngzPBj82zLtAXU,1068
41
44
  pytgcalls/methods/utilities/compose.py,sha256=Nzdv8orMmka5NIBZ1SW1nsqXRzArZl4m6FdZU7syaR4,334
42
45
  pytgcalls/methods/utilities/cpu_usage.py,sha256=Mbga4MFCIwuh7WC8sqBbv1Pa6ALcp5AIDyfYMH_Bix4,162
43
46
  pytgcalls/methods/utilities/idle.py,sha256=MDdzHTv1ws2yBhsvhBUnssGdghkZ2KwR0HUCPOwV38o,814
44
47
  pytgcalls/methods/utilities/ping.py,sha256=hhIMSHk2BzMB-IKpwLdZFVrsEvGm2ftJwKLs1k4anh8,244
45
48
  pytgcalls/methods/utilities/resolve_chat_id.py,sha256=92x2LHbUlnJMm-kS3fXOYmzYpY2TZbqtQD2rw3eBXDY,382
46
49
  pytgcalls/methods/utilities/run.py,sha256=cnYQd2xB5Cr_WS0Q2cXJZPGiN6JOCULzj1r4xXVyrlg,152
47
- pytgcalls/methods/utilities/start.py,sha256=7mHp6RkfhuYC6i0JYmQvxK4KYRmkcvOs9kSrClPhNnk,9342
48
- pytgcalls/methods/utilities/stream_params.py,sha256=hYcNxx__McmPeHgOUDEuNcN7ThgDjukejQYHrfmWm-A,1519
50
+ pytgcalls/methods/utilities/start.py,sha256=ObY79b_2qxDSAytQEYeHKK4k4JRD2_iyLCPyGyKpH-E,13340
51
+ pytgcalls/methods/utilities/stream_params.py,sha256=g-DmwTY_aYTWhhZ4RDthORQXz_VrhK1JQKPFYmB64II,2992
49
52
  pytgcalls/mtproto/__init__.py,sha256=X4zvzFG7km7qHyE0fdvA550WcOVO_xl_p__gvIfDGmw,130
50
- pytgcalls/mtproto/bridged_client.py,sha256=kK22n-CKjtfmtNE6bXCpuL6kWAUK2_Ul7cGgx_HNuHQ,4975
51
- pytgcalls/mtproto/client_cache.py,sha256=1yA5CFAmWZUsWdpqk5vlaN3j1RV1rIN-X7EcqmsnlfY,5087
52
- pytgcalls/mtproto/hydrogram_client.py,sha256=x0s0ZmD_cVT_TtEUIT5qO0OueZg719TkfyraaUWJze0,21290
53
- pytgcalls/mtproto/mtproto_client.py,sha256=LO71RqgxZ3bYxSFb6l9cc4ks6_peyqHN4i_z478c7yw,6883
54
- pytgcalls/mtproto/pyrogram_client.py,sha256=oXKEoChpEpt3xS1NuM3rfXbmFcpWgBFyibgqm_Pp6D4,21479
55
- pytgcalls/mtproto/telethon_client.py,sha256=j2Ybibhg67IL8M2LXBWXIJwpc6dTDMz5_9MRYsOVcuw,20373
56
- pytgcalls/types/__init__.py,sha256=yJVJZoH9M9u9VgpZGUX-MF4NzE-vKp4KrId21YQbcGE,910
53
+ pytgcalls/mtproto/bridged_client.py,sha256=OlFCV7Xe2a9I0_AAWfrWJciAe1b7WtVocVjl1EsBMyY,5843
54
+ pytgcalls/mtproto/client_cache.py,sha256=Mt0827e_T8DXJHOTkXhkIQUT9EUBWjoLcFcXP1gBnZY,5973
55
+ pytgcalls/mtproto/hydrogram_client.py,sha256=3oMeEQN85yYkjeNA9oMCZvuniLTjdRdP_GJMJiOXfkI,22813
56
+ pytgcalls/mtproto/mtproto_client.py,sha256=3TN2MfFYr8Lfd5AKp_u8G64XHSfCtpy59h4_SACa8G4,7564
57
+ pytgcalls/mtproto/pyrogram_client.py,sha256=TumcUPm4HkQBnOpuQ2BgE6EgrZ9heTGjjhwh1_EbBbU,22996
58
+ pytgcalls/mtproto/telethon_client.py,sha256=vzhIQG3u9sbkoyWED3BezI-p_VQ1Bu41sGMVM9lDzPE,21800
59
+ pytgcalls/types/__init__.py,sha256=E-R2HKAH2AtMxVFDiPa1C7zY13cEqrPW6nTdCBIEOZU,1031
57
60
  pytgcalls/types/browsers.py,sha256=47Kr5q96n4Q4WvVhA6IUlS2egEcA9GRLlDeFcQYyc9M,9545
58
61
  pytgcalls/types/cache.py,sha256=FfsOcmYnsBGPlJoTPIXXYcUSpGE3rhx6cjIH77hyUL0,1059
59
62
  pytgcalls/types/dict.py,sha256=lAo9hu4VlVJa9S7P8Y81BYmKtvz0rH7hwpGcH3ynHUw,78
@@ -64,7 +67,7 @@ pytgcalls/types/py_object.py,sha256=VlazuMP0cFpExKimW8BtWR66LDewnNdQSLC7r_t7JIM,
64
67
  pytgcalls/types/update.py,sha256=wPCzWLhrsScZ3ksRTyt8IuDaaG5YI-ItG_Yw-OqzK2Y,157
65
68
  pytgcalls/types/user_agent.py,sha256=sSfeGqUe0v0wqBgdVszNFK0iOC_0Tdyto9CglBXlY4U,1086
66
69
  pytgcalls/types/calls/__init__.py,sha256=6O2wp7I3d2YGLNeMgXTRyG37Y6BESafneLdr9n37_4s,346
67
- pytgcalls/types/calls/call.py,sha256=wxa3L3nZnbTKtZbezCaA3iUt4rZ5IriQyMMrgRlp7GA,485
70
+ pytgcalls/types/calls/call.py,sha256=n7LW7FRNT2qJzbYC3D312judOlVUuocQ1eW9l9scGCo,546
68
71
  pytgcalls/types/calls/call_config.py,sha256=b6P43YTGF2t7E2CyD1mSYPJDUBvYYeHoxB3hSbTVyOY,120
69
72
  pytgcalls/types/calls/call_data.py,sha256=-qPj2QhWv32Xs7LyFQY4hiWDqJ21B8VBvdzREK8bDvY,544
70
73
  pytgcalls/types/calls/call_protocol.py,sha256=OVIQs1VgdY-DWbZbNr41hjLA4pGQvHx8Rgom1_NhJxQ,408
@@ -72,22 +75,25 @@ pytgcalls/types/calls/group_call_config.py,sha256=auKH-hZJWj8PhTkyeQ_VK2z9NpNvNC
72
75
  pytgcalls/types/calls/raw_call_update.py,sha256=hpNw6HrTW8Z36Lh2HinS-wzprryRtsIxyIFbIfjGgeI,795
73
76
  pytgcalls/types/chats/__init__.py,sha256=v8pUp_vbr2kQpyHtAQc80N-YqzmXHe9SbllUsa6njkU,261
74
77
  pytgcalls/types/chats/chat_update.py,sha256=wh8v2I-pZxJWGNBjIwWRbhY-ZCI4v8qGabDTpuJaHu0,619
75
- pytgcalls/types/chats/group_call_participant.py,sha256=HQ2EVZKE1_uEjtUKdUA8yJemdc189IN4mioSP-KDEiY,1020
78
+ pytgcalls/types/chats/group_call_participant.py,sha256=yYeBVEeUo7AoAySCKbFwWZxrSdPDNg4r25RSz51i0fk,1656
76
79
  pytgcalls/types/chats/updated_group_call_participant.py,sha256=-KID-z-4e43fhYWQp0pNMKPfmZizbJHXyzn6yLtIGNg,291
77
80
  pytgcalls/types/raw/__init__.py,sha256=ROHsKFeUMUtlFbx2rhfrdB-TuVm0zBuvNo29Ccn5614,308
78
81
  pytgcalls/types/raw/audio_parameters.py,sha256=1DsBPwdn_Ukd2Tbkb3whP_ILo9xJY_3XNNmbO4_NO9Q,449
79
- pytgcalls/types/raw/audio_stream.py,sha256=wEMa93hHt0VBUSuS6gPJlFIGZp5GdNU94O2C2u4AXnY,476
80
- pytgcalls/types/raw/stream.py,sha256=jCvFUSAdHupqMqfG1E36CgKijKoy0o2LUbgcVjj5Mz0,491
82
+ pytgcalls/types/raw/audio_stream.py,sha256=oN7Sx9oLbNFuNXiGYpoNabMwqWKGquLiHEywef28o7c,488
83
+ pytgcalls/types/raw/stream.py,sha256=xJ3w77ofKFnLIA4cAWIuw2yREpMPvTzIvtei-3xEbJQ,666
81
84
  pytgcalls/types/raw/video_parameters.py,sha256=nUl9gkfYTVU0iLNGTtlZ5cZg8K6F7odIi9n8POJXCK4,639
82
- pytgcalls/types/raw/video_stream.py,sha256=2Chrk7NFWF1H9V7hH71RZ5rF3iBhT53syFkHKw4-5gc,433
83
- pytgcalls/types/stream/__init__.py,sha256=xfF-9ZulOLk3E6G1nw1Ky0ZRWXlFuER0Uj8HQn3650w,338
85
+ pytgcalls/types/raw/video_stream.py,sha256=uE3jU9kJsrAoefXtDtEKNqTjcYGaQbZ1gbJ1SfiVWIc,488
86
+ pytgcalls/types/stream/__init__.py,sha256=a-3kNWnp4Vpja_x_Un6misT3VVVllChpeinc3w6Yd1k,457
84
87
  pytgcalls/types/stream/audio_quality.py,sha256=4X94ErmTeLP4TVcE3eLtPPdtluSPxgxbgTosuNJOVhc,141
85
- pytgcalls/types/stream/media_stream.py,sha256=YoG-vISvDga1n4IHs4hdF03ldtqyojFMvwB3To_39kE,8931
86
- pytgcalls/types/stream/stream_audio_ended.py,sha256=2_EFa98F0vWu0d0jBmLtzp4NH_xBkDO_6yP9UtyKuCs,164
87
- pytgcalls/types/stream/stream_video_ended.py,sha256=9YFTTZPMDpB95eb815rGtgDrzBGfTeazJ5mZwP6Hvks,164
88
+ pytgcalls/types/stream/device.py,sha256=lnWrChNArFl3Sk-DqVEs61K-YXl2rqRAQq6PSPgjBCU,578
89
+ pytgcalls/types/stream/direction.py,sha256=_Q1SNb-47krKuZs7B5dw1mqDhQ9_CTb_Jr96-MAfv28,395
90
+ pytgcalls/types/stream/media_stream.py,sha256=_gevQrmDJyLxGQCGk9qAfxe7949S8w51X2aF2rNCYM0,10222
91
+ pytgcalls/types/stream/record_stream.py,sha256=FNwreJsEHHn7k_nZYbdnfC7D9-5LyPWNFQVwHYkRzio,2961
92
+ pytgcalls/types/stream/stream_ended.py,sha256=xR_kZwFf03hA6rw_nvI7Be7GwoCKzQf_1MKaGpPDXqY,716
93
+ pytgcalls/types/stream/stream_frame.py,sha256=TMoJUbC2tsMDL1tt4oWCkaMsHoeYKj8dnV6JIs7EoEk,797
88
94
  pytgcalls/types/stream/video_quality.py,sha256=HBfWq005kh-D19MaVE9VzVdnODzrXf4IJUimCfslfiU,231
89
- py_tgcalls-2.0.6.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
90
- py_tgcalls-2.0.6.dist-info/METADATA,sha256=nY0vX7_2j6fWLYtBk6I4BCDfIQ_7qvgu7JkCRjEb0vA,14356
91
- py_tgcalls-2.0.6.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
92
- py_tgcalls-2.0.6.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
93
- py_tgcalls-2.0.6.dist-info/RECORD,,
95
+ py_tgcalls-2.1.0.dev2.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
96
+ py_tgcalls-2.1.0.dev2.dist-info/METADATA,sha256=x49Taxds_EKwrWUaD8LgzmYaHHVrM5uQ17V_KtsC2hE,14380
97
+ py_tgcalls-2.1.0.dev2.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
98
+ py_tgcalls-2.1.0.dev2.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
99
+ py_tgcalls-2.1.0.dev2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
pytgcalls/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from .__version__ import __version__
2
2
  from .custom_api import CustomApi
3
+ from .media_devices import MediaDevices
3
4
  from .pytgcalls import PyTgCalls
4
5
  from .sync import compose
5
6
  from .sync import idle
@@ -9,5 +10,6 @@ __all__ = (
9
10
  'compose',
10
11
  'CustomApi',
11
12
  'PyTgCalls',
13
+ 'MediaDevices',
12
14
  'idle',
13
15
  )
pytgcalls/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '2.0.6'
1
+ __version__ = '2.1.0.dev2'
pytgcalls/filters.py CHANGED
@@ -7,9 +7,11 @@ from typing import Union
7
7
  from .mtproto import BridgedClient
8
8
  from .pytgcalls import PyTgCalls
9
9
  from .types import ChatUpdate
10
+ from .types import Device
11
+ from .types import Direction
10
12
  from .types import GroupCallParticipant
11
- from .types import StreamAudioEnded
12
- from .types import StreamVideoEnded
13
+ from .types import StreamEnded
14
+ from .types import StreamFrame
13
15
  from .types import Update
14
16
  from .types import UpdatedGroupCallParticipant
15
17
 
@@ -135,11 +137,26 @@ async def _me_filter(_, client: PyTgCalls, u: Update):
135
137
  me = create(_me_filter)
136
138
 
137
139
 
138
- async def _stream_filter(_, __, u: Update):
139
- return isinstance(u, (StreamVideoEnded, StreamAudioEnded))
140
-
140
+ class stream_end(Filter):
141
+ def __init__(
142
+ self,
143
+ stream_type: Optional[StreamEnded.Type] = None,
144
+ device: Optional[Device] = None,
145
+ ):
146
+ self.stream_type = stream_type
147
+ self.device = device
141
148
 
142
- stream_end = create(_stream_filter)
149
+ async def __call__(self, client: PyTgCalls, update: Update):
150
+ if isinstance(update, StreamEnded):
151
+ return (
152
+ (
153
+ self.stream_type is None or
154
+ self.stream_type & update.stream_type
155
+ ) and (
156
+ self.device is None or
157
+ self.device & update.device
158
+ )
159
+ )
143
160
 
144
161
 
145
162
  # noinspection PyPep8Naming
@@ -180,3 +197,26 @@ class call_participant(Filter):
180
197
  return True
181
198
  return self.flags & update.participant.action
182
199
  return False
200
+
201
+
202
+ class stream_frame(Filter):
203
+ def __init__(
204
+ self,
205
+ directions: Optional[Direction] = None,
206
+ devices: Optional[Device] = None,
207
+ ):
208
+ self.directions = directions
209
+ self.devices = devices
210
+
211
+ async def __call__(self, client: PyTgCalls, update: Update):
212
+ if isinstance(update, StreamFrame):
213
+ return (
214
+ (
215
+ self.directions is None or
216
+ self.directions & update.direction
217
+ ) and (
218
+ self.devices is None or
219
+ self.devices & update.device
220
+ )
221
+ )
222
+ return False
@@ -1,9 +1,13 @@
1
1
  from .device_info import DeviceInfo
2
+ from .input_device import InputDevice
2
3
  from .media_devices import MediaDevices
3
- from .screen_info import ScreenInfo
4
+ from .screen_device import ScreenDevice
5
+ from .speaker_device import SpeakerDevice
4
6
 
5
7
  __all__ = (
6
8
  'DeviceInfo',
9
+ 'InputDevice',
7
10
  'MediaDevices',
8
- 'ScreenInfo',
11
+ 'ScreenDevice',
12
+ 'SpeakerDevice',
9
13
  )
@@ -1,20 +1,13 @@
1
- from sys import platform
2
-
3
-
4
1
  class DeviceInfo:
5
2
  def __init__(
6
3
  self,
7
- identifier: str,
8
- title: str,
4
+ name: str,
5
+ metadata: str,
6
+ is_video: bool,
9
7
  ):
10
- self.identifier = identifier
11
- self.title = title
12
- self.ffmpeg_parameters = ['-f']
8
+ self.title = name
9
+ self.metadata = metadata
10
+ self.is_video = is_video
13
11
 
14
- def build_ffmpeg_command(self):
15
- if platform == 'win32':
16
- self.ffmpeg_parameters += ['dshow']
17
- return f'audio={self.identifier}'
18
- else:
19
- self.ffmpeg_parameters += ['pulse']
20
- return self.identifier
12
+ def __repr__(self):
13
+ return self.title
@@ -0,0 +1,11 @@
1
+ from .device_info import DeviceInfo
2
+
3
+
4
+ class InputDevice(DeviceInfo):
5
+ def __init__(
6
+ self,
7
+ name: str,
8
+ metadata: str,
9
+ is_video: bool,
10
+ ):
11
+ super().__init__(name, metadata, is_video)
@@ -1,101 +1,50 @@
1
- import asyncio
2
- import re
3
- import subprocess
4
- from sys import platform
5
-
6
- from screeninfo import get_monitors
7
- from screeninfo import ScreenInfoError
1
+ from ntgcalls import DeviceInfo as RawDeviceInfo
2
+ from ntgcalls import NTgCalls
8
3
 
9
4
  from ..types.list import List
10
- from .device_info import DeviceInfo
11
- from .screen_info import ScreenInfo
5
+ from .input_device import InputDevice
6
+ from .screen_device import ScreenDevice
7
+ from .speaker_device import SpeakerDevice
12
8
 
13
9
 
14
10
  class MediaDevices:
15
11
  @staticmethod
16
- async def get_screen_devices() -> List:
17
- list_screens: List = List()
18
- if platform != 'darwin':
19
- try:
20
- for screen in get_monitors():
21
- list_screens.append(
22
- ScreenInfo(
23
- screen.x,
24
- screen.y,
25
- screen.width,
26
- screen.height,
27
- screen.is_primary,
28
- screen.name,
29
- ),
30
- )
31
- except ScreenInfoError:
32
- pass
33
- return list_screens
12
+ def _parse_devices(devices: list[RawDeviceInfo], is_video: bool) -> List:
13
+ return List(
14
+ InputDevice(device.name, device.metadata, is_video)
15
+ for device in devices
16
+ )
17
+
18
+ @staticmethod
19
+ def microphone_devices() -> List:
20
+ return MediaDevices._parse_devices(
21
+ NTgCalls.get_media_devices().microphone,
22
+ False,
23
+ )
24
+
25
+ @staticmethod
26
+ def speaker_devices() -> List:
27
+ return List(
28
+ SpeakerDevice(
29
+ device.name,
30
+ device.metadata,
31
+ )
32
+ for device in NTgCalls.get_media_devices().speaker
33
+ )
34
+
35
+ @staticmethod
36
+ def camera_devices() -> List:
37
+ return MediaDevices._parse_devices(
38
+ NTgCalls.get_media_devices().camera,
39
+ True,
40
+ )
34
41
 
35
42
  @staticmethod
36
- async def get_audio_devices() -> List:
37
- list_devices: List = List()
38
- if platform == 'darwin':
39
- return list_devices
40
- try:
41
- if platform == 'win32':
42
- commands = [
43
- 'ffmpeg',
44
- '-list_devices',
45
- 'true',
46
- '-f',
47
- 'dshow',
48
- '-i',
49
- 'dummy',
50
- ]
51
- else:
52
- commands = [
53
- 'pactl',
54
- 'list',
55
- 'sources',
56
- ]
57
- ffmpeg = await asyncio.create_subprocess_exec(
58
- *tuple(commands),
59
- stdout=asyncio.subprocess.PIPE,
60
- stderr=asyncio.subprocess.PIPE,
43
+ def screen_devices() -> List:
44
+ return List(
45
+ ScreenDevice(
46
+ device.name,
47
+ device.metadata,
61
48
  )
62
- try:
63
- stdout, stderr = await asyncio.wait_for(
64
- ffmpeg.communicate(),
65
- timeout=3,
66
- )
67
- result: str = ''
68
- if platform == 'win32':
69
- result = stderr.decode('utf-8')
70
- elif platform != 'darwin':
71
- result = stdout.decode('utf-8')
72
- except subprocess.TimeoutExpired:
73
- return list_devices
74
- if platform == 'win32':
75
- list_raw = result.split('DirectShow audio devices')
76
- if len(list_raw) < 2:
77
- return list_devices
78
- output = re.findall(
79
- '\\[.*?].*?"(.*?)".*?\n\\[.*?].*?"(.*?)"', list_raw[1],
80
- )
81
- for device in output:
82
- list_devices.append(
83
- DeviceInfo(
84
- device[1],
85
- device[0],
86
- ),
87
- )
88
- else:
89
- output = re.findall(
90
- 'Name: (.*?)\n.*?Description: (.*?)\n', result,
91
- )
92
- for device in output:
93
- list_devices.append(
94
- DeviceInfo(
95
- device[0],
96
- device[1],
97
- ),
98
- )
99
- except FileNotFoundError:
100
- pass
101
- return list_devices
49
+ for device in NTgCalls.get_media_devices().screen
50
+ )
@@ -0,0 +1,10 @@
1
+ from .input_device import InputDevice
2
+
3
+
4
+ class ScreenDevice(InputDevice):
5
+ def __init__(
6
+ self,
7
+ name: str,
8
+ metadata: str,
9
+ ):
10
+ super().__init__(name, metadata, True)
@@ -0,0 +1,10 @@
1
+ from .device_info import DeviceInfo
2
+
3
+
4
+ class SpeakerDevice(DeviceInfo):
5
+ def __init__(
6
+ self,
7
+ name: str,
8
+ metadata: str,
9
+ ):
10
+ super().__init__(name, metadata, False)
@@ -1,8 +1,9 @@
1
1
  from .mute_stream import MuteStream
2
2
  from .pause_stream import PauseStream
3
3
  from .play import Play
4
- from .played_time import PlayedTime
4
+ from .record import Record
5
5
  from .resume_stream import ResumeStream
6
+ from .time import Time
6
7
  from .unmute_stream import UnMuteStream
7
8
 
8
9
 
@@ -10,7 +11,8 @@ class StreamMethods(
10
11
  MuteStream,
11
12
  PauseStream,
12
13
  Play,
13
- PlayedTime,
14
+ Record,
15
+ Time,
14
16
  ResumeStream,
15
17
  UnMuteStream,
16
18
  ):