mirror of
https://github.com/aler9/gortsplib
synced 2025-10-04 23:02:45 +08:00
@@ -27,6 +27,7 @@ func sha256Base64(in string) string {
|
||||
}
|
||||
|
||||
// Validator allows to validate credentials generated by a Sender.
|
||||
//
|
||||
// Deprecated: Validator{} has been replaced by Validate()
|
||||
type Validator struct {
|
||||
user string
|
||||
@@ -40,6 +41,7 @@ type Validator struct {
|
||||
|
||||
// NewValidator allocates a Validator.
|
||||
// If methods is nil, the Basic and Digest methods are used.
|
||||
//
|
||||
// Deprecated: Validator{} has been replaced by Validate()
|
||||
func NewValidator(user string, pass string, methods []headers.AuthMethod) *Validator {
|
||||
if methods == nil {
|
||||
@@ -80,6 +82,7 @@ func NewValidator(user string, pass string, methods []headers.AuthMethod) *Valid
|
||||
|
||||
// Header generates the WWW-Authenticate header needed by a client to
|
||||
// authenticate.
|
||||
//
|
||||
// Deprecated: Validator{} has been replaced by Validate()
|
||||
func (va *Validator) Header() base.HeaderValue {
|
||||
var ret base.HeaderValue
|
||||
@@ -103,6 +106,7 @@ func (va *Validator) Header() base.HeaderValue {
|
||||
}
|
||||
|
||||
// ValidateRequest validates a request sent by a client.
|
||||
//
|
||||
// Deprecated: Validator{} has been replaced by Validate()
|
||||
func (va *Validator) ValidateRequest(req *base.Request, baseURL *url.URL) error {
|
||||
var auth headers.Authorization
|
||||
|
@@ -4,6 +4,7 @@ package media
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -14,6 +15,8 @@ import (
|
||||
"github.com/bluenviron/gortsplib/v3/pkg/url"
|
||||
)
|
||||
|
||||
var smartRegexp = regexp.MustCompile("^([0-9]+) (.*?)/90000")
|
||||
|
||||
func getControlAttribute(attributes []psdp.Attribute) string {
|
||||
for _, attr := range attributes {
|
||||
if attr.Key == "control" {
|
||||
@@ -135,9 +138,9 @@ func (m *Media) unmarshal(md *psdp.MediaDescription) error {
|
||||
if payloadType == "smart/1/90000" {
|
||||
for _, attr := range md.Attributes {
|
||||
if attr.Key == "rtpmap" {
|
||||
i := strings.Index(attr.Value, " TP-LINK/90000")
|
||||
if i >= 0 {
|
||||
payloadType = attr.Value[:i]
|
||||
sm := smartRegexp.FindStringSubmatch(attr.Value)
|
||||
if sm != nil {
|
||||
payloadType = sm[1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@@ -522,19 +522,19 @@ var casesMedias = []struct {
|
||||
"o=- 4158123474391860926 2 IN IP4 127.0.0.1\r\n" +
|
||||
"s=-\r\n" +
|
||||
"t=0 0\r\n" +
|
||||
"m=application 42504 RTP/AVP smart/1/90000\r\n" +
|
||||
"m=application/TP-LINK 0 RTP/AVP smart/1/90000\r\n" +
|
||||
"a=rtpmap:95 TP-LINK/90000\r\n",
|
||||
"v=0\r\n" +
|
||||
"o=- 0 0 IN IP4 127.0.0.1\r\n" +
|
||||
"s=Stream\r\n" +
|
||||
"c=IN IP4 0.0.0.0\r\n" +
|
||||
"t=0 0\r\n" +
|
||||
"m=application 0 RTP/AVP 95\r\n" +
|
||||
"m=application/TP-LINK 0 RTP/AVP 95\r\n" +
|
||||
"a=control\r\n" +
|
||||
"a=rtpmap:95 TP-LINK/90000\r\n",
|
||||
Medias{
|
||||
{
|
||||
Type: "application",
|
||||
Type: "application/TP-LINK",
|
||||
Formats: []formats.Format{&formats.Generic{
|
||||
PayloadTyp: 95,
|
||||
RTPMa: "TP-LINK/90000",
|
||||
@@ -543,6 +543,34 @@ var casesMedias = []struct {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"mercury",
|
||||
"v=0\n" +
|
||||
"o=- 14665860 31787219 1 IN IP4 192.168.0.60\n" +
|
||||
"s=Session streamed by \"MERCURY RTSP Server\"\n" +
|
||||
"t=0 0\n" +
|
||||
"a=smart_encoder:virtualIFrame=1\n" +
|
||||
"m=application/MERCURY 0 RTP/AVP smart/1/90000\n" +
|
||||
"a=rtpmap:95 MERCURY/90000\n",
|
||||
"v=0\r\n" +
|
||||
"o=- 0 0 IN IP4 127.0.0.1\r\n" +
|
||||
"s=Stream\r\n" +
|
||||
"c=IN IP4 0.0.0.0\r\n" +
|
||||
"t=0 0\r\n" +
|
||||
"m=application/MERCURY 0 RTP/AVP 95\r\n" +
|
||||
"a=control\r\n" +
|
||||
"a=rtpmap:95 MERCURY/90000\r\n",
|
||||
Medias{
|
||||
{
|
||||
Type: "application/MERCURY",
|
||||
Formats: []formats.Format{&formats.Generic{
|
||||
PayloadTyp: 95,
|
||||
RTPMa: "MERCURY/90000",
|
||||
ClockRat: 90000,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"h264 with space at end",
|
||||
"v=0\r\n" +
|
||||
|
@@ -406,14 +406,13 @@ func (s *SessionDescription) unmarshalMediaDescription(value string) error {
|
||||
|
||||
newMediaDesc := &psdp.MediaDescription{}
|
||||
|
||||
if fields[0] == "application/TP-LINK" {
|
||||
fields[0] = "application"
|
||||
}
|
||||
|
||||
// <media>
|
||||
// Set according to currently registered with IANA
|
||||
// https://tools.ietf.org/html/rfc4566#section-5.14
|
||||
if i := indexOf(fields[0], []string{"audio", "video", "text", "application", "message"}); i == -1 {
|
||||
if fields[0] != "video" &&
|
||||
fields[0] != "audio" &&
|
||||
fields[0] != "application" &&
|
||||
!strings.HasPrefix(fields[0], "application/") {
|
||||
return fmt.Errorf("%w `%v`", errSDPInvalidValue, fields[0])
|
||||
}
|
||||
newMediaDesc.MediaName.Media = fields[0]
|
||||
|
@@ -1876,7 +1876,7 @@ var cases = []struct {
|
||||
"m=audio 0 RTP/AVP 8\r\n" +
|
||||
"a=rtpmap:8 PCMA/8000\r\n" +
|
||||
"a=control:track2\r\n" +
|
||||
"m=application 0 RTP/AVP smart/1/90000\r\n" +
|
||||
"m=application/TP-LINK 0 RTP/AVP smart/1/90000\r\n" +
|
||||
"a=rtpmap:95 TP-LINK/90000\r\n" +
|
||||
"a=control:track3\r\n"),
|
||||
SessionDescription{
|
||||
@@ -1945,7 +1945,7 @@ var cases = []struct {
|
||||
},
|
||||
{
|
||||
MediaName: psdp.MediaName{
|
||||
Media: "application",
|
||||
Media: "application/TP-LINK",
|
||||
Protos: []string{"RTP", "AVP"},
|
||||
Formats: []string{"smart/1/90000"},
|
||||
},
|
||||
@@ -2215,6 +2215,138 @@ var cases = []struct {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"mercury",
|
||||
[]byte("v=0\n" +
|
||||
"o=- 14665860 31787219 1 IN IP4 192.168.0.60\n" +
|
||||
"s=Session streamed by \"MERCURY RTSP Server\"\n" +
|
||||
"t=0 0\n" +
|
||||
"a=smart_encoder:virtualIFrame=1\n" +
|
||||
"m=video 0 RTP/AVP 96\n" +
|
||||
"c=IN IP4 0.0.0.0\n" +
|
||||
"b=AS:4096\n" +
|
||||
"a=range:npt=0-\n" +
|
||||
"a=control:track1\n" +
|
||||
"a=rtpmap:96 H264/90000\n" +
|
||||
"a=fmtp:96 packetization-mode=1; profile-level-id=4D001F;" +
|
||||
" sprop-parameter-sets=J00AH+dAKALdgKUFBQXwAAADABAAAAMCi2gD6AXf//wK,KO48gA==\n" +
|
||||
"m=audio 0 RTP/AVP 8\n" +
|
||||
"a=rtpmap:8 PCMA/8000\n" +
|
||||
"a=control:track2\n" +
|
||||
"m=application/MERCURY 0 RTP/AVP smart/1/90000\n" +
|
||||
"a=rtpmap:95 MERCURY/90000\n" +
|
||||
"a=control:track3\n"),
|
||||
[]byte("v=0\r\n" +
|
||||
"o=- 14665860 31787219 1 IN IP4 192.168.0.60\r\n" +
|
||||
"s=Session streamed by \"MERCURY RTSP Server\"\r\n" +
|
||||
"t=0 0\r\n" +
|
||||
"a=smart_encoder:virtualIFrame=1\r\n" +
|
||||
"m=video 0 RTP/AVP 96\r\n" +
|
||||
"c=IN IP4 0.0.0.0\r\n" +
|
||||
"b=AS:4096\r\n" +
|
||||
"a=range:npt=0-\r\n" +
|
||||
"a=control:track1\r\n" +
|
||||
"a=rtpmap:96 H264/90000\r\n" +
|
||||
"a=fmtp:96 packetization-mode=1; profile-level-id=4D001F;" +
|
||||
" sprop-parameter-sets=J00AH+dAKALdgKUFBQXwAAADABAAAAMCi2gD6AXf//wK,KO48gA==\r\n" +
|
||||
"m=audio 0 RTP/AVP 8\r\n" +
|
||||
"a=rtpmap:8 PCMA/8000\r\n" +
|
||||
"a=control:track2\r\n" +
|
||||
"m=application/MERCURY 0 RTP/AVP smart/1/90000\r\n" +
|
||||
"a=rtpmap:95 MERCURY/90000\r\n" +
|
||||
"a=control:track3\r\n"),
|
||||
SessionDescription{
|
||||
Origin: psdp.Origin{
|
||||
Username: "- 14665860",
|
||||
SessionID: 31787219,
|
||||
SessionVersion: 1,
|
||||
NetworkType: "IN",
|
||||
AddressType: "IP4",
|
||||
UnicastAddress: "192.168.0.60",
|
||||
},
|
||||
SessionName: "Session streamed by \"MERCURY RTSP Server\"",
|
||||
TimeDescriptions: []psdp.TimeDescription{{}},
|
||||
Attributes: []psdp.Attribute{
|
||||
{
|
||||
Key: "smart_encoder",
|
||||
Value: "virtualIFrame=1",
|
||||
},
|
||||
},
|
||||
MediaDescriptions: []*psdp.MediaDescription{
|
||||
{
|
||||
MediaName: psdp.MediaName{
|
||||
Media: "video",
|
||||
Protos: []string{"RTP", "AVP"},
|
||||
Formats: []string{"96"},
|
||||
},
|
||||
ConnectionInformation: &psdp.ConnectionInformation{
|
||||
NetworkType: "IN",
|
||||
AddressType: "IP4",
|
||||
Address: &psdp.Address{
|
||||
Address: "0.0.0.0",
|
||||
},
|
||||
},
|
||||
Bandwidth: []psdp.Bandwidth{{
|
||||
Type: "AS",
|
||||
Bandwidth: 4096,
|
||||
}},
|
||||
Attributes: []psdp.Attribute{
|
||||
{
|
||||
Key: "range",
|
||||
Value: "npt=0-",
|
||||
},
|
||||
{
|
||||
Key: "control",
|
||||
Value: "track1",
|
||||
},
|
||||
{
|
||||
Key: "rtpmap",
|
||||
Value: "96 H264/90000",
|
||||
},
|
||||
{
|
||||
Key: "fmtp",
|
||||
Value: "96 packetization-mode=1; profile-level-id=4D001F;" +
|
||||
" sprop-parameter-sets=J00AH+dAKALdgKUFBQXwAAADABAAAAMCi2gD6AXf//wK,KO48gA==",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
MediaName: psdp.MediaName{
|
||||
Media: "audio",
|
||||
Protos: []string{"RTP", "AVP"},
|
||||
Formats: []string{"8"},
|
||||
},
|
||||
Attributes: []psdp.Attribute{
|
||||
{
|
||||
Key: "rtpmap",
|
||||
Value: "8 PCMA/8000",
|
||||
},
|
||||
{
|
||||
Key: "control",
|
||||
Value: "track2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
MediaName: psdp.MediaName{
|
||||
Media: "application/MERCURY",
|
||||
Protos: []string{"RTP", "AVP"},
|
||||
Formats: []string{"smart/1/90000"},
|
||||
},
|
||||
Attributes: []psdp.Attribute{
|
||||
{
|
||||
Key: "rtpmap",
|
||||
Value: "95 MERCURY/90000",
|
||||
},
|
||||
{
|
||||
Key: "control",
|
||||
Value: "track3",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestUnmarshal(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user