mirror of
https://github.com/comma-hacks/webrtc.git
synced 2025-10-16 13:10:38 +08:00
connect from secureput iphone app
This commit is contained in:
138
server.py
138
server.py
@@ -6,104 +6,94 @@ import logging
|
||||
import os
|
||||
import ssl
|
||||
from typing import OrderedDict
|
||||
from aiohttp import web
|
||||
from aiortc import RTCPeerConnection, RTCSessionDescription, RTCRtpCodecCapability
|
||||
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
|
||||
|
||||
ROOT = os.path.dirname(__file__)
|
||||
# optional, for better performance
|
||||
# try:
|
||||
# import uvloop
|
||||
# except ImportError:
|
||||
# uvloop = None
|
||||
|
||||
cams = ["roadEncodeData","wideRoadEncodeData","driverEncodeData"]
|
||||
cam = 1
|
||||
|
||||
async def index(request):
|
||||
content = open(os.path.join(ROOT, "index.html"), "r").read()
|
||||
return web.Response(content_type="text/html", text=content)
|
||||
async def signal(pc, signaling):
|
||||
await signaling.connect()
|
||||
|
||||
async def javascript(request):
|
||||
content = open(os.path.join(ROOT, "client.js"), "r").read()
|
||||
return web.Response(content_type="application/javascript", text=content)
|
||||
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)
|
||||
|
||||
async def offer(request):
|
||||
params = await request.json()
|
||||
offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
|
||||
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 = RTCPeerConnection()
|
||||
pcs.add(pc)
|
||||
@pc.on("connectionstatechange")
|
||||
async def on_connectionstatechange():
|
||||
print("Connection state is %s" % pc.iceConnectionState)
|
||||
if pc.iceConnectionState == "failed":
|
||||
await pc.close()
|
||||
|
||||
@pc.on("connectionstatechange")
|
||||
async def on_connectionstatechange():
|
||||
print("Connection state is %s" % pc.connectionState)
|
||||
if pc.connectionState == "failed":
|
||||
await pc.close()
|
||||
pcs.discard(pc)
|
||||
@pc.on('datachannel')
|
||||
def on_datachannel(channel):
|
||||
print("data channel!")
|
||||
@channel.on('message')
|
||||
async def on_message(message):
|
||||
print("message!!")
|
||||
|
||||
# TODO: stream the microphone
|
||||
audio = None
|
||||
|
||||
# video = VisionIpcTrack(cams[int(args.cam)], args.addr)
|
||||
video = DesktopStreamTrack()
|
||||
|
||||
video_sender = pc.addTrack(video)
|
||||
|
||||
await pc.setRemoteDescription(offer)
|
||||
|
||||
answer = await pc.createAnswer()
|
||||
await pc.setLocalDescription(answer)
|
||||
|
||||
return web.Response(
|
||||
content_type="application/json",
|
||||
text=json.dumps(
|
||||
{"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
pcs = set()
|
||||
|
||||
|
||||
async def on_shutdown(app):
|
||||
# close peer connections
|
||||
coros = [pc.close() for pc in pcs]
|
||||
await asyncio.gather(*coros)
|
||||
pcs.clear()
|
||||
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="Decode video streams and broadcast via WebRTC")
|
||||
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("--cam", default="0", help="Camera to stream")
|
||||
|
||||
parser.add_argument("--cert-file", help="SSL certificate file (for HTTPS)")
|
||||
parser.add_argument("--key-file", help="SSL key file (for HTTPS)")
|
||||
parser.add_argument(
|
||||
"--host", default="0.0.0.0", help="Host for HTTP server (default: 0.0.0.0)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--port", type=int, default=8080, help="Port for HTTP server (default: 8080)"
|
||||
)
|
||||
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)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
if args.cert_file:
|
||||
ssl_context = ssl.SSLContext()
|
||||
ssl_context.load_cert_chain(args.cert_file, args.key_file)
|
||||
else:
|
||||
ssl_context = None
|
||||
# if uvloop is not None:
|
||||
# asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
||||
|
||||
app = web.Application()
|
||||
app.on_shutdown.append(on_shutdown)
|
||||
app.router.add_get("/", index)
|
||||
app.router.add_get("/client.js", javascript)
|
||||
app.router.add_post("/offer", offer)
|
||||
web.run_app(app, host=args.host, port=args.port, ssl_context=ssl_context)
|
||||
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())
|
Reference in New Issue
Block a user