forked from Monibuca/plugin-rtsp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsdp-parser.go
105 lines (101 loc) · 2.56 KB
/
sdp-parser.go
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
package rtsp
import (
"encoding/base64"
"encoding/hex"
"strconv"
"strings"
)
type SDPInfo struct {
AVType string
Codec string
TimeScale int
Control string
Rtpmap int
Config []byte
SpropParameterSets [][]byte
PayloadType int
SizeLength int
IndexLength int
}
func ParseSDP(sdpRaw string) map[string]*SDPInfo {
sdpMap := make(map[string]*SDPInfo)
var info *SDPInfo
for _, line := range strings.Split(sdpRaw, "\n") {
line = strings.TrimSpace(line)
typeval := strings.SplitN(line, "=", 2)
if len(typeval) == 2 {
fields := strings.SplitN(typeval[1], " ", 2)
switch typeval[0] {
case "m":
if len(fields) > 0 {
info = &SDPInfo{AVType: fields[0]}
sdpMap[info.AVType] = info
mfields := strings.Split(fields[1], " ")
if len(mfields) >= 3 {
info.PayloadType, _ = strconv.Atoi(mfields[2])
}
}
case "a":
if info != nil {
for _, field := range fields {
keyval := strings.SplitN(field, ":", 2)
if len(keyval) >= 2 {
key := keyval[0]
val := keyval[1]
switch key {
case "control":
info.Control = val
case "rtpmap":
info.Rtpmap, _ = strconv.Atoi(val)
}
}
keyval = strings.Split(field, "/")
if len(keyval) >= 2 {
key := keyval[0]
switch key {
case "PCMA":
info.Codec = "pcma"
case "PCMU":
info.Codec = "pcmu"
case "MPEG4-GENERIC":
info.Codec = "aac"
case "H264":
info.Codec = "h264"
case "H265":
info.Codec = "h265"
}
if i, err := strconv.Atoi(keyval[1]); err == nil {
info.TimeScale = i
}
}
keyval = strings.Split(field, ";")
if len(keyval) > 1 {
for _, field := range keyval {
keyval := strings.SplitN(field, "=", 2)
if len(keyval) == 2 {
key := strings.TrimSpace(keyval[0])
val := keyval[1]
switch key {
case "config":
info.Config, _ = hex.DecodeString(val)
case "sizelength":
info.SizeLength, _ = strconv.Atoi(val)
case "indexlength":
info.IndexLength, _ = strconv.Atoi(val)
case "sprop-parameter-sets":
fields := strings.Split(val, ",")
for _, field := range fields {
val, _ := base64.StdEncoding.DecodeString(field)
info.SpropParameterSets = append(info.SpropParameterSets, val)
}
}
}
}
}
}
}
}
}
}
return sdpMap
}