mirror of
https://github.com/Monibuca/plugin-rtsp.git
synced 2025-09-26 19:51:14 +08:00
134
client.go
134
client.go
@@ -144,7 +144,7 @@ func (client *RTSP) requestStream() (err error) {
|
||||
client.connRW = bufio.NewReadWriter(bufio.NewReaderSize(&timeoutConn, networkBuffer), bufio.NewWriterSize(&timeoutConn, networkBuffer))
|
||||
|
||||
headers := make(map[string]string)
|
||||
headers["Require"] = "implicit-play"
|
||||
//headers["Require"] = "implicit-play"
|
||||
// An OPTIONS request returns the request types the server will accept.
|
||||
resp, err := client.Request("OPTIONS", headers)
|
||||
if err != nil {
|
||||
@@ -191,80 +191,84 @@ func (client *RTSP) requestStream() (err error) {
|
||||
client.SDPMap = ParseSDP(client.SDPRaw)
|
||||
session := ""
|
||||
if videoInfo, ok := client.SDPMap["video"]; ok {
|
||||
client.VControl = videoInfo.Control
|
||||
client.VCodec = videoInfo.Codec
|
||||
client.WriteSPS(videoInfo.SpropParameterSets[0])
|
||||
client.WritePPS(videoInfo.SpropParameterSets[1])
|
||||
var _url = ""
|
||||
if strings.Index(strings.ToLower(client.VControl), "rtsp://") == 0 {
|
||||
_url = client.VControl
|
||||
} else {
|
||||
_url = strings.TrimRight(client.URL, "/") + "/" + strings.TrimLeft(client.VControl, "/")
|
||||
}
|
||||
headers = make(map[string]string)
|
||||
if client.TransType == TRANS_TYPE_TCP {
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/TCP;unicast;interleaved=%d-%d", client.vRTPChannel, client.vRTPControlChannel)
|
||||
} else {
|
||||
if client.UDPServer == nil {
|
||||
client.UDPServer = &UDPServer{Session: client}
|
||||
for i := 0; i < len(videoInfo.Control); i++ {
|
||||
client.VControl = videoInfo.Control[i]
|
||||
client.VCodec = videoInfo.Codec
|
||||
client.WriteSPS(videoInfo.SpropParameterSets[0])
|
||||
client.WritePPS(videoInfo.SpropParameterSets[1])
|
||||
var _url = ""
|
||||
if strings.Index(strings.ToLower(client.VControl), "rtsp://") == 0 {
|
||||
_url = client.VControl
|
||||
} else {
|
||||
_url = strings.TrimRight(client.URL, "/") + "/" + strings.TrimLeft(client.VControl, "/")
|
||||
}
|
||||
//RTP/AVP;unicast;client_port=64864-64865
|
||||
err = client.UDPServer.SetupVideo()
|
||||
if err != nil {
|
||||
Printf("Setup video err.%v", err)
|
||||
headers = make(map[string]string)
|
||||
if client.TransType == TRANS_TYPE_TCP {
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/TCP;unicast;interleaved=%d-%d", client.vRTPChannel, client.vRTPControlChannel)
|
||||
} else {
|
||||
if client.UDPServer == nil {
|
||||
client.UDPServer = &UDPServer{Session: client}
|
||||
}
|
||||
//RTP/AVP;unicast;client_port=64864-64865
|
||||
err = client.UDPServer.SetupVideo()
|
||||
if err != nil {
|
||||
Printf("Setup video err.%v", err)
|
||||
return err
|
||||
}
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/UDP;unicast;client_port=%d-%d", client.UDPServer.VPort, client.UDPServer.VControlPort)
|
||||
client.Conn.timeout = 0 // UDP ignore timeout
|
||||
}
|
||||
if session != "" {
|
||||
headers["Session"] = session
|
||||
}
|
||||
Printf("Parse DESCRIBE response, VIDEO VControl:%s, VCode:%s, url:%s,Session:%s,vRTPChannel:%d,vRTPControlChannel:%d", client.VControl, client.VCodec, _url, session, client.vRTPChannel, client.vRTPControlChannel)
|
||||
if resp, err = client.RequestWithPath("SETUP", _url, headers, true); err != nil {
|
||||
return err
|
||||
}
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/UDP;unicast;client_port=%d-%d", client.UDPServer.VPort, client.UDPServer.VControlPort)
|
||||
client.Conn.timeout = 0 // UDP ignore timeout
|
||||
session, _ = resp.Header["Session"].(string)
|
||||
session = strings.Split(session, ";")[0]
|
||||
}
|
||||
if session != "" {
|
||||
headers["Session"] = session
|
||||
}
|
||||
Printf("Parse DESCRIBE response, VIDEO VControl:%s, VCode:%s, url:%s,Session:%s,vRTPChannel:%d,vRTPControlChannel:%d", client.VControl, client.VCodec, _url, session, client.vRTPChannel, client.vRTPControlChannel)
|
||||
if resp, err = client.RequestWithPath("SETUP", _url, headers, true); err != nil {
|
||||
return err
|
||||
}
|
||||
session, _ = resp.Header["Session"].(string)
|
||||
session = strings.Split(session, ";")[0]
|
||||
}
|
||||
if audioInfo, ok := client.SDPMap["audio"]; ok {
|
||||
client.AControl = audioInfo.Control
|
||||
client.ACodec = audioInfo.Codec
|
||||
if len(audioInfo.Config) < 2 {
|
||||
Printf("Setup audio err codec not support: %s", client.ACodec)
|
||||
} else {
|
||||
client.WriteASC(audioInfo.Config)
|
||||
}
|
||||
var _url = ""
|
||||
if strings.Index(strings.ToLower(client.AControl), "rtsp://") == 0 {
|
||||
_url = client.AControl
|
||||
} else {
|
||||
_url = strings.TrimRight(client.URL, "/") + "/" + strings.TrimLeft(client.AControl, "/")
|
||||
}
|
||||
headers = make(map[string]string)
|
||||
if client.TransType == TRANS_TYPE_TCP {
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/TCP;unicast;interleaved=%d-%d", client.aRTPChannel, client.aRTPControlChannel)
|
||||
} else {
|
||||
if client.UDPServer == nil {
|
||||
client.UDPServer = &UDPServer{Session: client}
|
||||
for i := 0; i < len(audioInfo.Control); i++ {
|
||||
client.AControl = audioInfo.Control[i]
|
||||
client.ACodec = audioInfo.Codec
|
||||
if len(audioInfo.Config) < 2 {
|
||||
Printf("Setup audio err codec not support: %s", client.ACodec)
|
||||
} else {
|
||||
client.WriteASC(audioInfo.Config)
|
||||
}
|
||||
err = client.UDPServer.SetupAudio()
|
||||
if err != nil {
|
||||
Printf("Setup audio err.%v", err)
|
||||
var _url = ""
|
||||
if strings.Index(strings.ToLower(client.AControl), "rtsp://") == 0 {
|
||||
_url = client.AControl
|
||||
} else {
|
||||
_url = strings.TrimRight(client.URL, "/") + "/" + strings.TrimLeft(client.AControl, "/")
|
||||
}
|
||||
headers = make(map[string]string)
|
||||
if client.TransType == TRANS_TYPE_TCP {
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/TCP;unicast;interleaved=%d-%d", client.aRTPChannel, client.aRTPControlChannel)
|
||||
} else {
|
||||
if client.UDPServer == nil {
|
||||
client.UDPServer = &UDPServer{Session: client}
|
||||
}
|
||||
err = client.UDPServer.SetupAudio()
|
||||
if err != nil {
|
||||
Printf("Setup audio err.%v", err)
|
||||
return err
|
||||
}
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/UDP;unicast;client_port=%d-%d", client.UDPServer.APort, client.UDPServer.AControlPort)
|
||||
client.Conn.timeout = 0 // UDP ignore timeout
|
||||
}
|
||||
if session != "" {
|
||||
headers["Session"] = session
|
||||
}
|
||||
Printf("Parse DESCRIBE response, AUDIO AControl:%s, ACodec:%s, url:%s,Session:%s, aRTPChannel:%d,aRTPControlChannel:%d", client.AControl, client.ACodec, _url, session, client.aRTPChannel, client.aRTPControlChannel)
|
||||
if resp, err = client.RequestWithPath("SETUP", _url, headers, true); err != nil {
|
||||
return err
|
||||
}
|
||||
headers["Transport"] = fmt.Sprintf("RTP/AVP/UDP;unicast;client_port=%d-%d", client.UDPServer.APort, client.UDPServer.AControlPort)
|
||||
client.Conn.timeout = 0 // UDP ignore timeout
|
||||
session, _ = resp.Header["Session"].(string)
|
||||
session = strings.Split(session, ";")[0]
|
||||
}
|
||||
if session != "" {
|
||||
headers["Session"] = session
|
||||
}
|
||||
Printf("Parse DESCRIBE response, AUDIO AControl:%s, ACodec:%s, url:%s,Session:%s, aRTPChannel:%d,aRTPControlChannel:%d", client.AControl, client.ACodec, _url, session, client.aRTPChannel, client.aRTPControlChannel)
|
||||
if resp, err = client.RequestWithPath("SETUP", _url, headers, true); err != nil {
|
||||
return err
|
||||
}
|
||||
session, _ = resp.Header["Session"].(string)
|
||||
session = strings.Split(session, ";")[0]
|
||||
}
|
||||
headers = make(map[string]string)
|
||||
if session != "" {
|
||||
|
2
go.mod
2
go.mod
@@ -5,6 +5,6 @@ go 1.13
|
||||
require (
|
||||
github.com/Monibuca/engine/v2 v2.1.2
|
||||
github.com/Monibuca/plugin-rtp v0.0.0-20200531014802-504413c0dfcb
|
||||
github.com/pion/rtp v1.5.4 // indirect
|
||||
github.com/pion/rtp v1.6.0 // indirect
|
||||
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf
|
||||
)
|
||||
|
4
go.sum
4
go.sum
@@ -22,8 +22,12 @@ github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+v
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/pion/randutil v0.0.0 h1:aLWLVhTG2jzoD25F0OlW6nXvXrjoGwiXq2Sz7j7NzL0=
|
||||
github.com/pion/randutil v0.0.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/rtp v1.5.4 h1:PuNg6xqV3brIUihatcKZj1YDUs+M45L0ZbrZWYtkDxY=
|
||||
github.com/pion/rtp v1.5.4/go.mod h1:bg60AL5GotNOlYZsqycbhDtEV3TkfbpXG0KBiUq29Mg=
|
||||
github.com/pion/rtp v1.6.0 h1:4Ssnl/T5W2LzxHj9ssYpGVEQh3YYhQFNVmSWO88MMwk=
|
||||
github.com/pion/rtp v1.6.0/go.mod h1:QgfogHsMBVE/RFNno467U/KBqfUywEH+HK+0rtnwsdI=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@@ -11,7 +11,7 @@ type SDPInfo struct {
|
||||
AVType string
|
||||
Codec string
|
||||
TimeScale int
|
||||
Control string
|
||||
Control []string
|
||||
Rtpmap int
|
||||
Config []byte
|
||||
SpropParameterSets [][]byte
|
||||
@@ -51,7 +51,7 @@ func ParseSDP(sdpRaw string) map[string]*SDPInfo {
|
||||
val := keyval[1]
|
||||
switch key {
|
||||
case "control":
|
||||
info.Control = val
|
||||
info.Control = append(info.Control, val)
|
||||
case "rtpmap":
|
||||
info.Rtpmap, _ = strconv.Atoi(val)
|
||||
}
|
||||
|
@@ -320,13 +320,13 @@ func (session *RTSP) handleRequest(req *Request) {
|
||||
if session.Publish(streamPath) {
|
||||
sdp, ok := session.SDPMap["audio"]
|
||||
if ok {
|
||||
session.AControl = sdp.Control
|
||||
session.AControl = sdp.Control[0]
|
||||
session.ACodec = sdp.Codec
|
||||
session.WriteASC(sdp.Config)
|
||||
Printf("audio codec[%s]\n", session.ACodec)
|
||||
}
|
||||
if sdp, ok = session.SDPMap["video"]; ok {
|
||||
session.VControl = sdp.Control
|
||||
session.VControl = sdp.Control[0]
|
||||
session.VCodec = sdp.Codec
|
||||
session.WriteSPS(sdp.SpropParameterSets[0])
|
||||
session.WritePPS(sdp.SpropParameterSets[1])
|
||||
|
Reference in New Issue
Block a user