pyLiveMusic 0.2__tar.gz → 0.3__tar.gz

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.

Potentially problematic release.


This version of pyLiveMusic might be problematic. Click here for more details.

Files changed (48) hide show
  1. {pylivemusic-0.2 → pylivemusic-0.3}/PKG-INFO +1 -1
  2. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_engine/_webrtc/backend.py +2 -8
  3. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_engine/_webrtc/peer.py +18 -5
  4. pylivemusic-0.3/src/_core/_core_engine/_webrtc/signaling.py +109 -0
  5. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/__init__.py +1 -1
  6. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic.egg-info/PKG-INFO +1 -1
  7. pylivemusic-0.2/src/_core/_core_engine/_webrtc/signaling.py +0 -91
  8. {pylivemusic-0.2 → pylivemusic-0.3}/LICENSE +0 -0
  9. {pylivemusic-0.2 → pylivemusic-0.3}/README.md +0 -0
  10. {pylivemusic-0.2 → pylivemusic-0.3}/pyproject.toml +0 -0
  11. {pylivemusic-0.2 → pylivemusic-0.3}/setup.cfg +0 -0
  12. {pylivemusic-0.2 → pylivemusic-0.3}/src/_api/_errors.py +0 -0
  13. {pylivemusic-0.2 → pylivemusic-0.3}/src/_api/_routes.py +0 -0
  14. {pylivemusic-0.2 → pylivemusic-0.3}/src/_api/playback.py +0 -0
  15. {pylivemusic-0.2 → pylivemusic-0.3}/src/_api/queue.py +0 -0
  16. {pylivemusic-0.2 → pylivemusic-0.3}/src/_api/rooms.py +0 -0
  17. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_aiohttp/_app.py +0 -0
  18. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_aiohttp/_endpoints.py +0 -0
  19. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_engine/_webrtc/audio.py +0 -0
  20. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_func/_auth/_auth.py +0 -0
  21. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_func/_context.py +0 -0
  22. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_func/_data_config.py +0 -0
  23. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_core_func/_state/_data_state.py +0 -0
  24. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_database/memory/_repo.py +0 -0
  25. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_database/memory/_storage.py +0 -0
  26. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_database/mongo/_repo.py +0 -0
  27. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_database/mongo/_storage.py +0 -0
  28. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_database/redis/_repo.py +0 -0
  29. {pylivemusic-0.2 → pylivemusic-0.3}/src/_core/_database/redis/_storage.py +0 -0
  30. {pylivemusic-0.2 → pylivemusic-0.3}/src/_utils/_settings.py +0 -0
  31. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/_logger.py +0 -0
  32. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/_static/audio.html +0 -0
  33. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/_static/audio.js +0 -0
  34. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/_static/embed.html +0 -0
  35. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/core/__init__.py +0 -0
  36. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/core/client.py +0 -0
  37. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/player/__init__.py +0 -0
  38. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/player/playback.py +0 -0
  39. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/player/queue.py +0 -0
  40. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/player/room.py +0 -0
  41. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/storage/__init__.py +0 -0
  42. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/storage/memory.py +0 -0
  43. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/storage/mongodb.py +0 -0
  44. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic/storage/redis.py +0 -0
  45. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic.egg-info/SOURCES.txt +0 -0
  46. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic.egg-info/dependency_links.txt +0 -0
  47. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic.egg-info/requires.txt +0 -0
  48. {pylivemusic-0.2 → pylivemusic-0.3}/src/pyLiveMusic.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyLiveMusic
3
- Version: 0.2
3
+ Version: 0.3
4
4
  Summary: A python framework for creating private room for live streaming audio using webrtc.
5
5
  Author: Bakachii
6
6
  License-Expression: MIT
@@ -352,27 +352,21 @@ class Room:
352
352
 
353
353
 
354
354
  # WebRTC offer
355
-
356
355
  async def offer(self, peer, sdp):
357
356
  offer = RTCSessionDescription(
358
357
  sdp=sdp,
359
358
  type="offer",
360
359
  )
361
360
 
362
- await peer.connection.setRemoteDescription(
363
- offer
364
- )
361
+ await peer.connection.setRemoteDescription(offer)
365
362
 
366
363
  await peer.set_remote_ready()
