modulepackage
0.0.0-20230222042824-0e2993686387
Repository: https://github.com/transtone/sdp.git
Documentation: pkg.go.dev
# README
SDP
Package sdp implements SDP: Session Description Protocol [RFC4566]. Complies to gortc principles as core package.
Examples
See examples folder.
Also there is online SDP example that gets
RTCPeerConnection.localDescription.sdp
using WebRTC,
sends it to server, decodes as sdp.Session
and renders it on web page.
SDP example:
v=0
o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
s=SDP Seminar
i=A Seminar on the session description protocol
u=http://www.example.com/seminars/sdp.pdf
[email protected] (Jane Doe)
p=12345
c=IN IP4 224.2.17.12/127
b=CT:154798
t=2873397496 2873404696
r=7d 1h 0 25h
k=clear:ab8c4df8b8f4as8v8iuy8re
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 99
b=AS:66781
k=prompt
a=rtpmap:99 h263-1998/90000
Encode:
package main
import (
"fmt"
"net"
"time"
"github.com/transtone/sdp"
)
func main() {
var (
s sdp.Session
b []byte
)
// defining medias
audio := sdp.Media{
Description: sdp.MediaDescription{
Type: "audio",
Port: 49170,
Formats: []string{"0"},
Protocol: "RTP/AVP",
},
}
video := sdp.Media{
Description: sdp.MediaDescription{
Type: "video",
Port: 51372,
Formats: []string{"99"},
Protocol: "RTP/AVP",
},
Bandwidths: sdp.Bandwidths{
sdp.BandwidthApplicationSpecific: 66781,
},
Encryption: sdp.Encryption{
Method: "prompt",
},
}
video.AddAttribute("rtpmap", "99", "h263-1998/90000")
// defining message
m := &sdp.Message{
Origin: sdp.Origin{
Username: "jdoe",
SessionID: 2890844526,
SessionVersion: 2890842807,
Address: "10.47.16.5",
},
Name: "SDP Seminar",
Info: "A Seminar on the session description protocol",
URI: "http://www.example.com/seminars/sdp.pdf",
Email: "[email protected] (Jane Doe)",
Phone: "12345",
Connection: sdp.ConnectionData{
IP: net.ParseIP("224.2.17.12"),
TTL: 127,
},
Bandwidths: sdp.Bandwidths{
sdp.BandwidthConferenceTotal: 154798,
},
Timing: []sdp.Timing{
{
Start: sdp.NTPToTime(2873397496),
End: sdp.NTPToTime(2873404696),
Repeat: 7 * time.Hour * 24,
Active: 3600 * time.Second,
Offsets: []time.Duration{
0,
25 * time.Hour,
},
},
},
Encryption: sdp.Encryption{
Method: "clear",
Key: "ab8c4df8b8f4as8v8iuy8re",
},
Medias: []sdp.Media{audio, video},
}
m.AddFlag("recvonly")
// appending message to session
s = m.Append(s)
// appending session to byte buffer
b = s.AppendTo(b)
fmt.Println(string(b))
}
Decode:
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"github.com/transtone/sdp"
)
func main() {
name := "example.sdp"
if len(os.Args) > 1 {
name = os.Args[1]
}
var (
s sdp.Session
b []byte
err error
f io.ReadCloser
)
fmt.Println("sdp file:", name)
if f, err = os.Open(name); err != nil {
log.Fatal("err:", err)
}
defer f.Close()
if b, err = ioutil.ReadAll(f); err != nil {
log.Fatal("err:", err)
}
if s, err = sdp.DecodeSession(b, s); err != nil {
log.Fatal("err:", err)
}
for k, v := range s {
fmt.Println(k, v)
}
d := sdp.NewDecoder(s)
m := new(sdp.Message)
if err = d.Decode(m); err != nil {
log.Fatal("err:", err)
}
fmt.Println("Decoded session", m.Name)
fmt.Println("Info:", m.Info)
fmt.Println("Origin:", m.Origin)
}
Also, low-level Session struct can be used directly to compose SDP message:
package main
import (
"fmt"
"github.com/transtone/sdp"
)
func main() {
var (
s sdp.Session
b []byte
)
b = s.AddVersion(0).
AddMediaDescription(sdp.MediaDescription{
Type: "video",
Port: 51372,
Formats: []string{"99"},
Protocol: "RTP/AVP",
}).
AddAttribute("rtpmap", "99", "h263-1998/90000").
AddLine(sdp.TypeEmail, "[email protected]").
AddRaw('ü', "vαlue").
AppendTo(b)
// and so on
fmt.Println(string(b))
// Output:
// v=0
// m=video 51372 RTP/AVP 99
// a=rtpmap:99 h263-1998/90000
// [email protected]
// ü=vαlue
}
Supported params
- v (protocol version)
- o (originator and session identifier)
- s (session name)
- i (session information)
- u (URI of description)
- e (email address)
- p (phone number)
- c (connection information)
- b (zero or more bandwidth information lines)
- t (time)
- r (repeat)
- z (time zone adjustments)
- k (encryption key)
- a (zero or more session attribute lines)
- m (media name and transport address)
TODO:
- Encoding
- Parsing
- High level encoding
- High level decoding
- Examples
- CI
- More examples and docs
- Online example
- io.Reader and io.Writer interop
- Include to high-level CI
Possible optimizations
There are comments // ALLOCATIONS: suboptimal.
and // CPU: suboptimal.
that indicate suboptimal implementation that can be optimized. There are often
a benchmarks for this pieces.
Benchmarks
goos: linux
goarch: amd64
pkg: github.com/gortc/sdp
PASS
benchmark iter time/iter bytes alloc allocs
--------- ---- --------- ----------- ------
BenchmarkDecoder_Decode-12 300000 4884.00 ns/op 3166 B/op 93 allocs/op
BenchmarkEncode-12 1000000 1577.00 ns/op 0 B/op 0 allocs/op
BenchmarkSession_AddConnectionData-12 20000000 114.00 ns/op 0 B/op 0 allocs/op
BenchmarkAppendIP-12 50000000 37.90 ns/op 0 B/op 0 allocs/op
BenchmarkAppendByte-12 100000000 11.00 ns/op 0 B/op 0 allocs/op
BenchmarkAppendInt-12 100000000 11.90 ns/op 0 B/op 0 allocs/op
BenchmarkSession_EX1-12 3000000 578.00 ns/op 16 B/op 1 allocs/op
BenchmarkAppendRune-12 200000000 6.70 ns/op 0 B/op 0 allocs/op
BenchmarkDecode-12 100000000 13.10 ns/op 0 B/op 0 allocs/op
BenchmarkDecodeSession-12 5000000 234.00 ns/op 0 B/op 0 allocs/op
ok github.com/gortc/sdp 16.820s
Build status
License
# Packages
No description provided by the author
# Functions
Decode decodes b as SDP message, returning error if any.
DecodeSession decodes Session from b, returning error if any.
NewDecoder returns Decoder for Session.
NTPToTime converts NTP timestamp to time.Time with special case for Zero time, that is interpreted as 0 timestamp.
TimeToNTP converts time.Time to NTP timestamp with special case for Zero time, that is interpreted as 0 timestamp.
# Constants
Possible values for <bwtype> defined in section 5.8.
defined in RFC 3890.
Possible values for <bwtype> defined in section 5.8.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
Attribute types as described in RFC 4566.
# Variables
ErrFailedToDecodeIP means that decoder failed to parse IP.
# Structs
Attribute represents key:value pair.
ConnectionData is representation for Connection Data field.
DecodeError wraps Reason of error and occurrence Place.
Decoder decodes session.
Encryption wraps encryption Key and Method.
Line of SDP session.
Media is media description and attributes.
MediaDescription represents Media Description field value.
Message is top level abstraction.
Origin is field defined in RFC4566 5.2.
TimeZone is representation of <adjustment time> <offset> pair.
Timing wraps "repeat times" and "timing" information.
# Type aliases
Attributes is list of k:v.
Bandwidths is map of BandwidthsType and int (bytes per second).
BandwidthType is <bwtype> sub-field of Bandwidth field.
Medias is list of Media.
Session is set of Lines.
Type of SDP Line is exactly one case-significant character.