sdp

package module
v0.18.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 1, 2020 License: BSD-3-Clause Imports: 10 Imported by: 8

README

Master status codecov GoDoc

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
e=j.doe@example.com (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"
	
	"gortc.io/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: "j.doe@example.com (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"

	"gortc.io/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"

	"gortc.io/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, "test@test.com").
		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
	//	e=test@test.com
	//	ü=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

Build Status Build status

License

FOSSA Status

Documentation

Overview

Package sdp implements RFC 4566 SDP: Session Description Protocol.

Index

Constants

This section is empty.

Variables

View Source
var ErrFailedToDecodeIP = errors.New("invalid IP")

ErrFailedToDecodeIP means that decoder failed to parse IP.

Functions

func NTPToTime

func NTPToTime(v uint64) time.Time

NTPToTime converts NTP timestamp to time.Time with special case for Zero time, that is interpreted as 0 timestamp.

func TimeToNTP

func TimeToNTP(t time.Time) uint64

TimeToNTP converts time.Time to NTP timestamp with special case for Zero time, that is interpreted as 0 timestamp.

Types

type Attribute added in v0.15.0

type Attribute struct {
	Key   string
	Value string
}

Attribute represents key:value pair.

type Attributes

type Attributes []Attribute

Attributes is list of k:v.

func (Attributes) Flag

func (a Attributes) Flag(flag string) bool

Flag returns true if set.

func (Attributes) Value

func (a Attributes) Value(attribute string) string

Value returns value of first attribute.

func (Attributes) Values

func (a Attributes) Values(attribute string) []string

Values returns list of values associated to attribute.

type BandwidthType

type BandwidthType string

BandwidthType is <bwtype> sub-field of Bandwidth field.

const (
	BandwidthConferenceTotal     BandwidthType = "CT"
	BandwidthApplicationSpecific BandwidthType = "AS"
	// defined in RFC 3890
	BandwidthApplicationSpecificTransportIndependent BandwidthType = "TIAS"
)

Possible values for <bwtype> defined in section 5.8.

type Bandwidths

type Bandwidths map[BandwidthType]int

Bandwidths is map of BandwidthsType and int (bytes per second).

type ConnectionData

type ConnectionData struct {
	NetworkType string // <nettype>
	AddressType string // <addrtype>
	IP          net.IP // <base multicast address>
	TTL         byte   // <ttl>
	Addresses   byte   // <number of addresses>
}

ConnectionData is representation for Connection Data field. Only IP field is required. NetworkType and AddressType have sensible defaults.

func (ConnectionData) Blank

func (c ConnectionData) Blank() bool

Blank determines if ConnectionData is blank value.

func (ConnectionData) ConnectionAddress

func (c ConnectionData) ConnectionAddress() string

ConnectionAddress formats <connection-address> sub-field.

func (ConnectionData) Equal

func (c ConnectionData) Equal(b ConnectionData) bool

Equal returns c == b.

func (ConnectionData) String

func (c ConnectionData) String() string

type DecodeError

type DecodeError struct {
	Reason string
	Place  string
}

DecodeError wraps Reason of error and occurrence Place.

func (DecodeError) Error

func (e DecodeError) Error() string

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder decodes session.

func NewDecoder

func NewDecoder(s Session) Decoder

NewDecoder returns Decoder for Session.

func (*Decoder) Decode

func (d *Decoder) Decode(m *Message) error

Decode message from session.

type Encryption

type Encryption struct {
	Method string
	Key    string
}

Encryption wraps encryption Key and Method.

func (Encryption) Blank

func (e Encryption) Blank() bool

Blank determines whether Encryption is blank value.

func (Encryption) Equal

func (e Encryption) Equal(b Encryption) bool

Equal returns e == b.

type Line

type Line struct {
	Type  Type
	Value []byte
}

Line of SDP session.

Form

<type>=<value>

Where <type> MUST be exactly one case-significant character and <value> is structured text whose format depends on <type>.

func (Line) AppendTo

func (l Line) AppendTo(b []byte) []byte

AppendTo appends Line encoded value to b.

func (*Line) Decode

func (l *Line) Decode(b []byte) error

Decode parses b into l and returns error if any.

Decode does not reuse b, so it is safe to corrupt it.

func (Line) Equal

func (l Line) Equal(b Line) bool

Equal returns true if l == b.

func (Line) String

func (l Line) String() string

type Media

type Media struct {
	Title       string
	Description MediaDescription
	Connection  ConnectionData
	Attributes  Attributes
	Encryption  Encryption
	Bandwidths  Bandwidths
}

Media is media description and attributes.

func (*Media) AddAttribute

func (m *Media) AddAttribute(k string, values ...string)

AddAttribute appends new k-v pair to attribute list.

func (*Media) AddFlag

func (m *Media) AddFlag(f string)

AddFlag appends new flag to attribute list.

func (*Media) Attribute

func (m *Media) Attribute(k string) string

Attribute returns string v.

func (*Media) Flag

func (m *Media) Flag(f string) bool

Flag returns true if set.

func (*Media) PayloadFormat added in v0.13.0

func (m *Media) PayloadFormat(payloadType string) string

PayloadFormat returns payload format from a=rtpmap. See RFC 4566 Section 6.

type MediaDescription

type MediaDescription struct {
	Type        string
	Port        int
	PortsNumber int
	Protocol    string
	Formats     []string
}

MediaDescription represents Media Description field value.

func (MediaDescription) Equal added in v0.13.0

Equal returns true if b equals to m.

type Medias

type Medias []Media

Medias is list of Media.

type Message

type Message struct {
	Version       int
	Origin        Origin
	Name          string
	Info          string
	Email         string
	Phone         string
	URI           string
	Connection    ConnectionData
	Attributes    Attributes
	Medias        Medias
	Encryption    Encryption
	Bandwidths    map[BandwidthType]int
	BandwidthType BandwidthType
	Timing        []Timing
	TZAdjustments []TimeZone
}

Message is top level abstraction.

func Decode added in v0.18.0

func Decode(b []byte) (*Message, error)

Decode decodes b as SDP message, returning error if any.

func (*Message) AddAttribute

func (m *Message) AddAttribute(k, v string)

AddAttribute appends new k-v pair to attribute list.

func (*Message) AddFlag

func (m *Message) AddFlag(f string)

AddFlag appends new flag to attribute list.

func (*Message) Append

func (m *Message) Append(s Session) Session

Append encodes message to Session and returns result.

See RFC 4566 Section 5.

func (*Message) Attribute

func (m *Message) Attribute(attribute string) string

Attribute returns string v.

func (*Message) End

func (m *Message) End() time.Time

End returns end of session.

func (*Message) Flag

func (m *Message) Flag(flag string) bool

Flag returns true if set.

func (*Message) Start

func (m *Message) Start() time.Time

Start returns start of session.

type Origin

type Origin struct {
	Username       string // <username>
	SessionID      int64  // <sess-id>
	SessionVersion int64  // <sess-version>
	NetworkType    string // <nettype>
	AddressType    string // <addrtype>
	Address        string // <unicast-address>
}

Origin is field defined in RFC4566 5.2. See https://tools.ietf.org/html/rfc4566#section-5.2.

func (*Origin) Equal

func (o *Origin) Equal(b Origin) bool

Equal returns b == o.

type Session

type Session []Line

Session is set of Lines.

func DecodeSession

func DecodeSession(b []byte, s Session) (Session, error)

DecodeSession decodes Session from b, returning error if any. Blank lines and leading/trialing whitespace are ignored.

If s is passed, it will be reused with its lines. It is safe to mutate b.

func (Session) AddAttribute

func (s Session) AddAttribute(attribute string, values ...string) Session

AddAttribute appends Attribute field to Session in a=<attribute>:<value>" form. If len(values) > 1, then "<value>" is "<val1> <val2> ... <valn>", and if len(values) == 0, then AddFlag method is used in "a=<flag>" form.

func (Session) AddBandwidth

func (s Session) AddBandwidth(t BandwidthType, bandwidth int) Session

AddBandwidth appends Bandwidth field to Session.

func (Session) AddConnectionData

func (s Session) AddConnectionData(data ConnectionData) Session

AddConnectionData appends Connection Data field to Session using ConnectionData struct with sensible defaults.

func (Session) AddConnectionDataIP

func (s Session) AddConnectionDataIP(ip net.IP) Session

AddConnectionDataIP appends Connection Data field using only ip address.

func (Session) AddEmail

func (s Session) AddEmail(email string) Session

AddEmail appends Email Address field to Session.

func (Session) AddEncryption

func (s Session) AddEncryption(e Encryption) Session

AddEncryption appends Encryption and is shorthand for AddEncryptionKey.

func (Session) AddEncryptionKey

func (s Session) AddEncryptionKey(method, key string) Session

AddEncryptionKey appends Encryption Key field with method and key in "k=<method>:<encryption key>" format to Session.

func (Session) AddEncryptionMethod

func (s Session) AddEncryptionMethod(method string) Session

AddEncryptionMethod appends Encryption Key field with only method in "k=<method>" format to Session.

func (Session) AddFlag

func (s Session) AddFlag(attribute string) Session

AddFlag appends Attribute field to Session in "a=<flag>" form.

func (Session) AddLine

func (s Session) AddLine(t Type, v string) Session

AddLine appends t=v to Session.

func (Session) AddMediaDescription

func (s Session) AddMediaDescription(m MediaDescription) Session

AddMediaDescription appends Media Description field to Session.

func (Session) AddOrigin

func (s Session) AddOrigin(o Origin) Session

AddOrigin appends Origin field to Session.

func (Session) AddPhone

func (s Session) AddPhone(phone string) Session

AddPhone appends Phone Address field to Session.

func (Session) AddRaw

func (s Session) AddRaw(k rune, v string) Session

AddRaw appends k=v to Session.

func (Session) AddRepeatTimes

func (s Session) AddRepeatTimes(interval, duration time.Duration,
	offsets ...time.Duration) Session

AddRepeatTimes appends Repeat Times field to Session.

func (Session) AddRepeatTimesCompact

func (s Session) AddRepeatTimesCompact(interval, duration time.Duration,
	offsets ...time.Duration) Session

AddRepeatTimesCompact appends Repeat Times field to Session using "compact" syntax.

func (Session) AddSessionInfo

func (s Session) AddSessionInfo(info string) Session

AddSessionInfo appends Session Information field to Session.

func (Session) AddSessionName

func (s Session) AddSessionName(name string) Session

AddSessionName appends Session Name field to Session.

func (Session) AddTimeZones

func (s Session) AddTimeZones(zones ...TimeZone) Session

AddTimeZones append TimeZones field to Session.

func (Session) AddTiming

func (s Session) AddTiming(start, end time.Time) Session

AddTiming appends Timing field to Session. Both start and end can be zero.

func (Session) AddTimingNTP

func (s Session) AddTimingNTP(start, end uint64) Session

AddTimingNTP appends Timing field to Session with NTP timestamps as input. It is just wrapper for AddTiming and NTPToTime.

func (Session) AddURI

func (s Session) AddURI(uri string) Session

AddURI appends Uniform Resource Identifier field to Session.

func (Session) AddVersion

func (s Session) AddVersion(version int) Session

AddVersion appends Version field to Session.

func (Session) AppendTo

func (s Session) AppendTo(b []byte) []byte

AppendTo appends all session lines to b and returns b.

func (Session) Equal

func (s Session) Equal(b Session) bool

Equal returns true if b == s.

type TimeZone

type TimeZone struct {
	Start  time.Time
	Offset time.Duration
}

TimeZone is representation of <adjustment time> <offset> pair.

type Timing

type Timing struct {
	Start   time.Time
	End     time.Time
	Repeat  time.Duration
	Active  time.Duration
	Offsets []time.Duration
}

Timing wraps "repeat times" and "timing" information.

type Type

type Type rune

Type of SDP Line is exactly one case-significant character.

const (
	TypeProtocolVersion    Type = 'v'
	TypeOrigin             Type = 'o'
	TypeSessionName        Type = 's'
	TypeSessionInformation Type = 'i'
	TypeURI                Type = 'u'
	TypeEmail              Type = 'e'
	TypePhone              Type = 'p'
	TypeConnectionData     Type = 'c'
	TypeBandwidth          Type = 'b'
	TypeTiming             Type = 't'
	TypeRepeatTimes        Type = 'r'
	TypeTimeZones          Type = 'z'
	TypeEncryptionKey      Type = 'k'
	TypeAttribute          Type = 'a'
	TypeMediaDescription   Type = 'm'
)

Attribute types as described in RFC 4566.

func (Type) String

func (t Type) String() string

Directories

Path Synopsis
e2e module
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL