Files
go2rtc/pkg/rtsp/helpers.go
2023-01-26 09:09:48 +03:00

69 lines
1.5 KiB
Go

package rtsp
import (
"bytes"
"github.com/AlexxIT/go2rtc/pkg/streamer"
"github.com/pion/rtcp"
"net/url"
"strings"
)
type RTCP struct {
Channel byte
Header rtcp.Header
Packets []rtcp.Packet
}
const sdpHeader = `v=0
o=- 0 0 IN IP4 0.0.0.0
s=-
t=0 0`
func UnmarshalSDP(rawSDP []byte) ([]*streamer.Media, error) {
medias, err := streamer.UnmarshalSDP(rawSDP)
if err != nil {
// fix SDP header for some cameras
i := bytes.Index(rawSDP, []byte("\nm="))
if i > 0 {
rawSDP = append([]byte(sdpHeader), rawSDP[i:]...)
medias, err = streamer.UnmarshalSDP(rawSDP)
}
if err != nil {
return nil, err
}
}
// fix bug in ONVIF spec
// https://www.onvif.org/specs/stream/ONVIF-Streaming-Spec-v241.pdf
for _, media := range medias {
switch media.Direction {
case streamer.DirectionRecvonly, "":
media.Direction = streamer.DirectionSendonly
case streamer.DirectionSendonly:
media.Direction = streamer.DirectionRecvonly
}
}
return medias, nil
}
// urlParse fix bugs:
// 1. Content-Base: rtsp://::ffff:192.168.1.123/onvif/profile.1/
// 2. Content-Base: rtsp://rtsp://turret2-cam.lan:554/stream1/
func urlParse(rawURL string) (*url.URL, error) {
if strings.HasPrefix(rawURL, "rtsp://rtsp://") {
rawURL = rawURL[7:]
}
u, err := url.Parse(rawURL)
if err != nil && strings.HasSuffix(err.Error(), "after host") {
if i1 := strings.Index(rawURL, "://"); i1 > 0 {
if i2 := strings.IndexByte(rawURL[i1+3:], '/'); i2 > 0 {
return urlParse(rawURL[:i1+3+i2] + ":" + rawURL[i1+3+i2:])
}
}
}
return u, err
}