Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import asyncio
- import json
- import websockets
- from aiortc import RTCIceCandidate, RTCPeerConnection, RTCSessionDescription, RTCIceServer, RTCConfiguration
- class WebRTCClient:
- def __init__(self, uri):
- self.uri = uri
- ice_servers = [
- RTCIceServer(urls="stun:stun.l.google.com:19302") # Google's public STUN server
- ]
- self.pc = RTCPeerConnection(RTCConfiguration(iceServers=ice_servers))
- self.ice_candidates = []
- async def connect_to_websocket(self):
- self.websocket = await websockets.connect(self.uri)
- print("Connected to the signaling server")
- asyncio.create_task(self.receive_messages())
- @self.pc.on("track")
- async def on_track(track):
- print('TRACK RECEIVED', track)
- print('TRACK KIND', track.kind)
- @self.pc.on("icecandidate")
- async def on_icecandidate(event):
- candidate = event.candidate
- if candidate:
- print('ICE CANDIDATE GENERATED:', candidate)
- message = {
- 'event': 'candidate',
- 'data': {
- 'candidate': candidate.candidate,
- 'sdpMLineIndex': candidate.sdpMLineIndex,
- 'sdpMid': candidate.sdpMid
- }
- }
- await self.send_message(message)
- @self.pc.on('iceconnectionstatechange')
- async def on_iceconnectionstatechange():
- print("ICE connection state is", self.pc.iceConnectionState)
- if self.pc.iceConnectionState == "failed":
- print("ICE Connection has failed, attempting to restart ICE")
- await self.pc.restartIce()
- @self.pc.on('connectionstatechange')
- async def on_connectionstatechange():
- print('Connection state change:', self.pc.connectionState)
- if self.pc.connectionState == 'connected':
- print('Peers successfully connected')
- @self.pc.on('icegatheringstatechange')
- async def on_icegatheringstatechange():
- print('ICE gathering state changed to', self.pc.iceGatheringState)
- if self.pc.iceGatheringState == 'complete':
- print('All ICE candidates have been gathered.')
- # Log all gathered candidates
- for candidate in self.ice_candidates:
- print('Gathered candidate:', candidate)
- async def create_offer(self):
- await self.setup_media() # Setup media before creating an offer
- offer = await self.pc.createOffer()
- await self.pc.setLocalDescription(offer)
- await self.send_message({'event': 'offer', 'data': {'type': offer.type, 'sdp': offer.sdp}})
- async def setup_media(self):
- self.pc.addTransceiver('audio')
- self.pc.addTransceiver('video')
- async def receive_messages(self):
- async for message in self.websocket:
- data = json.loads(message)
- await self.handle_message(data)
- async def handle_message(self, message):
- event = message.get('event')
- data = message.get('data')
- if event == 'offer':
- await self.handle_offer(data)
- elif event == 'candidate':
- await self.handle_candidate(data)
- elif event == 'answer':
- await self.handle_answer(data)
- async def handle_offer(self, offer):
- await self.pc.setRemoteDescription(RTCSessionDescription(sdp=offer['sdp'], type=offer['type']))
- answer = await self.pc.createAnswer()
- await self.pc.setLocalDescription(answer)
- await self.send_message({'event': 'answer', 'data': {'type': answer.type, 'sdp': answer.sdp}})
- async def handle_candidate(self, candidate):
- ip = candidate['candidate'].split(' ')[4]
- port = candidate['candidate'].split(' ')[5]
- protocol = candidate['candidate'].split(' ')[7]
- priority = candidate['candidate'].split(' ')[3]
- foundation = candidate['candidate'].split(' ')[0]
- component = candidate['candidate'].split(' ')[1]
- type = candidate['candidate'].split(' ')[7]
- rtc_candidate = RTCIceCandidate(
- ip=ip,
- port=port,
- protocol=protocol,
- priority=priority,
- foundation=foundation,
- component=component,
- type=type,
- sdpMid=candidate['sdpMid'],
- sdpMLineIndex=candidate['sdpMLineIndex']
- )
- await self.pc.addIceCandidate(rtc_candidate)
- async def handle_answer(self, answer):
- await self.pc.setRemoteDescription(RTCSessionDescription(sdp=answer['sdp'], type=answer['type']))
- async def send_message(self, message):
- await self.websocket.send(json.dumps(message))
- async def close(self):
- await self.pc.close()
- await self.websocket.close()
- async def main():
- client = WebRTCClient('ws://localhost:8080/socket')
- await client.connect_to_websocket()
- # await client.create_offer() # Create an offer after connecting to the websocket
- await asyncio.sleep(3600) # Keep the session alive for debugging
- await client.close()
- if __name__ == '__main__':
- asyncio.run(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement