async def test_rtp_unknown_payload_type(self): async with create_receiver("video") as receiver: receiver._track = RemoteStreamTrack(kind="video") await receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC])) # receive RTP with unknown payload type packet = RtpPacket(payload_type=123) await receiver._handle_rtp_packet(packet, arrival_time_ms=0)
def test_rtp_and_rtcp(self): receiver = RTCRtpReceiver("audio", self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind="audio") self.assertEqual(receiver._track.readyState, "live") run(receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC]))) # receive RTP for i in range(10): packet = RtpPacket.parse(load("rtp.bin")) packet.sequence_number += i packet.timestamp += i * 160 run(receiver._handle_rtp_packet(packet, arrival_time_ms=i * 20)) # receive RTCP SR for packet in RtcpPacket.parse(load("rtcp_sr.bin")): run(receiver._handle_rtcp_packet(packet)) # check stats report = run(receiver.getStats()) self.assertTrue(isinstance(report, RTCStatsReport)) self.assertEqual( sorted([s.type for s in report.values()]), ["inbound-rtp", "remote-outbound-rtp", "transport"], ) # check sources sources = receiver.getSynchronizationSources() self.assertEqual(len(sources), 1) self.assertTrue(isinstance(sources[0], RTCRtpSynchronizationSource)) self.assertEqual(sources[0].source, 4028317929) # check remote track frame = run(receiver._track.recv()) self.assertEqual(frame.pts, 0) self.assertEqual(frame.sample_rate, 8000) self.assertEqual(frame.time_base, fractions.Fraction(1, 8000)) frame = run(receiver._track.recv()) self.assertEqual(frame.pts, 160) self.assertEqual(frame.sample_rate, 8000) self.assertEqual(frame.time_base, fractions.Fraction(1, 8000)) # shutdown run(receiver.stop()) # read until end with self.assertRaises(MediaStreamError): while True: run(receiver._track.recv()) self.assertEqual(receiver._track.readyState, "ended") # try reading again with self.assertRaises(MediaStreamError): run(receiver._track.recv())
def test_send_rtcp_nack(self): receiver = RTCRtpReceiver("video", self.local_transport) receiver._set_rtcp_ssrc(1234) receiver._track = RemoteStreamTrack(kind="video") run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC]))) # send RTCP feedback NACK run(receiver._send_rtcp_nack(5678, [7654])) # shutdown run(receiver.stop())
def test_send_rtcp_pli(self): receiver = RTCRtpReceiver('video', self.local_transport) receiver._set_rtcp_ssrc(1234) receiver._track = RemoteStreamTrack(kind='video') run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC]))) # send RTCP feedback PLI run(receiver._send_rtcp_pli(5678)) # shutdown run(receiver.stop())
def test_rtp_unknown_payload_type(self): receiver = RTCRtpReceiver('video', self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind='video') run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC]))) # receive RTP with unknown payload type packet = RtpPacket(payload_type=123) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # shutdown run(receiver.stop())
def test_rtp_empty_video_packet(self): receiver = RTCRtpReceiver("video", self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind="video") run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC]))) # receive RTP with empty payload packet = RtpPacket(payload_type=100) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # shutdown run(receiver.stop())
def test_rtp_and_rtcp(self): receiver = RTCRtpReceiver('audio', self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind='audio') self.assertEqual(receiver._track.readyState, 'live') run(receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC]))) # receive RTP for i in range(10): packet = RtpPacket.parse(load('rtp.bin')) packet.sequence_number += i packet.timestamp += i * 160 run(receiver._handle_rtp_packet(packet, arrival_time_ms=i * 20)) # receive RTCP SR for packet in RtcpPacket.parse(load('rtcp_sr.bin')): run(receiver._handle_rtcp_packet(packet)) # check stats report = run(receiver.getStats()) self.assertTrue(isinstance(report, RTCStatsReport)) self.assertEqual( sorted([s.type for s in report.values()]), ['inbound-rtp', 'remote-outbound-rtp', 'transport']) # check remote track frame = run(receiver._track.recv()) self.assertEqual(frame.pts, 0) self.assertEqual(frame.sample_rate, 8000) self.assertEqual(frame.time_base, fractions.Fraction(1, 8000)) frame = run(receiver._track.recv()) self.assertEqual(frame.pts, 160) self.assertEqual(frame.sample_rate, 8000) self.assertEqual(frame.time_base, fractions.Fraction(1, 8000)) # shutdown run(receiver.stop()) # read until end with self.assertRaises(MediaStreamError): while True: run(receiver._track.recv()) self.assertEqual(receiver._track.readyState, 'ended') # try reading again with self.assertRaises(MediaStreamError): run(receiver._track.recv())
def test_send_rtcp_pli(self): receiver = RTCRtpReceiver('video', self.local_transport) receiver._set_rtcp_ssrc(1234) receiver._track = RemoteStreamTrack(kind='video') run( receiver.receive( RTCRtpReceiveParameters(codecs=[ RTCRtpCodecParameters( name='VP8', clockRate=90000, payloadType=100), ]))) # send RTCP feedback PLI run(receiver._send_rtcp_pli(5678)) # shutdown run(receiver.stop())
def test_rtp_rtx_unknown_ssrc(self): receiver = RTCRtpReceiver('video', self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind='video') run(receiver.receive(RTCRtpReceiveParameters( codecs=[ RTCRtpCodecParameters(name='VP8', clockRate=90000, payloadType=100), RTCRtpCodecParameters(name='rtx', clockRate=90000, payloadType=101, parameters={'apt': 100}), ]))) # receive RTX with unknown SSRC packet = RtpPacket(payload_type=101, ssrc=1234) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # shutdown run(receiver.stop())
def test_rtp_empty_video_packet(self): receiver = RTCRtpReceiver('video', self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind='video') run( receiver.receive( RTCRtpReceiveParameters(codecs=[ RTCRtpCodecParameters( name='VP8', clockRate=90000, payloadType=100), ]))) # receive RTP with empty payload packet = RtpPacket(payload_type=100) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # shutdown run(receiver.stop())
async def test_connection_error(self): """ Close the underlying transport before the receiver. """ async with create_receiver("audio") as receiver: receiver._track = RemoteStreamTrack(kind="audio") receiver._set_rtcp_ssrc(1234) await receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC])) # receive a packet to prime RTCP packet = RtpPacket.parse(load("rtp.bin")) await receiver._handle_rtp_packet(packet, arrival_time_ms=0) # break connection await receiver.transport.stop() # give RTCP time to send a report await asyncio.sleep(2)
async def test_rtp_rtx_unknown_ssrc(self): async with create_receiver("video") as receiver: receiver._track = RemoteStreamTrack(kind="video") await receiver.receive( RTCRtpReceiveParameters( codecs=[ VP8_CODEC, RTCRtpCodecParameters( mimeType="video/rtx", clockRate=90000, payloadType=101, parameters={"apt": 100}, ), ] ) ) # receive RTX with unknown SSRC packet = RtpPacket(payload_type=101, ssrc=1234) await receiver._handle_rtp_packet(packet, arrival_time_ms=0)
def test_rtp_rtx(self): receiver = RTCRtpReceiver("video", self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind="video") run( receiver.receive( RTCRtpReceiveParameters( codecs=[ VP8_CODEC, RTCRtpCodecParameters( mimeType="video/rtx", clockRate=90000, payloadType=101, parameters={"apt": 100}, ), ], encodings=[ RTCRtpEncodingParameters( ssrc=1234, payloadType=100, rtx=RTCRtpRtxParameters(ssrc=2345), ) ], ) ) ) # receive RTX with payload packet = RtpPacket(payload_type=101, ssrc=2345, payload=b"\x00\x00") run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # receive RTX without payload packet = RtpPacket(payload_type=101, ssrc=2345) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # shutdown run(receiver.stop())
def test_connection_error(self): """ Close the underlying transport before the receiver. """ receiver = RTCRtpReceiver('audio', self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind='audio') receiver._set_rtcp_ssrc(1234) run(receiver.receive(RTCRtpReceiveParameters(codecs=[PCMU_CODEC]))) # receive a packet to prime RTCP packet = RtpPacket.parse(load('rtp.bin')) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # break connection run(self.local_transport.stop()) # give RTCP time to send a report run(asyncio.sleep(2)) # shutdown run(receiver.stop())
def test_rtp_rtx_unknown_ssrc(self): receiver = RTCRtpReceiver("video", self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._track = RemoteStreamTrack(kind="video") run( receiver.receive( RTCRtpReceiveParameters(codecs=[ VP8_CODEC, RTCRtpCodecParameters( mimeType="video/rtx", clockRate=90000, payloadType=101, parameters={"apt": 100}, ), ]))) # receive RTX with unknown SSRC packet = RtpPacket(payload_type=101, ssrc=1234) run(receiver._handle_rtp_packet(packet, arrival_time_ms=0)) # shutdown run(receiver.stop())
def test_rtp_missing_video_packet(self): nacks = [] pli = [] async def mock_send_rtcp_nack(*args): nacks.append(args) async def mock_send_rtcp_pli(*args): pli.append(args[0]) receiver = RTCRtpReceiver("video", self.local_transport) self.assertEqual(receiver.transport, self.local_transport) receiver._send_rtcp_nack = mock_send_rtcp_nack receiver._send_rtcp_pli = mock_send_rtcp_pli receiver._track = RemoteStreamTrack(kind="video") run(receiver.receive(RTCRtpReceiveParameters(codecs=[VP8_CODEC]))) # generate some packets packets = create_rtp_video_packets(self, codec=VP8_CODEC, frames=129) # receive RTP with a with a gap run(receiver._handle_rtp_packet(packets[0], arrival_time_ms=0)) run(receiver._handle_rtp_packet(packets[128], arrival_time_ms=0)) # check NACK was triggered lost_packets = [] for i in range(127): lost_packets.append(i + 1) self.assertEqual(nacks[0], (1234, lost_packets)) # check PLI was triggered self.assertEqual(pli, [1234]) # shutdown run(receiver.stop())
def test_rtp(self): transport1, transport2 = dummy_ice_transport_pair() certificate1 = RTCCertificate.generateCertificate() session1 = RTCDtlsTransport(transport1, [certificate1]) receiver1 = DummyRtpReceiver() session1._register_rtp_receiver( receiver1, RTCRtpReceiveParameters( codecs=[ RTCRtpCodecParameters( mimeType="audio/PCMU", clockRate=8000, payloadType=0 ) ], encodings=[RTCRtpDecodingParameters(ssrc=1831097322, payloadType=0)], ), ) certificate2 = RTCCertificate.generateCertificate() session2 = RTCDtlsTransport(transport2, [certificate2]) receiver2 = DummyRtpReceiver() session2._register_rtp_receiver( receiver2, RTCRtpReceiveParameters( codecs=[ RTCRtpCodecParameters( mimeType="audio/PCMU", clockRate=8000, payloadType=0 ) ], encodings=[RTCRtpDecodingParameters(ssrc=4028317929, payloadType=0)], ), ) run( asyncio.gather( session1.start(session2.getLocalParameters()), session2.start(session1.getLocalParameters()), ) ) self.assertCounters(session1, session2, 2, 2) # send RTP run(session1._send_rtp(RTP)) run(asyncio.sleep(0.1)) self.assertCounters(session1, session2, 3, 2) self.assertEqual(len(receiver2.rtcp_packets), 0) self.assertEqual(len(receiver2.rtp_packets), 1) # send RTCP run(session2._send_rtp(RTCP)) run(asyncio.sleep(0.1)) self.assertCounters(session1, session2, 3, 3) self.assertEqual(len(receiver1.rtcp_packets), 1) self.assertEqual(len(receiver1.rtp_packets), 0) # shutdown run(session1.stop()) run(asyncio.sleep(0.1)) self.assertCounters(session1, session2, 4, 3) self.assertEqual(session1.state, "closed") self.assertEqual(session2.state, "closed") # try closing again run(session1.stop()) run(session2.stop()) # try sending after close with self.assertRaises(ConnectionError): run(session1._send_rtp(RTP))