367
364
 
368
365
  answer = await peer.connection.createAnswer()
369
366
 
370
- await peer.connection.setLocalDescription(
371
- answer
372
- )
367
+ await peer.connection.setLocalDescription(answer)
373
368
 
374
369
  return peer.connection.localDescription
375
-
376
370
  # State
377
371
 
378
372
  def state(self):
@@ -1,13 +1,14 @@
1
+ import asyncio
2
+
1
3
  from aiortc import RTCPeerConnection
2
4
  from aiortc.contrib.media import MediaRelay
3
- from pyLiveMusic._logger import logs
4
5
 
6
+ from pyLiveMusic._logger import logs
5
7
  from _utils._settings import QUALITY_BITRATES
6
8
 
7
9
 
8
10
  class Peer:
9
11
  def __init__(self, relay, audio_track, quality="high", on_close=None):
10
-
11
12
  self.id = None
12
13
  self.connection = RTCPeerConnection()
13
14
  logs.info("[WEBRTC] Creating peer")
@@ -22,6 +23,9 @@ class Peer:
22
23
  self._on_close = on_close
23
24
  self._closed = False
24
25
 
26
+ self._remote_ready = asyncio.Event()
27
+ self._pending_candidates = []
28
+
25
29
  @self.connection.on("connectionstatechange")
26
30
  async def connection_state():
27
31
  logs.info(
@@ -51,10 +55,20 @@ class Peer:
51
55
  f"{self.connection.signalingState}"
52
56
  )
53
57
 
58
+ async def add_candidate(self, candidate):
59
+ if not self._remote_ready.is_set():
60
+ self._pending_candidates.append(candidate)
61
+ return
54
62
 
55
- async def add_ice_candidate(self, candidate):
56
63
  await self.connection.addIceCandidate(candidate)
57
64
 
65
+ async def set_remote_ready(self):
66
+ self._remote_ready.set()
67
+
68
+ for candidate in self._pending_candidates:
69
+ await self.connection.addIceCandidate(candidate)
70
+
71
+ self._pending_candidates.clear()
58
72
 
59
73
  async def set_quality(self, quality):
60
74
  if quality not in QUALITY_BITRATES:
@@ -70,10 +84,9 @@ class Peer:
70
84
 
71
85
  await self.sender.setParameters(parameters)
72
86
 
73
-
74
87
  async def close(self):
75
88
  if self._closed:
76
89
  return
77
90
 
78
91
  self._closed = True
79
- await self.connection.close()
92
+ await self.connection.close()
@@ -0,0 +1,109 @@
1
+ from aiohttp import web
2
+ from aiortc.sdp import candidate_from_sdp
3
+
4
+ from pyLiveMusic._logger import logs
5
+
6
+
7
+ async def offer(request):
8
+ try:
9
+ room_id = request.match_info["room_id"]
10
+
11
+ room = request.app["state"].rooms.get(room_id)
12
+
13
+ if room is None:
14
+ raise web.HTTPNotFound(text="Room not found")
15
+
16
+ data = await request.json()
17
+
18
+ sdp = data.get("sdp")
19
+
20
+ if not sdp:
21
+ raise web.HTTPBadRequest(text="Missing SDP")
22
+
23
+ peer = await room.add_peer()
24
+
25
+ try:
26
+ answer = await room.offer(peer, sdp)
27
+
28
+ except Exception:
29
+ await room.remove_peer(peer)
30
+ raise
31
+
32
+ return web.json_response({
33
+ "peer_id": peer.id,
34
+ "type": answer.type,
35
+ "sdp": answer.sdp,
36
+ })
37
+
38
+ except web.HTTPException:
39
+ raise
40
+
41
+ except Exception:
42
+ logs.exception("[WEBRTC] Offer error")
43
+ raise
44
+
45
+
46
+ async def candidate(request):
47
+ try:
48
+ room_id = request.match_info["room_id"]
49
+
50
+ room = request.app["state"].rooms.get(room_id)
51
+
52
+ if room is None:
53
+ raise web.HTTPNotFound(
54
+ text="Room not found"
55
+ )
56
+
57
+ data = await request.json()
58
+
59
+ peer_id = data.get("peer_id")
60
+
61
+ if not peer_id:
62
+ raise web.HTTPBadRequest(
63
+ text="Missing peer_id"
64
+ )
65
+
66
+ peer = room.get_peer(peer_id)
67
+
68
+ if peer is None:
69
+ raise web.HTTPNotFound(
70
+ text="Peer not found"
71
+ )
72
+
73
+ value = data.get("candidate")
74
+
75
+ if not value:
76
+ return web.json_response({
77
+ "ok": True
78
+ })
79
+
80
+ candidate_sdp = value.get("candidate")
81
+
82
+ if not candidate_sdp:
83
+ return web.json_response({
84
+ "ok": True
85
+ })
86
+
87
+ try:
88
+ ice = candidate_from_sdp(candidate_sdp)
89
+
90
+ except Exception as error:
91
+ raise web.HTTPBadRequest(
92
+ text=f"Invalid ICE candidate: {error}"
93
+ )
94
+
95
+ ice.sdpMid = value.get("sdpMid")
96
+ ice.sdpMLineIndex = value.get("sdpMLineIndex")
97
+
98
+ await peer.add_candidate(ice)
99
+
100
+ return web.json_response({
101
+ "ok": True
102
+ })
103
+
104
+ except web.HTTPException:
105
+ raise
106
+
107
+ except Exception:
108
+ logs.exception("[WEBRTC] Candidate error")
109
+ raise
@@ -1,6 +1,6 @@
1
1
  from .core import Client
