extmap.go 2.4 KB

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