def test_video_ended(self): track = VideoStreamTrack() recorder = MediaBlackhole() recorder.addTrack(track) run(recorder.start()) run(asyncio.sleep(1)) track.stop() run(asyncio.sleep(1)) run(recorder.stop())
def __init__(self, uri, player=None, recorder=MediaBlackhole()): self._uri = uri self._player = player self._recorder = recorder # Save answers temporarily self._answers = {} self._websocket = None self._device = None self._tracks = [] if player and player.audio: audioTrack = player.audio else: audioTrack = AudioStreamTrack() if player and player.video: videoTrack = player.video else: videoTrack = VideoStreamTrack() self._videoTrack = videoTrack self._audioTrack = audioTrack self._tracks.append(videoTrack) self._tracks.append(audioTrack) self._sendTransport: Optional[Transport] = None self._recvTransport: Optional[Transport] = None self._producers = [] self._consumers = [] self._tasks = [] self._closed = False
async def publish(plugin, player): """ Send video to the room. """ pc = RTCPeerConnection() pcs.add(pc) # configure media media = {"audio": False, "video": True} if player: print("Play") pc.addTrack(player) else: pc.addTrack(VideoStreamTrack()) # send offer await pc.setLocalDescription(await pc.createOffer()) request = {"request": "configure"} request.update(media) response = await plugin.send({ "body": request, "jsep": { "sdp": pc.localDescription.sdp, "trickle": False, "type": pc.localDescription.type, }, }) # apply answer await pc.setRemoteDescription( RTCSessionDescription(sdp=response["jsep"]["sdp"], type=response["jsep"]["type"]))
def test_audio_and_video(self): recorder = MediaRecorder(path='foo.mp4') recorder.addTrack(AudioStreamTrack()) recorder.addTrack(VideoStreamTrack()) recorder.start() run(asyncio.sleep(2)) recorder.stop()
def test_audio_and_video(self): recorder = MediaBlackhole() recorder.addTrack(AudioStreamTrack()) recorder.addTrack(VideoStreamTrack()) run(recorder.start()) run(asyncio.sleep(2)) run(recorder.stop())
def test_audio_and_video(self): recorder = MediaRecorder(self.temporary_path('test.mp4')) recorder.addTrack(AudioStreamTrack()) recorder.addTrack(VideoStreamTrack()) run(recorder.start()) run(asyncio.sleep(2)) run(recorder.stop())
async def join_room(room): consumers = [] # fetch room parameters async with aiohttp.ClientSession() as session: async with session.post('https://appr.tc/join/' + room) as response: # we cannot use response.json() due to: # https://github.com/webrtc/apprtc/issues/562 data = json.loads(await response.text()) assert data['result'] == 'SUCCESS' params = data['params'] # create peer conection pc = RTCPeerConnection() pc.addTrack(AudioStreamTrack()) pc.addTrack(VideoStreamTrack()) @pc.on('track') def on_track(track): if track.kind == 'audio': consumers.append(asyncio.ensure_future(consume_audio(track))) elif track.kind == 'video': consumers.append(asyncio.ensure_future(consume_video(track))) # connect to websocket and join signaling = Signaling() await signaling.connect(params) await signaling.send({ 'clientid': params['client_id'], 'cmd': 'register', 'roomid': params['room_id'], }) if params['is_initiator'] == 'true': # send offer await pc.setLocalDescription(await pc.createOffer()) await signaling.send_message(description_to_dict(pc.localDescription)) print('Please point a browser at %s' % params['room_link']) # receive 60s of media try: await asyncio.wait_for(consume_signaling(signaling, pc, params), timeout=60) except asyncio.TimeoutError: pass # shutdown print('Shutting down') await signaling.send_message({'type': 'bye'}) for c in consumers: c.cancel() await pc.close()
async def run(pc, player, room, session): await session.create() # configure media media = {"audio": False, "video": True} if player and player.audio: pc.addTrack(player.audio) media["audio"] = True if player and player.video: pc.addTrack(player.video) else: pc.addTrack(VideoStreamTrack()) # join video room plugin = await session.attach("janus.plugin.videoroom") await plugin.send( { "body": { "display": "aiortc", "ptype": "publisher", "request": "join", "room": room, } } ) # send offer await pc.setLocalDescription(await pc.createOffer()) request = {"request": "configure"} request.update(media) response = await plugin.send( { "body": request, "jsep": { "sdp": pc.localDescription.sdp, "trickle": False, "type": pc.localDescription.type, }, } ) # apply answer answer = RTCSessionDescription( sdp=response["jsep"]["sdp"], type=response["jsep"]["type"] ) await pc.setRemoteDescription(answer) # exchange media for 10 minutes print("Exchanging media") await asyncio.sleep(600)
async def trigger_sdp_parsing(self, name='konata', plugin_name='janus.plugin.videocall'): session = JanusSession(self.url, name) await session.create() self.log_success('session created') plugin = await session.attach(plugin_name) self.log_success('attached to {} plugin'.format(plugin_name)) pc = RTCPeerConnection() pc.addTrack(VideoStreamTrack()) await pc.setLocalDescription(await pc.createOffer()) self.log_info( 'trying to trigger null pointer dereference at janus_sdp_process') sdp = '\n'.join([ 'v=-1', 'o=aaaa 0 0 IN IP6 cccc', 's=aaaa', 't=1 2', 'c=IN IP4 dddd', 'a=fingerprint', 'm=audio 1 ffff 0', ]) self.log_info('malicious sdp is crafted') try: self.log_info('sending a malicious offer...') response = await plugin.send({ "body": {}, "jsep": { "sdp": sdp, "type": 'offer' } }) except Exception: self.log_success('null dereference is triggered') sys.exit(0) answer = await session.get_answer() log.info('got answer: {}'.format(answer)) await pc.setRemoteDescription( RTCSessionDescription(sdp=answer["sdp"], type=answer["type"])) await asyncio.sleep(10)
async def run(pc, player, session): await session.create() # configure media media = {'audio': False, 'video': True} if player and player.audio: pc.addTrack(player.audio) media['audio'] = True if player and player.video: pc.addTrack(player.video) else: pc.addTrack(VideoStreamTrack()) # join video room plugin = await session.attach('janus.plugin.videoroom') await plugin.send({ 'body': { 'display': 'aiortc', 'ptype': 'publisher', 'request': 'join', 'room': 1234, } }) # send offer await pc.setLocalDescription(await pc.createOffer()) request = {'request': 'configure'} request.update(media) response = await plugin.send({ 'body': request, 'jsep': { 'sdp': pc.localDescription.sdp, 'trickle': False, 'type': pc.localDescription.type } }) # apply answer answer = RTCSessionDescription( sdp=response['jsep']['sdp'], type=response['jsep']['type']) await pc.setRemoteDescription(answer) # exchange media for 10 minutes print('Exchanging media') await asyncio.sleep(600)
def test_video_mp4(self): path = self.temporary_path('test.mp4') recorder = MediaRecorder(path) recorder.addTrack(VideoStreamTrack()) run(recorder.start()) run(asyncio.sleep(2)) run(recorder.stop()) # check output media container = av.open(path, 'r') self.assertEqual(len(container.streams), 1) self.assertEqual(container.streams[0].codec.name, 'h264') self.assertGreater( float(container.streams[0].duration * container.streams[0].time_base), 0) self.assertEqual(container.streams[0].width, 640) self.assertEqual(container.streams[0].height, 480)
def test_audio_and_video(self): path = self.temporary_path("test.mp4") recorder = MediaRecorder(path) recorder.addTrack(AudioStreamTrack()) recorder.addTrack(VideoStreamTrack()) run(recorder.start()) run(asyncio.sleep(2)) run(recorder.stop()) # check output media container = av.open(path, "r") self.assertEqual(len(container.streams), 2) self.assertEqual(container.streams[0].codec.name, "aac") self.assertGreater( float(container.streams[0].duration * container.streams[0].time_base), 0) self.assertEqual(container.streams[1].codec.name, "h264") self.assertEqual(container.streams[1].width, 640) self.assertEqual(container.streams[1].height, 480) self.assertGreater( float(container.streams[1].duration * container.streams[1].time_base), 0)
def test_video_jpg(self): recorder = MediaRecorder(path='foo-%3d.jpg') recorder.addTrack(VideoStreamTrack()) recorder.start() run(asyncio.sleep(2)) recorder.stop()
from pymediasoup.sctp_parameters import SctpCapabilities, SctpStreamParameters from pymediasoup.transport import Transport from pymediasoup.models.transport import DtlsParameters from pymediasoup.producer import Producer from pymediasoup.data_producer import DataProducer from pymediasoup.data_consumer import DataConsumer from pymediasoup.errors import UnsupportedError from pymediasoup.consumer import Consumer from .fake_parameters import generateRouterRtpCapabilities, generateTransportRemoteParameters, generateConsumerRemoteParameters, generateDataProducerRemoteParameters, generateDataConsumerRemoteParameters from .fake_handler import FakeHandler logging.basicConfig(level=logging.DEBUG) audioTrack = AudioStreamTrack() videoTrack = VideoStreamTrack() TRACKS = [videoTrack, audioTrack] class TestMethods(unittest.IsolatedAsyncioTestCase): def test_create_device(self): device = Device(handlerFactory=AiortcHandler.createFactory( tracks=TRACKS)) self.assertEqual(device.loaded, False) async def test_device_load(self): device = Device(handlerFactory=AiortcHandler.createFactory( tracks=TRACKS)) await device.load(generateRouterRtpCapabilities()) self.assertEqual(device.handlerName, 'aiortc') self.assertTrue(device.loaded)
def test_video(self): track = VideoStreamTrack() self.assertEqual(track.kind, "video") self.assertEqual(len(track.id), 36)
async def publish(self, plugin, player): """ Send video to the room. """ self.connection.turn_server = self.turnservers self.connection.turn_transport = "udp" self.connection.turn_username = self.username self.connection.turn_password = self.password self.connection.remote_username = self.username self.connection.remote_password = self.password # configure media media = {"audio": False, "video": True} if player and player.audio: self.pc.addTrack(player.audio) media["audio"] = True if player and player.video: self.pc.addTrack(player.video) else: self.pc.addTrack(VideoStreamTrack()) await self.connection.gather_candidates() # for c in self.connection.local_candidates: # c.sdpMid = '0' # self.pc.addIceCandidate(c) # send offer offer = await self.pc.createOffer() await self.pc.setLocalDescription(offer) request = {"request": "configure"} request.update(media) message = { "janus": "message", "transaction": self.publish_transaction_id, "session_id": self.session_id, "handle_id": self.handle_id, "token": self.token } payload = { "body": request, "jsep": { "sdp": self.pc.localDescription.sdp, "type": self.pc.localDescription.type, }, } message.update(payload) await self.send(json.dumps(message)) print("getting candidates") for c in self.connection.local_candidates: data = { "janus": "trickle", "candidate": { "candidate": "candidate:" + aioice.Candidate.to_sdp(c), "sdpMid": "0", "sdpMLineIndex": 0 }, "transaction": transaction_id(), "token": self.token, "session_id": self.session_id, "handle_id": self.handle_id } await self.send(json.dumps(data)) completed = { "janus": "trickle", "candidate": { "completed": True }, "transaction": self.candidates_complete, "token": self.token, "session_id": self.session_id, "handle_id": self.handle_id } await self.send(json.dumps(completed)) configure = { "janus": "message", "body": request, "transaction": self.message_id, "token": self.token, "session_id": self.session_id, "handle_id": self.handle_id } await self.send(json.dumps(configure))
async def run(pc, player, recorder, room, session): await session.create() # configure media media = {"audio": False, "video": True} if player and player.audio: pc.addTrack(player.audio) if player and player.video: pc.addTrack(player.video) else: pc.addTrack(VideoStreamTrack()) # join video room plugin = await session.attach("janus.plugin.videoroom") videoroom_response = await plugin.send( { "body": { "display": "aiortc", "ptype": "publisher", "request": "join", "room": room, } } ) # find out who else is in the room? publishers = videoroom_response['plugindata']['data']['publishers'] for publisher in publishers: remote_id = publisher['id'] remote_name = publisher['display'] print('remote_id:', remote_id, 'name:', remote_name) # send offer await pc.setLocalDescription(await pc.createOffer()) request = {"request": "configure"} request.update(media) response = await plugin.send( { "body": request, "jsep": { "sdp": pc.localDescription.sdp, "trickle": False, "type": pc.localDescription.type, }, } ) # apply answer answer = RTCSessionDescription( sdp=response["jsep"]["sdp"], type=response["jsep"]["type"] ) await pc.setRemoteDescription(answer) # start recording from 1st remote_id participant if publishers != []: await subscribe(publishers[0]["id"], room, recorder, session) # exchange media for 10 minutes print("Exchanging media") await asyncio.sleep(600) print("--Stopped 10 minutes limit--")
async def create_target_user_and_accept(self, targetname): session = JanusSession(self.url, targetname) await session.create() self.log_success('[targetuser] : session created') plugin = await session.attach(self.plugin_name) self.log_success('[targetuser] : attached to {} plugin'.format( self.plugin_name)) response = await plugin.send( {"body": { "request": "register", "username": targetname }}) self.log_success('[targetuser] : registered') pc = RTCPeerConnection() pc.addTrack(VideoStreamTrack()) offer = await session.get_offer() # self.log_info("[targetuser] : got offer: {}".format(offer)) await pc.setRemoteDescription( RTCSessionDescription(sdp=offer["sdp"], type=offer["type"])) self.log_info('[targetuser] : remote description is ready') await pc.setLocalDescription(await pc.createAnswer()) self.log_info('[targetuser]: answer created') sdp = '\n'.join([ "v=0", "o=mozilla...THIS_IS_SDPARTA-74.0 2447000379536746271 0 IN IP4 0.0.0.0", "s=-", "t=0 0", "a=fingerprint:sha-256 9A:9C:0E:72:47:18:43:2D:A6:61:17:94:53:73:E0:6A:D5:99:F3:8C:D5:F4:DE:0C:BA:94:61:98:4C:FC:AD:02", "m=video 9 UDP/TLS/RTP/SAVPF 120 121 126 97", "c=IN IP4 0.0.0.0", "a=sendrecv", "a=ice-pwd:0b5a4e0345d7490bf75350794acb07d6", "a=ice-ufrag:79a8384b", "a=mid:1234", "a=rtpmap:120 VP8/90000", "a=rtpmap:121 VP9/90000", "a=rtpmap:126 H264/90000", "a=rtpmap:97 H264/90000", "m=application 9 UDP/DTLS/SCTP webrtc-datachannel", "a=mid:{}".format(self.payload), "m=application 9 JUNKJUNK webrtc-datachann", "a=mid:4567", "m=application 9 JUNKJUNK webrtc-datachann", "a=mid:4567", "m=application 9 JUNKJUNK webrtc-datachann", "a=mid:4567", "m=application 9 JUNKJUNK webrtc-datachann", "a=mid:4567\n", ]) try: self.log_info('[targetuser] : sending answer back...') response = await plugin.send({ "body": { "request": "accept" }, "jsep": { "sdp": sdp, "type": pc.localDescription.type } }) await asyncio.sleep(10) except Exception: self.log_success('[targetuser] : bof is triggered')
def test_video_png(self): recorder = MediaRecorder(self.temporary_path('test-%3d.png')) recorder.addTrack(VideoStreamTrack()) run(recorder.start()) run(asyncio.sleep(2)) run(recorder.stop())