2
2
 
3
- __version__ = "0.2" # MAJOR.PATCH
3
+ __version__ = "0.3" # MAJOR.PATCH
4
4
 
5
5
  __author__ = "github.com/Bakachii"
6
6
  __all__ = ["Client"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyLiveMusic
3
- Version: 0.2
3
+ Version: 0.3
4
4
  Summary: A python framework for creating private room for live streaming audio using webrtc.
5
5
  Author: Bakachii
6
6
  License-Expression: MIT
@@ -1,91 +0,0 @@
1
- from aiohttp import web
2
- from aiortc.sdp import candidate_from_sdp
3
-
4
-
5
- async def offer(request):
6
- room_id = request.match_info["room_id"]
7
- room = request.app["state"].rooms.get(room_id)
8
-
9
- if room is None:
10
- raise web.HTTPNotFound(text="Room not found")
11
-
12
- data = await request.json()
13
-
14
- peer = await room.add_peer()
15
-
16
- try:
17
- answer = await room.offer(
18
- peer,
19
- data["sdp"]
20
- )
21
-
22
- except Exception:
23
- await room.remove_peer(peer)
24
- raise
25
-
26
- return web.json_response({
27
- "peer_id": peer.id,
28
- "type": answer.type,
29
- "sdp": answer.sdp,
30
- })
31
-
32
-
33
- async def candidate(request):
34
- room_id = request.match_info["room_id"]
35
-
36
- room = request.app["state"].rooms.get(room_id)
37
-
38
- if room is None:
39
- raise web.HTTPNotFound(
40
- text="Room not found"
41
- )
42
-
43
- data = await request.json()
44
-
45
- peer_id = data.get("peer_id")
46
-
47
- if not peer_id:
48
- raise web.HTTPBadRequest(
49
- text="Missing peer_id"
50
- )
51
-
52
- peer = room.get_peer(peer_id)
53
-
54
- if peer is None:
55
- raise web.HTTPNotFound(
56
- text="Peer not found"
57
- )
58
-
59
- value = data.get("candidate")
60
-
61
- if not value:
62
- return web.json_response({
63
- "ok": True
64
- })
65
-
66
- candidate_sdp = value.get("candidate")
67
-
68
- if not candidate_sdp:
69
- return web.json_response({
70
- "ok": True
71
- })
72
-
73
- try:
74
- ice = candidate_from_sdp(
75
- candidate_sdp
76
- )
77
- except Exception as error:
78
- raise web.HTTPBadRequest(
79
- text=f"Invalid ICE candidate: {error}"
80
- )
81
-
82
- ice.sdpMid = value.get("sdpMid")
83
- ice.sdpMLineIndex = value.get(
84
- "sdpMLineIndex"
85
- )
86
-
87
- await peer.add_candidate(ice)
88
-
89
- return web.json_response({
90
- "ok": True
91
- })
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes