1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
package sdp
import (
"fmt"
"net/url"
"strconv"
"strings"
)
// Default ext values.
const (
DefExtMapValueABSSendTime = 1
DefExtMapValueTransportCC = 2
DefExtMapValueSDESMid = 3
DefExtMapValueSDESRTPStreamID = 4
ABSSendTimeURI = "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"
TransportCCURI = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
SDESMidURI = "urn:ietf:params:rtp-hdrext:sdes:mid"
SDESRTPStreamIDURI = "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"
SDESRepairRTPStreamIDURI = "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"
AudioLevelURI = "urn:ietf:params:rtp-hdrext:ssrc-audio-level"
)
// ExtMap represents the activation of a single RTP header extension.
type ExtMap struct {
Value int
Direction Direction
URI *url.URL
ExtAttr *string
}
// Clone converts this object to an Attribute.
func (e *ExtMap) Clone() Attribute {
return Attribute{Key: "extmap", Value: e.string()}
}
// Unmarshal creates an Extmap from a string.
func (e *ExtMap) Unmarshal(raw string) error {
parts := strings.SplitN(raw, ":", 2)
if len(parts) != 2 {
return fmt.Errorf("%w: %v", errSyntaxError, raw)
}
fields := strings.Fields(parts[1])
if len(fields) < 2 {
return fmt.Errorf("%w: %v", errSyntaxError, raw)
}
valdir := strings.Split(fields[0], "/")
value, err := strconv.ParseInt(valdir[0], 10, 64)
if (value < 1) || (value > 246) {
return fmt.Errorf("%w: %v -- extmap key must be in the range 1-256", errSyntaxError, valdir[0])
}
if err != nil {
return fmt.Errorf("%w: %v", errSyntaxError, valdir[0])
}
var direction Direction
if len(valdir) == 2 {
direction, err = NewDirection(valdir[1])
if err != nil {
return err
}
}
uri, err := url.Parse(fields[1])
if err != nil {
return err
}
if len(fields) == 3 {
tmp := fields[2]
e.ExtAttr = &tmp
}
e.Value = int(value)
e.Direction = direction
e.URI = uri
return nil
}
// Marshal creates a string from an ExtMap.
func (e *ExtMap) Marshal() string {
return e.Name() + ":" + e.string()
}
func (e *ExtMap) string() string {
output := fmt.Sprintf("%d", e.Value)
dirstring := e.Direction.String()
if dirstring != directionUnknownStr {
output += "/" + dirstring
}
if e.URI != nil {
output += " " + e.URI.String()
}
if e.ExtAttr != nil {
output += " " + *e.ExtAttr
}
return output
}
// Name returns the constant name of this object.
func (e *ExtMap) Name() string {
return "extmap"
}
|