async def on_connect(self, websocket): websocket.state.pc = RTCPeerConnection() await websocket.accept()
async def offer(request): params = await request.json() offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"]) pc = RTCPeerConnection() pc_id = "PeerConnection(%s)" % uuid.uuid4() pcs.add(pc) def log_info(msg, *args): logger.info(pc_id + " " + msg, *args) log_info("Created for %s", request.remote) # prepare local media player = MediaPlayer(os.path.join(ROOT, "demo-instruct.wav")) if args.record_to: recorder = MediaRecorder(args.record_to) else: recorder = MediaBlackhole() @pc.on("datachannel") def on_datachannel(channel): @channel.on("message") def on_message(message): if isinstance(message, str) and message.startswith("ping"): channel.send("pong" + message[4:]) @pc.on("connectionstatechange") async def on_connectionstatechange(): log_info("Connection state is %s", pc.connectionState) if pc.connectionState == "failed": await pc.close() pcs.discard(pc) @pc.on("track") def on_track(track): log_info("Track %s received", track.kind) if track.kind == "audio": pc.addTrack(player.audio) recorder.addTrack(track) elif track.kind == "video": pc.addTrack( VideoTransformTrack(relay.subscribe(track), transform=params["video_transform"])) if args.record_to: recorder.addTrack(relay.subscribe(track)) @track.on("ended") async def on_ended(): log_info("Track %s ended", track.kind) await recorder.stop() # handle offer await pc.setRemoteDescription(offer) await recorder.start() # send answer 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 }), )
"--room", type=int, default=1234, help="The video room ID to join (default: 1234).", ), parser.add_argument("--play-from", help="Read the media from a file and sent it to room."), parser.add_argument("--record-to", help="Write the media received to a device."), parser.add_argument("--verbose", "-v", action="count") args = parser.parse_args() if args.verbose: logging.basicConfig(level=logging.DEBUG) # create signaling and peer connection session = JanusSession(args.url) pc = RTCPeerConnection() # create media source if args.play_from: player = MediaPlayer(args.play_from) else: player = None # create media sink if args.record_to: print('Recording to: ', args.record_to) recorder = MediaRecorder(args.record_to, format='v4l2') else: recorder = MediaBlackhole() loop = asyncio.get_event_loop()
async def handler(request): uri = str(request.rel_url) logger.info('Request: {}'.format(uri)) if uri == '/start': udp_ep.status = "start" return web.Response(text=udp_ep.status) elif uri == '/stop': udp_ep.status = "stop" return web.Response(text=udp_ep.status) elif uri == '/status': return web.Response(text=udp_ep.status) elif uri == '/offer': if request.method == "OPTIONS": return web.Response( headers={ "Access-Control-Allow-Origin": request.headers["Origin"], "Access-Control-Allow-Headers": "content-type", }) params = await request.json() offer = RTCSessionDescription(sdp=params['sdp'], type=params['type']) pc = RTCPeerConnection() pc_id = 'PeerConnection(%s)' % uuid.uuid4() pcs.add(pc) def log_info(msg, *args): logger.debug(pc_id + ' ' + msg, *args) log_info('Created for %s', request.remote) @pc.on('datachannel') def on_datachannel(channel): replier.channel = channel @pc.on('iceconnectionstatechange') async def on_iceconnectionstatechange(): log_info('ICE connection state is %s', pc.iceConnectionState) if pc.iceConnectionState == 'failed': await pc.close() pcs.discard(pc) @pc.on('track') async def on_track(track): log_info('Track %s received', track.kind) if track.kind == 'audio': while True: frame = await track.recv() try: frame = resampler.resample(frame) data = frame.to_ndarray().tobytes() datagram_endpoint.datagram_received(data, '') except: pass @track.on('ended') async def on_ended(): log_info('Track %s ended', track.kind) # handle offer await pc.setRemoteDescription(offer) # send answer answer = await pc.createAnswer() await pc.setLocalDescription(answer) return web.Response(headers={"Access-Control-Allow-Origin": "*"}, content_type='application/json', text=json.dumps({ 'sdp': pc.localDescription.sdp, 'type': pc.localDescription.type })) else: return web.Response(text="not implemented")