vdk/format/rtsp/sdp/parser.go

182 lines
4.4 KiB
Go
Raw Permalink Normal View History

2019-12-01 04:53:21 +08:00
package sdp
import (
"encoding/base64"
"encoding/hex"
"fmt"
2021-02-03 11:10:03 +08:00
"log"
2019-12-01 04:53:21 +08:00
"strconv"
"strings"
"github.com/deepch/vdk/av"
)
type Session struct {
Uri string
}
type Media struct {
AVType string
Type av.CodecType
2021-05-09 04:07:59 +08:00
FPS int
2019-12-01 04:53:21 +08:00
TimeScale int
Control string
Rtpmap int
2021-01-09 12:37:19 +08:00
ChannelCount int
2019-12-01 04:53:21 +08:00
Config []byte
SpropParameterSets [][]byte
2021-02-03 11:10:03 +08:00
SpropVPS []byte
SpropSPS []byte
SpropPPS []byte
2019-12-01 04:53:21 +08:00
PayloadType int
SizeLength int
IndexLength int
}
func Parse(content string) (sess Session, medias []Media) {
var media *Media
for _, line := range strings.Split(content, "\n") {
line = strings.TrimSpace(line)
2021-05-09 04:07:59 +08:00
////Camera [BUG] a=x-framerate: 25
if strings.Contains(line, "x-framerate") {
line = strings.Replace(line, " ", "", -1)
}
2019-12-01 04:53:21 +08:00
typeval := strings.SplitN(line, "=", 2)
if len(typeval) == 2 {
fields := strings.SplitN(typeval[1], " ", 2)
switch typeval[0] {
case "m":
if len(fields) > 0 {
switch fields[0] {
case "audio", "video":
medias = append(medias, Media{AVType: fields[0]})
media = &medias[len(medias)-1]
mfields := strings.Split(fields[1], " ")
if len(mfields) >= 3 {
media.PayloadType, _ = strconv.Atoi(mfields[2])
}
2021-01-08 12:23:06 +08:00
switch media.PayloadType {
case 0:
media.Type = av.PCM_MULAW
case 8:
media.Type = av.PCM_ALAW
}
2020-06-29 23:35:37 +08:00
default:
media = nil
2019-12-01 04:53:21 +08:00
}
}
case "u":
sess.Uri = typeval[1]
case "a":
if media != nil {
for _, field := range fields {
keyval := strings.SplitN(field, ":", 2)
if len(keyval) >= 2 {
key := keyval[0]
val := keyval[1]
switch key {
case "control":
media.Control = val
case "rtpmap":
media.Rtpmap, _ = strconv.Atoi(val)
2021-05-09 04:07:59 +08:00
case "x-framerate":
media.FPS, _ = strconv.Atoi(val)
2019-12-01 04:53:21 +08:00
}
}
keyval = strings.Split(field, "/")
if len(keyval) >= 2 {
key := keyval[0]
switch strings.ToUpper(key) {
case "MPEG4-GENERIC":
media.Type = av.AAC
2021-01-08 12:23:06 +08:00
case "L16":
media.Type = av.PCM
2021-01-09 12:37:19 +08:00
case "OPUS":
media.Type = av.OPUS
if len(keyval) > 2 {
if i, err := strconv.Atoi(keyval[2]); err == nil {
media.ChannelCount = i
}
}
2019-12-01 04:53:21 +08:00
case "H264":
media.Type = av.H264
2021-09-30 07:10:08 +08:00
case "JPEG":
media.Type = av.JPEG
2021-02-03 11:10:03 +08:00
case "H265":
media.Type = av.H265
case "HEVC":
media.Type = av.H265
2021-04-21 22:03:35 +08:00
case "PCMA":
media.Type = av.PCM_ALAW
case "PCMU":
media.Type = av.PCM_MULAW
2019-12-01 04:53:21 +08:00
}
if i, err := strconv.Atoi(keyval[1]); err == nil {
media.TimeScale = i
}
if false {
fmt.Println("sdp:", keyval[1], media.TimeScale)
}
}
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":
media.Config, _ = hex.DecodeString(val)
case "sizelength":
media.SizeLength, _ = strconv.Atoi(val)
case "indexlength":
media.IndexLength, _ = strconv.Atoi(val)
2021-02-03 11:10:03 +08:00
case "sprop-vps":
val, err := base64.StdEncoding.DecodeString(val)
if err == nil {
media.SpropVPS = val
} else {
log.Println("SDP: decode vps error", err)
}
case "sprop-sps":
val, err := base64.StdEncoding.DecodeString(val)
if err == nil {
media.SpropSPS = val
} else {
log.Println("SDP: decode sps error", err)
}
case "sprop-pps":
val, err := base64.StdEncoding.DecodeString(val)
if err == nil {
media.SpropPPS = val
} else {
log.Println("SDP: decode pps error", err)
}
2019-12-01 04:53:21 +08:00
case "sprop-parameter-sets":
fields := strings.Split(val, ",")
for _, field := range fields {
if field == "" {
continue
}
2019-12-01 04:53:21 +08:00
val, _ := base64.StdEncoding.DecodeString(field)
media.SpropParameterSets = append(media.SpropParameterSets, val)
}
}
}
}
}
}
}
}
2020-06-26 13:28:33 +08:00
2019-12-01 04:53:21 +08:00
}
}
return
}