mirror of
https://github.com/comma-hacks/webrtc.git
synced 2025-10-06 00:26:52 +08:00
109 lines
3.3 KiB
Python
Executable File
109 lines
3.3 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 aiohttp import web
|
|
from aiortc import RTCPeerConnection, RTCSessionDescription, RTCRtpCodecCapability
|
|
from compressed_vipc_track import VisionIpcTrack
|
|
from desktop_stream_track import DesktopStreamTrack
|
|
|
|
ROOT = os.path.dirname(__file__)
|
|
|
|
cams = ["roadEncodeData","wideRoadEncodeData","driverEncodeData"]
|
|
|
|
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 javascript(request):
|
|
content = open(os.path.join(ROOT, "client.js"), "r").read()
|
|
return web.Response(content_type="application/javascript", text=content)
|
|
|
|
|
|
async def offer(request):
|
|
params = await request.json()
|
|
offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
|
|
|
|
pc = RTCPeerConnection()
|
|
pcs.add(pc)
|
|
|
|
@pc.on("connectionstatechange")
|
|
async def on_connectionstatechange():
|
|
print("Connection state is %s" % pc.connectionState)
|
|
if pc.connectionState == "failed":
|
|
await pc.close()
|
|
pcs.discard(pc)
|
|
|
|
# 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()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description="Decode video streams and broadcast via WebRTC")
|
|
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("--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
|
|
|
|
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) |