def __set_attribute(self, value): assert type(value) is str if self.__attribute is None: self.__attribute = Attribute("mid", RawMid(value)) self.__attribute.appendTo(self.__attributes) else: self.__attribute.value.value = value
def __set_packet_time(self, packet_time): assert type(packet_time) is int if self.__ptime_attribute is not None: self.__ptime_attribute.value.packet_time = packet_time else: self.__ptime_attribute = Attribute("ptime", PtimeValue(packet_time)) self.__attributes.append(self.__ptime_attribute)
def __add_attribute(self, port, nettype=None, addrtype=None, connection_address=None): assert self.__rtcp_attribute is None assert type(port) is int self.__rtcp_attribute = Attribute( "rtcp", RtcpAttribute(port, nettype, addrtype, connection_address)) self.__attributes.append(self.__rtcp_attribute)
class Rtcp(object): """ RFC 3605 (http://www.rfc-editor.org/rfc/rfc3605.txt) Real Time Control Protocol (RTCP) attribute in Session Description Protocol (SDP) """ def __init__(self, attributes): assert type(attributes) is AttributeCollection self.__attributes = attributes rtcps = attributes.get("rtcp") assert len(rtcps) < 2 self.__rtcp_attribute = rtcps[0] if len(rtcps) == 1 else None def __nonzero__(self): return self.__rtcp_attribute is not None @property def port(self): return self.__rtcp_attribute.value.port if self.__rtcp_attribute else None @port.setter def port(self, port): assert type(port) is int if self.__rtcp_attribute is not None: self.__rtcp_attribute.value.port = port else: self.__add_attribute(port) @property def connection_address(self): return self.__rtcp_attribute.value.connection_address if self.__rtcp_attribute else None @connection_address.setter def connection_address(self, connection_address): assert type(connection_address) is str if self.__rtcp_attribute is not None: self.__rtcp_attribute.value.connection_address = connection_address else: self.__add_attribute(0, NetType.IN, AddrType.IP4, connection_address) def __add_attribute(self, port, nettype=None, addrtype=None, connection_address=None): assert self.__rtcp_attribute is None assert type(port) is int self.__rtcp_attribute = Attribute( "rtcp", RtcpAttribute(port, nettype, addrtype, connection_address)) self.__attributes.append(self.__rtcp_attribute) def __remove_attribute(self): assert self.__rtcp_attribute is not None self.__rtcp_attribute.remove() self.__rtcp_attribute = None
def test_init(self): rtpmap96 = Attribute("rtpmap", RtpmapValue(96, "VP8", 90000, 1)) fmtp96 = Attribute("fmtp", FmtpValue(96, "0-16")) rtcp_mux_attr = Attribute("rtcp-mux", RtcpMuxAttribute()) attributes = AttributeCollection([rtpmap96, fmtp96, rtcp_mux_attr]) rtcp_mux = RtcpMux(attributes) self.failUnlessEqual(rtcp_mux.value, True) attributes = AttributeCollection([rtpmap96, fmtp96]) rtcp_mux = RtcpMux(attributes) self.failUnlessEqual(rtcp_mux.value, False)
def test_modify(self): rtpmap96 = Attribute("rtpmap", RtpmapValue(96, "VP8", 90000, 1)) fmtp96 = Attribute("fmtp", FmtpValue(96, "0-16")) rtcp_mux_attr = Attribute("rtcp-mux", RtcpMuxAttribute()) attributes = AttributeCollection([rtpmap96, rtcp_mux_attr, fmtp96]) rtcp_mux = RtcpMux(attributes) rtcp_mux.value = False self.failUnlessEqual(rtcp_mux.value, False) self.failUnlessEqual(list(attributes), [rtpmap96, fmtp96]) rtcp_mux.value = True self.failUnlessEqual(rtcp_mux.value, True) self.failUnlessEqual(type(attributes[2].value), RtcpMuxAttribute)
def add_codec(self, codec): """ :param codec: Codec """ assert type(codec) is Codec known_codecs = [rtp_codec for rtp_codec in KNOWN_RTP_CODECS if rtp_codec.base_codec == codec] if len(known_codecs): rtp_codec = known_codecs[0].clone() else: payload_types = list(DYNAMIC_PT) for rtp_codec in self.__rtp_codecs: if rtp_codec.payload_type in payload_types: payload_types.remove(rtp_codec.payload_type) # TODO: throw exception assert len(payload_types) > 0 payload_type = payload_types[0] rtp_codec = RtpCodec(codec, payload_type) rtpmap = Attribute("rtpmap", RtpmapValue(payload_type=payload_type, encoding_name=codec.encoding_name, clock_rate=codec.clock_rate, channels=codec.channels if codec.channels != 1 else None)) # add rtpmap attribute self.__raw_media.attributes.append(rtpmap) # add payload_type self.__rtp_codecs.append(rtp_codec) self.payload_types.append(rtp_codec.payload_type)
def test_modify(self): attributes = AttributeCollection([ Attribute("rtpmap", RtpmapValue(96, "VP8", 90000, 1)), Attribute("fmtp", FmtpValue(96, "0-16")) ]) rtcp = Rtcp(attributes) self.failIf(bool(rtcp)) self.failUnlessEqual(rtcp.port, None) self.failUnlessEqual(rtcp.connection_address, None) rtcp.port = 9999 self.failUnless(bool(rtcp)) self.failUnlessEqual(rtcp.port, 9999) self.failUnlessEqual(rtcp.connection_address, None) self.failUnlessEqual(str(attributes[2]), "rtcp:9999") rtcp.connection_address = "127.0.0.1" self.failUnlessEqual(str(attributes[2]), "rtcp:9999 IN IP4 127.0.0.1")
def generate_AES_CM_128_HMAC_SHA1_80(self): if self.__attribute is None: value = CryptoValue( 1, SrtpCryptoSuite.AES_CM_128_HMAC_SHA1_80, CryptoKeyParams.with_key( "DOUXfgs9sLB4F16vvCksVKUptM7IptAStkjNS7ky")) self.__attribute = Attribute("crypto", value) self.__attributes.append(self.__attribute) #TODO: write tests
def test_init_1(self): attributes = AttributeCollection([Attribute("mid", RawMid("mid-value"))]) mid = Mid(attributes) self.failUnlessEqual(len(attributes), 1) self.failUnlessEqual(str(attributes), "a=mid:mid-value\r\n") self.failUnlessEqual(mid.value, "mid-value") self.failUnlessEqual(bool(mid), True) mid.value = None self.failUnlessEqual(len(attributes), 0) self.failUnlessEqual(str(attributes), "\r\n") self.failUnlessEqual(mid.value, None) self.failUnlessEqual(bool(mid), False)
def value(self, direction): assert type(direction) is _SdpDirectionValue new_attribute = None if direction == SdpDirection.SEND_RECV: new_attribute = Attribute("sendrecv", SendRecvValue()) elif direction == SdpDirection.RECV_ONLY: new_attribute = Attribute("recvonly", RecvOnlyValue()) elif direction == SdpDirection.SEND_ONLY: new_attribute = Attribute("sendonly", SendOnlyValue()) elif direction == SdpDirection.INACTIVE: new_attribute = Attribute("inactive", InactiveValue()) assert new_attribute is not None if self.__attribute: self.__attribute.after(new_attribute) self.__attribute.remove() self.__attribute = new_attribute else: self.__attributes.append(new_attribute) self.__attribute = new_attribute
def generate(self, ssrc_id=None, cname=None, stream_id=None, track_id=None, media_type=None): """ TODO: this method is wrong and works only for one case - zero streams """ assert ssrc_id is None or type(ssrc_id) is long assert cname is None or type(cname) is str assert stream_id is None or type(stream_id) is str assert track_id is None or type(track_id) is str if ssrc_id is None: ssrc_id = 1111L if cname is None: cname = "d7K1+bIOxM3hwrLB" if stream_id is None: stream_id = "OiLq8LkWFcq3I7yJSQOsSNpvHo8P4vZ3LT7K" if track_id is None: track_id = stream_id + "v0" if media_type is MediaType.VIDEO else stream_id + "a0" stream_label = stream_id track_label = track_id cname_attribute = Attribute("ssrc", SsrcValue(ssrc_id, "cname", cname)) msid_attribute = Attribute( "ssrc", SsrcValue(ssrc_id, "msid", stream_id + " " + track_id)) mslabel_attribute = Attribute( "ssrc", SsrcValue(ssrc_id, "mslabel", stream_label)) label_attribute = Attribute("ssrc", SsrcValue(ssrc_id, "label", track_label)) self.__attributes.append(cname_attribute) self.__attributes.append(msid_attribute) self.__attributes.append(mslabel_attribute) self.__attributes.append(label_attribute) stream = Stream(ssrc_id, cname_attribute, msid_attribute, mslabel_attribute, label_attribute) self.__streams.append(stream)
def test_init(self): attributes = AttributeCollection([ Attribute("rtpmap", RtpmapValue(96, "VP8", 90000, 1)), Attribute("fmtp", FmtpValue(96, "0-16")), Attribute("rtcp", RtcpAttribute(9999)) ]) rtcp = Rtcp(attributes) self.failUnless(bool(rtcp)) self.failUnlessEqual(rtcp.port, 9999) self.failUnlessEqual(rtcp.connection_address, None) attributes = AttributeCollection([ Attribute("rtpmap", RtpmapValue(96, "VP8", 90000, 1)), Attribute("fmtp", FmtpValue(96, "0-16")), Attribute( "rtcp", RtcpAttribute(9999, NetType.IN, AddrType.IP4, "127.0.0.1")) ]) rtcp = Rtcp(attributes) self.failUnless(bool(rtcp)) self.failUnlessEqual(rtcp.port, 9999) self.failUnlessEqual(rtcp.connection_address, "127.0.0.1") attributes = AttributeCollection([]) rtcp = Rtcp(attributes) self.failIf(bool(rtcp)) self.failUnlessEqual(rtcp.port, None) self.failUnlessEqual(rtcp.connection_address, None)
def test_init(self): attributes = AttributeCollection() direction = Direction(attributes) self.failUnlessEqual(direction.value, SdpDirection.SEND_RECV) self.failUnlessEqual(len(attributes), 0) a = get_attrs() self.failUnlessRaises( SemanticError, Direction, AttributeCollection([a["sendrecv"], a["sendonly"]])) self.failUnlessRaises( SemanticError, Direction, AttributeCollection([a["sendrecv"], a["sendrecv"]])) attr0 = Attribute("fmtp", FmtpValue(99, "0-15")) attr2 = Attribute("ptime", PtimeValue(20)) attributes = AttributeCollection([attr0, a["sendonly"], attr2]) direction = Direction(attributes) self.failUnlessEqual(direction.value, SdpDirection.SEND_ONLY) direction.value = SdpDirection.INACTIVE self.failUnlessEqual(direction.value, SdpDirection.INACTIVE) self.failUnlessEqual(attributes[0], attr0) self.failUnlessEqual(attributes[2], attr2)
class Ptime(object): def __init__(self, attributes): assert type(attributes) is AttributeCollection self.__attributes = attributes ptimes = attributes.get("ptime") assert len(ptimes) < 2 self.__ptime_attribute = ptimes[0] if len(ptimes) == 1 else None def __nonzero__(self): return self.__ptime_attribute is not None @property def packet_time(self): return self.__ptime_attribute.value.packet_time if self.__ptime_attribute else None @packet_time.setter def packet_time(self, packet_time): assert packet_time is None or type(packet_time) is int if packet_time is not None: self.__set_packet_time(packet_time) else: self.__remove_packet_time() def __set_packet_time(self, packet_time): assert type(packet_time) is int if self.__ptime_attribute is not None: self.__ptime_attribute.value.packet_time = packet_time else: self.__ptime_attribute = Attribute("ptime", PtimeValue(packet_time)) self.__attributes.append(self.__ptime_attribute) def __remove_packet_time(self): if self.__ptime_attribute is not None: self.__ptime_attribute.remove() self.__ptime_attribute = None
class Mid(object): def __init__(self, attributes): assert type(attributes) is AttributeCollection self.__attributes = attributes mids = self.__attributes.get("mid") if len(mids) > 1: raise SemanticError("More than one mid attribute") self.__attribute = mids[0] if len(mids) == 1 else None @property def value(self): return self.__attribute.value.value if self.__attribute else None @value.setter def value(self, value): assert value is None or type(value) is str if value is not None: self.__set_attribute(value) else: self.__remove_attribute() def __nonzero__(self): return self.value is not None def __set_attribute(self, value): assert type(value) is str if self.__attribute is None: self.__attribute = Attribute("mid", RawMid(value)) self.__attribute.appendTo(self.__attributes) else: self.__attribute.value.value = value def __remove_attribute(self): if self.__attribute is not None: self.__attribute.remove() self.__attribute = None
class RtcpMux(object): """ RFC 5761 Multiplexing RTP Data and Control Packets on a Single Port """ def __init__(self, attributes): assert type(attributes) is AttributeCollection self.__attributes = attributes rtcpmuxs = attributes.get("rtcp-mux") assert len(rtcpmuxs) < 2 self.__rtcpmux_attribute = rtcpmuxs[0] if len(rtcpmuxs) == 1 else None def __nonzero__(self): return self.value @property def value(self): return self.__rtcpmux_attribute is not None @value.setter def value(self, value): assert type(value) is bool if self.__rtcpmux_attribute is None and value: self.__add_attribute() elif self.__rtcpmux_attribute is not None and not value: self.__remove_attribute() def __add_attribute(self): assert self.__rtcpmux_attribute is None self.__rtcpmux_attribute = Attribute("rtcp-mux", RtcpMuxAttribute()) self.__attributes.append(self.__rtcpmux_attribute) def __remove_attribute(self): assert self.__rtcpmux_attribute is not None self.__rtcpmux_attribute.remove() self.__rtcpmux_attribute = None
def __set_attribute(self, silence_supp_enable=False, silence_timer=None, supp_pref=None, sid_use=None, fxnslevel=None): if self.__silence_supp_attribute is not None: self.__silence_supp_attribute.value.silence_supp_enable = silence_supp_enable self.__silence_supp_attribute.value.silence_timer = silence_timer self.__silence_supp_attribute.value.supp_pref = supp_pref self.__silence_supp_attribute.value.sid_use = sid_use self.__silence_supp_attribute.value.fxnslevel = fxnslevel else: self.__silence_supp_attribute = Attribute( "silenceSupp", SilenceSuppValue(silence_supp_enable, silence_timer, supp_pref, sid_use, fxnslevel)) self.__attributes.append(self.__silence_supp_attribute)
def get_attrs(): return dict(sendrecv=Attribute("sendrecv", SendRecvValue()), recvonly=Attribute("recvonly", RecvOnlyValue()), sendonly=Attribute("sendonly", SendOnlyValue()), inactive=Attribute("inactive", InactiveValue()))
def __add_attribute(self, semantics): mids = self.__get_mids() if self.__attribute is None: self.__attribute = Attribute("group", RawGroup(semantics, mids)) self.__sdp.raw_sdp.attributes.append(self.__attribute)
def __add_attribute(self): assert self.__rtcpmux_attribute is None self.__rtcpmux_attribute = Attribute("rtcp-mux", RtcpMuxAttribute()) self.__attributes.append(self.__rtcpmux_attribute)