mirror of
https://github.com/bluenviron/mediamtx
synced 2025-02-20 21:46:56 +00:00
update gortsplib (#2126)
This commit is contained in:
parent
83484b1e82
commit
e3d4856b4f
2
go.mod
2
go.mod
@ -8,7 +8,7 @@ require (
|
||||
github.com/alecthomas/kong v0.8.0
|
||||
github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87
|
||||
github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072
|
||||
github.com/bluenviron/gortsplib/v3 v3.9.0
|
||||
github.com/bluenviron/gortsplib/v3 v3.9.1-0.20230730204034-8b8b52e689d9
|
||||
github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
|
4
go.sum
4
go.sum
@ -12,8 +12,8 @@ github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87 h1:SCAqalLhg
|
||||
github.com/asticode/go-astits v1.11.1-0.20230727094110-0df190a2dd87/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
|
||||
github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072 h1:pAbC7frXsTMxP7Ck3E50hl7oFeSeD2dgc2lWjmHXztQ=
|
||||
github.com/bluenviron/gohlslib v0.3.1-0.20230730162911-eb9f86511072/go.mod h1:rK4b161qErs82QqvBEl84vpi2xhdZBUT0yubXuytZ7E=
|
||||
github.com/bluenviron/gortsplib/v3 v3.9.0 h1:aAHV6MhsDtgBF6yKaNBBCdvtSpLB8ne4kyUfLQlN7nM=
|
||||
github.com/bluenviron/gortsplib/v3 v3.9.0/go.mod h1:5h3Zu7jkzwDknYrf+89q2saab//oioKgM9mgvBEX3pg=
|
||||
github.com/bluenviron/gortsplib/v3 v3.9.1-0.20230730204034-8b8b52e689d9 h1:QBdUlT/taEG0b8dxguJ6GYT7r6vJFRhvwlhs1LGWYlQ=
|
||||
github.com/bluenviron/gortsplib/v3 v3.9.1-0.20230730204034-8b8b52e689d9/go.mod h1:vBmCYjtox2pXWSvU+r9ROpEbwSOhh5lVWd+t9Sj8glc=
|
||||
github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda h1:+ungCWRNDjsy/CVL1l/UjAj4vYL4+NIJQoJJWbR3Xw8=
|
||||
github.com/bluenviron/mediacommon v0.7.1-0.20230730144331-10b74a4f6eda/go.mod h1:tfk0qGPhqnOxVCrElu8ct3LKQn6Cj4Tpu3zbbJBTKj4=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
|
@ -115,7 +115,7 @@ type pathReaderAddReq struct {
|
||||
res chan pathReaderSetupPlayRes
|
||||
}
|
||||
|
||||
type pathPublisherAnnounceRes struct {
|
||||
type pathPublisherAddRes struct {
|
||||
path *path
|
||||
err error
|
||||
}
|
||||
@ -125,7 +125,7 @@ type pathPublisherAddReq struct {
|
||||
pathName string
|
||||
skipAuth bool
|
||||
credentials authCredentials
|
||||
res chan pathPublisherAnnounceRes
|
||||
res chan pathPublisherAddRes
|
||||
}
|
||||
|
||||
type pathPublisherRecordRes struct {
|
||||
@ -743,7 +743,7 @@ func (pa *path) handlePublisherRemove(req pathPublisherRemoveReq) {
|
||||
|
||||
func (pa *path) handlePublisherAdd(req pathPublisherAddReq) {
|
||||
if pa.conf.Source != "publisher" {
|
||||
req.res <- pathPublisherAnnounceRes{
|
||||
req.res <- pathPublisherAddRes{
|
||||
err: fmt.Errorf("can't publish to path '%s' since 'source' is not 'publisher'", pa.name),
|
||||
}
|
||||
return
|
||||
@ -751,7 +751,7 @@ func (pa *path) handlePublisherAdd(req pathPublisherAddReq) {
|
||||
|
||||
if pa.source != nil {
|
||||
if pa.conf.DisablePublisherOverride {
|
||||
req.res <- pathPublisherAnnounceRes{err: fmt.Errorf("someone is already publishing to path '%s'", pa.name)}
|
||||
req.res <- pathPublisherAddRes{err: fmt.Errorf("someone is already publishing to path '%s'", pa.name)}
|
||||
return
|
||||
}
|
||||
|
||||
@ -762,7 +762,7 @@ func (pa *path) handlePublisherAdd(req pathPublisherAddReq) {
|
||||
|
||||
pa.source = req.author
|
||||
|
||||
req.res <- pathPublisherAnnounceRes{path: pa}
|
||||
req.res <- pathPublisherAddRes{path: pa}
|
||||
}
|
||||
|
||||
func (pa *path) handlePublisherStart(req pathPublisherStartReq) {
|
||||
@ -973,12 +973,12 @@ func (pa *path) publisherRemove(req pathPublisherRemoveReq) {
|
||||
}
|
||||
|
||||
// publisherAdd is called by a publisher through pathManager.
|
||||
func (pa *path) publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes {
|
||||
func (pa *path) publisherAdd(req pathPublisherAddReq) pathPublisherAddRes {
|
||||
select {
|
||||
case pa.chPublisherAdd <- req:
|
||||
return <-req.res
|
||||
case <-pa.ctx.Done():
|
||||
return pathPublisherAnnounceRes{err: fmt.Errorf("terminated")}
|
||||
return pathPublisherAddRes{err: fmt.Errorf("terminated")}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,14 +289,14 @@ outer:
|
||||
case req := <-pm.chPublisherAdd:
|
||||
pathConfName, pathConf, pathMatches, err := getConfForPath(pm.pathConfs, req.pathName)
|
||||
if err != nil {
|
||||
req.res <- pathPublisherAnnounceRes{err: err}
|
||||
req.res <- pathPublisherAddRes{err: err}
|
||||
continue
|
||||
}
|
||||
|
||||
if !req.skipAuth {
|
||||
err = doAuthentication(pm.externalAuthenticationURL, pm.authMethods, req.pathName, pathConf, true, req.credentials)
|
||||
if err != nil {
|
||||
req.res <- pathPublisherAnnounceRes{err: err}
|
||||
req.res <- pathPublisherAddRes{err: err}
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -306,7 +306,7 @@ outer:
|
||||
pm.createPath(pathConfName, pathConf, req.pathName, pathMatches)
|
||||
}
|
||||
|
||||
req.res <- pathPublisherAnnounceRes{path: pm.paths[req.pathName]}
|
||||
req.res <- pathPublisherAddRes{path: pm.paths[req.pathName]}
|
||||
|
||||
case s := <-pm.chHLSManagerSet:
|
||||
pm.hlsManager = s
|
||||
@ -449,8 +449,8 @@ func (pm *pathManager) describe(req pathDescribeReq) pathDescribeRes {
|
||||
}
|
||||
|
||||
// publisherAnnounce is called by a publisher.
|
||||
func (pm *pathManager) publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes {
|
||||
req.res = make(chan pathPublisherAnnounceRes)
|
||||
func (pm *pathManager) publisherAdd(req pathPublisherAddReq) pathPublisherAddRes {
|
||||
req.res = make(chan pathPublisherAddRes)
|
||||
select {
|
||||
case pm.chPublisherAdd <- req:
|
||||
res := <-req.res
|
||||
@ -461,7 +461,7 @@ func (pm *pathManager) publisherAdd(req pathPublisherAddReq) pathPublisherAnnoun
|
||||
return res.path.publisherAdd(req)
|
||||
|
||||
case <-pm.ctx.Done():
|
||||
return pathPublisherAnnounceRes{err: fmt.Errorf("terminated")}
|
||||
return pathPublisherAddRes{err: fmt.Errorf("terminated")}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ const (
|
||||
|
||||
type rtmpConnPathManager interface {
|
||||
readerAdd(req pathReaderAddReq) pathReaderSetupPlayRes
|
||||
publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes
|
||||
publisherAdd(req pathPublisherAddReq) pathPublisherAddRes
|
||||
}
|
||||
|
||||
type rtmpConnParent interface {
|
||||
|
@ -137,7 +137,13 @@ func (c *rtspConn) onDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx,
|
||||
ctx.Path = ctx.Path[1:]
|
||||
|
||||
if c.authNonce == "" {
|
||||
c.authNonce = auth.GenerateNonce()
|
||||
var err error
|
||||
c.authNonce, err = auth.GenerateNonce()
|
||||
if err != nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusInternalServerError,
|
||||
}, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
res := c.pathManager.describe(pathDescribeReq{
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
type rtspSessionPathManager interface {
|
||||
publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes
|
||||
publisherAdd(req pathPublisherAddReq) pathPublisherAddRes
|
||||
readerAdd(req pathReaderAddReq) pathReaderSetupPlayRes
|
||||
}
|
||||
|
||||
@ -122,7 +122,13 @@ func (s *rtspSession) onAnnounce(c *rtspConn, ctx *gortsplib.ServerHandlerOnAnno
|
||||
ctx.Path = ctx.Path[1:]
|
||||
|
||||
if c.authNonce == "" {
|
||||
c.authNonce = auth.GenerateNonce()
|
||||
var err error
|
||||
c.authNonce, err = auth.GenerateNonce()
|
||||
if err != nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusInternalServerError,
|
||||
}, err
|
||||
}
|
||||
}
|
||||
|
||||
res := s.pathManager.publisherAdd(pathPublisherAddReq{
|
||||
@ -201,7 +207,13 @@ func (s *rtspSession) onSetup(c *rtspConn, ctx *gortsplib.ServerHandlerOnSetupCt
|
||||
}
|
||||
|
||||
if c.authNonce == "" {
|
||||
c.authNonce = auth.GenerateNonce()
|
||||
var err error
|
||||
c.authNonce, err = auth.GenerateNonce()
|
||||
if err != nil {
|
||||
return &base.Response{
|
||||
StatusCode: base.StatusInternalServerError,
|
||||
}, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
res := s.pathManager.readerAdd(pathReaderAddReq{
|
||||
|
@ -2,11 +2,6 @@ package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bluenviron/gortsplib/v3"
|
||||
@ -19,37 +14,6 @@ import (
|
||||
"github.com/bluenviron/mediamtx/internal/logger"
|
||||
)
|
||||
|
||||
type rtspSourceParent interface {
|
||||
logger.Writer
|
||||
sourceStaticImplSetReady(req pathSourceStaticSetReadyReq) pathSourceStaticSetReadyRes
|
||||
sourceStaticImplSetNotReady(req pathSourceStaticSetNotReadyReq)
|
||||
}
|
||||
|
||||
type rtspSource struct {
|
||||
readTimeout conf.StringDuration
|
||||
writeTimeout conf.StringDuration
|
||||
readBufferCount int
|
||||
parent rtspSourceParent
|
||||
}
|
||||
|
||||
func newRTSPSource(
|
||||
readTimeout conf.StringDuration,
|
||||
writeTimeout conf.StringDuration,
|
||||
readBufferCount int,
|
||||
parent rtspSourceParent,
|
||||
) *rtspSource {
|
||||
return &rtspSource{
|
||||
readTimeout: readTimeout,
|
||||
writeTimeout: writeTimeout,
|
||||
readBufferCount: readBufferCount,
|
||||
parent: parent,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *rtspSource) Log(level logger.Level, format string, args ...interface{}) {
|
||||
s.parent.Log(level, "[rtsp source] "+format, args...)
|
||||
}
|
||||
|
||||
func createRangeHeader(cnf *conf.PathConf) (*headers.Range, error) {
|
||||
switch cnf.RtspRangeType {
|
||||
case conf.RtspRangeTypeClock:
|
||||
@ -95,33 +59,44 @@ func createRangeHeader(cnf *conf.PathConf) (*headers.Range, error) {
|
||||
}
|
||||
}
|
||||
|
||||
type rtspSourceParent interface {
|
||||
logger.Writer
|
||||
sourceStaticImplSetReady(req pathSourceStaticSetReadyReq) pathSourceStaticSetReadyRes
|
||||
sourceStaticImplSetNotReady(req pathSourceStaticSetNotReadyReq)
|
||||
}
|
||||
|
||||
type rtspSource struct {
|
||||
readTimeout conf.StringDuration
|
||||
writeTimeout conf.StringDuration
|
||||
readBufferCount int
|
||||
parent rtspSourceParent
|
||||
}
|
||||
|
||||
func newRTSPSource(
|
||||
readTimeout conf.StringDuration,
|
||||
writeTimeout conf.StringDuration,
|
||||
readBufferCount int,
|
||||
parent rtspSourceParent,
|
||||
) *rtspSource {
|
||||
return &rtspSource{
|
||||
readTimeout: readTimeout,
|
||||
writeTimeout: writeTimeout,
|
||||
readBufferCount: readBufferCount,
|
||||
parent: parent,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *rtspSource) Log(level logger.Level, format string, args ...interface{}) {
|
||||
s.parent.Log(level, "[rtsp source] "+format, args...)
|
||||
}
|
||||
|
||||
// run implements sourceStaticImpl.
|
||||
func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan *conf.PathConf) error {
|
||||
s.Log(logger.Debug, "connecting")
|
||||
|
||||
var tlsConfig *tls.Config
|
||||
if cnf.SourceFingerprint != "" {
|
||||
tlsConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||
h := sha256.New()
|
||||
h.Write(cs.PeerCertificates[0].Raw)
|
||||
hstr := hex.EncodeToString(h.Sum(nil))
|
||||
fingerprintLower := strings.ToLower(cnf.SourceFingerprint)
|
||||
|
||||
if hstr != fingerprintLower {
|
||||
return fmt.Errorf("server fingerprint do not match: expected %s, got %s",
|
||||
fingerprintLower, hstr)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
c := &gortsplib.Client{
|
||||
Transport: cnf.SourceProtocol.Transport,
|
||||
TLSConfig: tlsConfig,
|
||||
TLSConfig: tlsConfigForFingerprint(cnf.SourceFingerprint),
|
||||
ReadTimeout: time.Duration(s.readTimeout),
|
||||
WriteTimeout: time.Duration(s.writeTimeout),
|
||||
ReadBufferCount: s.readBufferCount,
|
||||
|
@ -43,7 +43,9 @@ func TestRTSPSource(t *testing.T) {
|
||||
t.Run(source, func(t *testing.T) {
|
||||
medi := testMediaH264
|
||||
stream := gortsplib.NewServerStream(media.Medias{medi})
|
||||
nonce := auth.GenerateNonce()
|
||||
|
||||
nonce, err := auth.GenerateNonce()
|
||||
require.NoError(t, err)
|
||||
|
||||
s := gortsplib.Server{
|
||||
Handler: &testServer{
|
||||
@ -112,7 +114,7 @@ func TestRTSPSource(t *testing.T) {
|
||||
s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
|
||||
}
|
||||
|
||||
err := s.Start()
|
||||
err = s.Start()
|
||||
require.NoError(t, err)
|
||||
defer s.Wait()
|
||||
defer s.Close()
|
||||
@ -167,7 +169,10 @@ func TestRTSPSource(t *testing.T) {
|
||||
|
||||
func TestRTSPSourceNoPassword(t *testing.T) {
|
||||
stream := gortsplib.NewServerStream(media.Medias{testMediaH264})
|
||||
nonce := auth.GenerateNonce()
|
||||
|
||||
nonce, err := auth.GenerateNonce()
|
||||
require.NoError(t, err)
|
||||
|
||||
done := make(chan struct{})
|
||||
|
||||
s := gortsplib.Server{
|
||||
@ -201,7 +206,7 @@ func TestRTSPSourceNoPassword(t *testing.T) {
|
||||
},
|
||||
RTSPAddress: "127.0.0.1:8555",
|
||||
}
|
||||
err := s.Start()
|
||||
err = s.Start()
|
||||
require.NoError(t, err)
|
||||
defer s.Wait()
|
||||
defer s.Close()
|
||||
|
@ -131,7 +131,7 @@ func gatherIncomingTracks(
|
||||
}
|
||||
|
||||
type webRTCSessionPathManager interface {
|
||||
publisherAdd(req pathPublisherAddReq) pathPublisherAnnounceRes
|
||||
publisherAdd(req pathPublisherAddReq) pathPublisherAddRes
|
||||
readerAdd(req pathReaderAddReq) pathReaderSetupPlayRes
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user