package sdp
import (
"fmt"
"net/url"
"strconv"
"time"
)
const (
AttrKeyCandidate = "candidate"
AttrKeyEndOfCandidates = "end-of-candidates"
AttrKeyIdentity = "identity"
AttrKeyGroup = "group"
AttrKeySSRC = "ssrc"
AttrKeySSRCGroup = "ssrc-group"
AttrKeyMsid = "msid"
AttrKeyMsidSemantic = "msid-semantic"
AttrKeyConnectionSetup = "setup"
AttrKeyMID = "mid"
AttrKeyICELite = "ice-lite"
AttrKeyICEOptions = "ice-options"
AttrKeyRTCPMux = "rtcp-mux"
AttrKeyRTCPRsize = "rtcp-rsize"
AttrKeyInactive = "inactive"
AttrKeyRecvOnly = "recvonly"
AttrKeySendOnly = "sendonly"
AttrKeySendRecv = "sendrecv"
AttrKeyExtMap = "extmap"
AttrKeyExtMapAllowMixed = "extmap-allow-mixed"
)
const (
SemanticTokenLipSynchronization = "LS"
SemanticTokenFlowIdentification = "FID"
SemanticTokenForwardErrorCorrection = "FEC"
SemanticTokenForwardErrorCorrectionFramework = "FEC-FR"
SemanticTokenWebRTCMediaStreams = "WMS"
)
const (
ExtMapValueTransportCC = 3
)
func extMapURI() map [int ]string {
return map [int ]string {
ExtMapValueTransportCC : "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01" ,
}
}
func NewJSEPSessionDescription (identity bool ) (*SessionDescription , error ) {
sid , err := newSessionID ()
if err != nil {
return nil , err
}
descr := &SessionDescription {
Version : 0 ,
Origin : Origin {
Username : "-" ,
SessionID : sid ,
SessionVersion : uint64 (time .Now ().Unix ()),
NetworkType : "IN" ,
AddressType : "IP4" ,
UnicastAddress : "0.0.0.0" ,
},
SessionName : "-" ,
TimeDescriptions : []TimeDescription {
{
Timing : Timing {
StartTime : 0 ,
StopTime : 0 ,
},
RepeatTimes : nil ,
},
},
Attributes : []Attribute {
},
}
if identity {
descr .WithPropertyAttribute (AttrKeyIdentity )
}
return descr , nil
}
func (s *SessionDescription ) WithPropertyAttribute (key string ) *SessionDescription {
s .Attributes = append (s .Attributes , NewPropertyAttribute (key ))
return s
}
func (s *SessionDescription ) WithValueAttribute (key , value string ) *SessionDescription {
s .Attributes = append (s .Attributes , NewAttribute (key , value ))
return s
}
func (s *SessionDescription ) WithICETrickleAdvertised () *SessionDescription {
return s .WithValueAttribute (AttrKeyICEOptions , "trickle" )
}
func (s *SessionDescription ) WithFingerprint (algorithm , value string ) *SessionDescription {
return s .WithValueAttribute ("fingerprint" , algorithm +" " +value )
}
func (s *SessionDescription ) WithMedia (md *MediaDescription ) *SessionDescription {
s .MediaDescriptions = append (s .MediaDescriptions , md )
return s
}
func NewJSEPMediaDescription (codecType string , _ []string ) *MediaDescription {
return &MediaDescription {
MediaName : MediaName {
Media : codecType ,
Port : RangedPort {Value : 9 },
Protos : []string {"UDP" , "TLS" , "RTP" , "SAVPF" },
},
ConnectionInformation : &ConnectionInformation {
NetworkType : "IN" ,
AddressType : "IP4" ,
Address : &Address {
Address : "0.0.0.0" ,
},
},
}
}
func (d *MediaDescription ) WithPropertyAttribute (key string ) *MediaDescription {
d .Attributes = append (d .Attributes , NewPropertyAttribute (key ))
return d
}
func (d *MediaDescription ) WithValueAttribute (key , value string ) *MediaDescription {
d .Attributes = append (d .Attributes , NewAttribute (key , value ))
return d
}
func (d *MediaDescription ) WithFingerprint (algorithm , value string ) *MediaDescription {
return d .WithValueAttribute ("fingerprint" , algorithm +" " +value )
}
func (d *MediaDescription ) WithICECredentials (username , password string ) *MediaDescription {
return d .
WithValueAttribute ("ice-ufrag" , username ).
WithValueAttribute ("ice-pwd" , password )
}
func (d *MediaDescription ) WithCodec (
payloadType uint8 ,
name string ,
clockrate uint32 ,
channels uint16 ,
fmtp string ,
) *MediaDescription {
d .MediaName .Formats = append (d .MediaName .Formats , strconv .Itoa (int (payloadType )))
rtpmap := fmt .Sprintf ("%d %s/%d" , payloadType , name , clockrate )
if channels > 0 {
rtpmap += fmt .Sprintf ("/%d" , channels )
}
d .WithValueAttribute ("rtpmap" , rtpmap )
if fmtp != "" {
d .WithValueAttribute ("fmtp" , fmt .Sprintf ("%d %s" , payloadType , fmtp ))
}
return d
}
func (d *MediaDescription ) WithMediaSource (ssrc uint32 , cname , streamLabel , label string ) *MediaDescription {
return d .
WithValueAttribute ("ssrc" , fmt .Sprintf ("%d cname:%s" , ssrc , cname )).
WithValueAttribute ("ssrc" , fmt .Sprintf ("%d msid:%s %s" , ssrc , streamLabel , label )).
WithValueAttribute ("ssrc" , fmt .Sprintf ("%d mslabel:%s" , ssrc , streamLabel )).
WithValueAttribute ("ssrc" , fmt .Sprintf ("%d label:%s" , ssrc , label ))
}
func (d *MediaDescription ) WithCandidate (value string ) *MediaDescription {
return d .WithValueAttribute ("candidate" , value )
}
func (d *MediaDescription ) WithExtMap (e ExtMap ) *MediaDescription {
return d .WithPropertyAttribute (e .Marshal ())
}
func (d *MediaDescription ) WithTransportCCExtMap () *MediaDescription {
uri , _ := url .Parse (extMapURI ()[ExtMapValueTransportCC ])
e := ExtMap {
Value : ExtMapValueTransportCC ,
URI : uri ,
}
return d .WithExtMap (e )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .