Files
webrtc/server.py
2023-01-16 01:17:16 -08:00

99 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python
import argparse
import asyncio
import json
import logging
import os
import ssl
from typing import OrderedDict
from aiortc import RTCPeerConnection, RTCSessionDescription, RTCIceCandidate, RTCRtpCodecCapability, RTCConfiguration, RTCIceServer
from compressed_vipc_track import VisionIpcTrack
from desktop_stream_track import DesktopStreamTrack
from aiortc.contrib.signaling import BYE
from secureput.secureput_signaling import SecureputSignaling
# optional, for better performance
# try:
# import uvloop
# except ImportError:
# uvloop = None
cams = ["roadEncodeData","wideRoadEncodeData","driverEncodeData"]
cam = 1
async def signal(pc, signaling):
await signaling.connect()
while True:
obj = await signaling.receive()
# The peer trickles, but aiortc doesn't https://github.com/aiortc/aiortc/issues/227
# > aioice, the library which aiortc uses for ICE does not trickle ICE candidates:
# > you get all the candidates in one go. As such once you have called setLocalDescription()
# > for your offer or answer, all your ICE candidates are listed in pc.localDescription.
if isinstance(obj, RTCIceCandidate):
pc.addIceCandidate(obj)
if isinstance(obj, RTCSessionDescription):
if pc != None and pc.iceConnectionState != "failed":
await pc.close()
pc = RTCPeerConnection(configuration=RTCConfiguration([RTCIceServer("stun:stun.secureput.com:3478")]))
@pc.on("connectionstatechange")
async def on_connectionstatechange():
print("Connection state is %s" % pc.iceConnectionState)
if pc.iceConnectionState == "failed":
await pc.close()
@pc.on('datachannel')
def on_datachannel(channel):
print("data channel!")
@channel.on('message')
async def on_message(message):
print("message!!")
await pc.setRemoteDescription(obj)
if obj.type == 'offer':
# TODO: stream the microphone
audio = None
video = VisionIpcTrack(cams[int(cam)], "tici")
# video = DesktopStreamTrack()
pc.addTrack(video)
answer = await pc.createAnswer()
await pc.setLocalDescription(answer)
await signaling.send(pc.localDescription)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Comma Body WebRTC Service")
parser.add_argument("--addr", default='tici', help="Address of comma three")
# Not implemented (yet?). Geo already made the PoC for this, it should be possible.
# parser.add_argument("--nvidia", action="store_true", help="Use nvidia instead of ffmpeg")
parser.add_argument("--signaling-server", default="wss://signal.secureput.com", help="Signaling server to use")
parser.add_argument("--stun-server", default="stun:stun.secureput.com:3478", help="STUN server to use")
parser.add_argument("--verbose", "-v", action="count")
args = parser.parse_args()
if args.verbose:
logging.basicConfig(level=logging.DEBUG)
# if uvloop is not None:
# asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
pc = RTCPeerConnection(configuration=RTCConfiguration([RTCIceServer(args.stun_server)]))
signaling = SecureputSignaling(args.signaling_server)
coro = signal(pc, signaling)
# run event loop
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(coro)
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(pc.close())
loop.run_until_complete(signaling.close())