Advertisement
Harsh4999

Untitled

Apr 14th, 2024
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.26 KB | None | 0 0
  1. import asyncio
  2. import json
  3. import websockets
  4. from aiortc import RTCIceCandidate, RTCPeerConnection, RTCSessionDescription, RTCIceServer, RTCConfiguration
  5.  
  6. class WebRTCClient:
  7. def __init__(self, uri):
  8. self.uri = uri
  9. ice_servers = [
  10. RTCIceServer(urls="stun:stun.l.google.com:19302") # Google's public STUN server
  11. ]
  12. self.pc = RTCPeerConnection(RTCConfiguration(iceServers=ice_servers))
  13. self.ice_candidates = []
  14.  
  15. async def connect_to_websocket(self):
  16. self.websocket = await websockets.connect(self.uri)
  17. print("Connected to the signaling server")
  18. asyncio.create_task(self.receive_messages())
  19.  
  20. @self.pc.on("track")
  21. async def on_track(track):
  22. print('TRACK RECEIVED', track)
  23. print('TRACK KIND', track.kind)
  24.  
  25. @self.pc.on("icecandidate")
  26. async def on_icecandidate(event):
  27. candidate = event.candidate
  28. if candidate:
  29. print('ICE CANDIDATE GENERATED:', candidate)
  30. message = {
  31. 'event': 'candidate',
  32. 'data': {
  33. 'candidate': candidate.candidate,
  34. 'sdpMLineIndex': candidate.sdpMLineIndex,
  35. 'sdpMid': candidate.sdpMid
  36. }
  37. }
  38. await self.send_message(message)
  39.  
  40. @self.pc.on('iceconnectionstatechange')
  41. async def on_iceconnectionstatechange():
  42. print("ICE connection state is", self.pc.iceConnectionState)
  43. if self.pc.iceConnectionState == "failed":
  44. print("ICE Connection has failed, attempting to restart ICE")
  45. await self.pc.restartIce()
  46.  
  47. @self.pc.on('connectionstatechange')
  48. async def on_connectionstatechange():
  49. print('Connection state change:', self.pc.connectionState)
  50. if self.pc.connectionState == 'connected':
  51. print('Peers successfully connected')
  52.  
  53.  
  54. @self.pc.on('icegatheringstatechange')
  55. async def on_icegatheringstatechange():
  56. print('ICE gathering state changed to', self.pc.iceGatheringState)
  57. if self.pc.iceGatheringState == 'complete':
  58. print('All ICE candidates have been gathered.')
  59. # Log all gathered candidates
  60. for candidate in self.ice_candidates:
  61. print('Gathered candidate:', candidate)
  62.  
  63. async def create_offer(self):
  64. await self.setup_media() # Setup media before creating an offer
  65. offer = await self.pc.createOffer()
  66. await self.pc.setLocalDescription(offer)
  67. await self.send_message({'event': 'offer', 'data': {'type': offer.type, 'sdp': offer.sdp}})
  68.  
  69. async def setup_media(self):
  70. self.pc.addTransceiver('audio')
  71. self.pc.addTransceiver('video')
  72.  
  73. async def receive_messages(self):
  74. async for message in self.websocket:
  75. data = json.loads(message)
  76. await self.handle_message(data)
  77.  
  78. async def handle_message(self, message):
  79. event = message.get('event')
  80. data = message.get('data')
  81. if event == 'offer':
  82. await self.handle_offer(data)
  83. elif event == 'candidate':
  84. await self.handle_candidate(data)
  85. elif event == 'answer':
  86. await self.handle_answer(data)
  87.  
  88. async def handle_offer(self, offer):
  89. await self.pc.setRemoteDescription(RTCSessionDescription(sdp=offer['sdp'], type=offer['type']))
  90. answer = await self.pc.createAnswer()
  91. await self.pc.setLocalDescription(answer)
  92. await self.send_message({'event': 'answer', 'data': {'type': answer.type, 'sdp': answer.sdp}})
  93.  
  94. async def handle_candidate(self, candidate):
  95. ip = candidate['candidate'].split(' ')[4]
  96. port = candidate['candidate'].split(' ')[5]
  97. protocol = candidate['candidate'].split(' ')[7]
  98. priority = candidate['candidate'].split(' ')[3]
  99. foundation = candidate['candidate'].split(' ')[0]
  100. component = candidate['candidate'].split(' ')[1]
  101. type = candidate['candidate'].split(' ')[7]
  102. rtc_candidate = RTCIceCandidate(
  103. ip=ip,
  104. port=port,
  105. protocol=protocol,
  106. priority=priority,
  107. foundation=foundation,
  108. component=component,
  109. type=type,
  110. sdpMid=candidate['sdpMid'],
  111. sdpMLineIndex=candidate['sdpMLineIndex']
  112. )
  113. await self.pc.addIceCandidate(rtc_candidate)
  114.  
  115. async def handle_answer(self, answer):
  116. await self.pc.setRemoteDescription(RTCSessionDescription(sdp=answer['sdp'], type=answer['type']))
  117.  
  118. async def send_message(self, message):
  119. await self.websocket.send(json.dumps(message))
  120.  
  121. async def close(self):
  122. await self.pc.close()
  123. await self.websocket.close()
  124.  
  125. async def main():
  126. client = WebRTCClient('ws://localhost:8080/socket')
  127. await client.connect_to_websocket()
  128. # await client.create_offer() # Create an offer after connecting to the websocket
  129. await asyncio.sleep(3600) # Keep the session alive for debugging
  130. await client.close()
  131.  
  132. if __name__ == '__main__':
  133. asyncio.run(main())
  134.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement