2021-07-24 13:55:42 +00:00
|
|
|
package core
|
2020-10-19 20:17:48 +00:00
|
|
|
|
|
|
|
import (
|
2021-05-10 19:32:59 +00:00
|
|
|
"context"
|
2020-10-19 20:17:48 +00:00
|
|
|
"fmt"
|
2021-05-07 21:07:31 +00:00
|
|
|
"net"
|
2020-10-19 20:17:48 +00:00
|
|
|
"sync"
|
|
|
|
|
2021-05-07 21:07:31 +00:00
|
|
|
"github.com/aler9/gortsplib/pkg/base"
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2020-11-01 21:56:56 +00:00
|
|
|
"github.com/aler9/rtsp-simple-server/internal/conf"
|
2020-12-08 11:21:06 +00:00
|
|
|
"github.com/aler9/rtsp-simple-server/internal/logger"
|
2020-10-19 20:17:48 +00:00
|
|
|
)
|
|
|
|
|
2021-08-11 10:45:53 +00:00
|
|
|
type pathManagerHLSServer interface {
|
2021-10-27 19:01:00 +00:00
|
|
|
onPathSourceReady(pa *path)
|
2021-08-11 10:45:53 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
type pathManagerParent interface {
|
2020-12-08 11:21:06 +00:00
|
|
|
Log(logger.Level, string, ...interface{})
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
type pathManager struct {
|
2021-04-24 16:25:19 +00:00
|
|
|
rtspAddress string
|
2021-09-26 21:06:40 +00:00
|
|
|
readTimeout conf.StringDuration
|
|
|
|
writeTimeout conf.StringDuration
|
2021-02-18 22:26:45 +00:00
|
|
|
readBufferCount int
|
|
|
|
readBufferSize int
|
2021-01-10 11:55:53 +00:00
|
|
|
pathConfs map[string]*conf.PathConf
|
2021-08-12 09:48:47 +00:00
|
|
|
metrics *metrics
|
2021-07-24 13:55:42 +00:00
|
|
|
parent pathManagerParent
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
ctx context.Context
|
|
|
|
ctxCancel func()
|
|
|
|
wg sync.WaitGroup
|
2021-08-11 10:45:53 +00:00
|
|
|
hlsServer pathManagerHLSServer
|
2021-07-24 13:55:42 +00:00
|
|
|
paths map[string]*path
|
2020-10-19 20:17:48 +00:00
|
|
|
|
|
|
|
// in
|
2021-07-31 18:46:06 +00:00
|
|
|
confReload chan map[string]*conf.PathConf
|
|
|
|
pathClose chan *path
|
|
|
|
pathSourceReady chan *path
|
|
|
|
describe chan pathDescribeReq
|
|
|
|
readerSetupPlay chan pathReaderSetupPlayReq
|
|
|
|
publisherAnnounce chan pathPublisherAnnounceReq
|
2021-08-11 10:45:53 +00:00
|
|
|
hlsServerSet chan pathManagerHLSServer
|
2021-11-05 16:53:24 +00:00
|
|
|
apiPathsList chan pathAPIPathsListReq
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
func newPathManager(
|
|
|
|
parentCtx context.Context,
|
2021-04-24 16:25:19 +00:00
|
|
|
rtspAddress string,
|
2021-09-26 21:06:40 +00:00
|
|
|
readTimeout conf.StringDuration,
|
|
|
|
writeTimeout conf.StringDuration,
|
2021-02-18 22:26:45 +00:00
|
|
|
readBufferCount int,
|
|
|
|
readBufferSize int,
|
2020-10-24 17:55:47 +00:00
|
|
|
pathConfs map[string]*conf.PathConf,
|
2021-08-12 09:48:47 +00:00
|
|
|
metrics *metrics,
|
2021-07-24 13:55:42 +00:00
|
|
|
parent pathManagerParent) *pathManager {
|
|
|
|
ctx, ctxCancel := context.WithCancel(parentCtx)
|
2021-05-10 19:32:59 +00:00
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
pm := &pathManager{
|
2021-07-31 18:46:06 +00:00
|
|
|
rtspAddress: rtspAddress,
|
|
|
|
readTimeout: readTimeout,
|
|
|
|
writeTimeout: writeTimeout,
|
|
|
|
readBufferCount: readBufferCount,
|
|
|
|
readBufferSize: readBufferSize,
|
|
|
|
pathConfs: pathConfs,
|
2021-08-12 09:48:47 +00:00
|
|
|
metrics: metrics,
|
2021-07-31 18:46:06 +00:00
|
|
|
parent: parent,
|
|
|
|
ctx: ctx,
|
|
|
|
ctxCancel: ctxCancel,
|
|
|
|
paths: make(map[string]*path),
|
|
|
|
confReload: make(chan map[string]*conf.PathConf),
|
|
|
|
pathClose: make(chan *path),
|
|
|
|
pathSourceReady: make(chan *path),
|
|
|
|
describe: make(chan pathDescribeReq),
|
|
|
|
readerSetupPlay: make(chan pathReaderSetupPlayReq),
|
|
|
|
publisherAnnounce: make(chan pathPublisherAnnounceReq),
|
2021-08-11 10:45:53 +00:00
|
|
|
hlsServerSet: make(chan pathManagerHLSServer),
|
2021-11-05 16:53:24 +00:00
|
|
|
apiPathsList: make(chan pathAPIPathsListReq),
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-08-01 15:22:28 +00:00
|
|
|
for pathName, pathConf := range pm.pathConfs {
|
|
|
|
if pathConf.Regexp == nil {
|
|
|
|
pm.createPath(pathName, pathConf, pathName)
|
|
|
|
}
|
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2021-08-12 09:48:47 +00:00
|
|
|
if pm.metrics != nil {
|
2021-10-27 19:01:00 +00:00
|
|
|
pm.metrics.onPathManagerSet(pm)
|
2021-08-12 09:48:47 +00:00
|
|
|
}
|
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
pm.wg.Add(1)
|
2020-10-19 20:17:48 +00:00
|
|
|
go pm.run()
|
2021-05-10 19:32:59 +00:00
|
|
|
|
2020-10-19 20:17:48 +00:00
|
|
|
return pm
|
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
func (pm *pathManager) close() {
|
2021-05-10 19:32:59 +00:00
|
|
|
pm.ctxCancel()
|
|
|
|
pm.wg.Wait()
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2020-11-05 11:30:25 +00:00
|
|
|
// Log is the main logging function.
|
2021-10-27 19:01:00 +00:00
|
|
|
func (pm *pathManager) log(level logger.Level, format string, args ...interface{}) {
|
2020-12-08 11:21:06 +00:00
|
|
|
pm.parent.Log(level, format, args...)
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
func (pm *pathManager) run() {
|
2021-05-10 19:32:59 +00:00
|
|
|
defer pm.wg.Done()
|
2020-10-19 20:17:48 +00:00
|
|
|
|
|
|
|
outer:
|
|
|
|
for {
|
|
|
|
select {
|
2020-10-24 17:55:47 +00:00
|
|
|
case pathConfs := <-pm.confReload:
|
|
|
|
// remove confs
|
|
|
|
for pathName := range pm.pathConfs {
|
|
|
|
if _, ok := pathConfs[pathName]; !ok {
|
|
|
|
delete(pm.pathConfs, pathName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// update confs
|
|
|
|
for pathName, oldConf := range pm.pathConfs {
|
|
|
|
if !oldConf.Equal(pathConfs[pathName]) {
|
|
|
|
pm.pathConfs[pathName] = pathConfs[pathName]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add confs
|
|
|
|
for pathName, pathConf := range pathConfs {
|
|
|
|
if _, ok := pm.pathConfs[pathName]; !ok {
|
|
|
|
pm.pathConfs[pathName] = pathConf
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove paths associated with a conf which doesn't exist anymore
|
|
|
|
// or has changed
|
|
|
|
for _, pa := range pm.paths {
|
2020-11-08 21:07:15 +00:00
|
|
|
if pathConf, ok := pm.pathConfs[pa.ConfName()]; !ok || pathConf != pa.Conf() {
|
2020-10-24 17:55:47 +00:00
|
|
|
delete(pm.paths, pa.Name())
|
2021-10-27 19:01:00 +00:00
|
|
|
pa.close()
|
2020-10-24 17:55:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-01 15:22:28 +00:00
|
|
|
// add new paths
|
|
|
|
for pathName, pathConf := range pm.pathConfs {
|
|
|
|
if _, ok := pm.paths[pathName]; !ok && pathConf.Regexp == nil {
|
|
|
|
pm.createPath(pathName, pathConf, pathName)
|
|
|
|
}
|
|
|
|
}
|
2020-10-24 17:55:47 +00:00
|
|
|
|
2020-10-19 20:17:48 +00:00
|
|
|
case pa := <-pm.pathClose:
|
2021-05-10 19:32:59 +00:00
|
|
|
if pmpa, ok := pm.paths[pa.Name()]; !ok || pmpa != pa {
|
2020-10-24 17:55:47 +00:00
|
|
|
continue
|
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
delete(pm.paths, pa.Name())
|
2021-10-27 19:01:00 +00:00
|
|
|
pa.close()
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2021-07-30 12:49:09 +00:00
|
|
|
case pa := <-pm.pathSourceReady:
|
|
|
|
if pm.hlsServer != nil {
|
2021-10-27 19:01:00 +00:00
|
|
|
pm.hlsServer.onPathSourceReady(pa)
|
2021-07-30 12:49:09 +00:00
|
|
|
}
|
|
|
|
|
2021-07-31 18:46:06 +00:00
|
|
|
case req := <-pm.describe:
|
2020-10-24 17:55:47 +00:00
|
|
|
pathName, pathConf, err := pm.findPathConf(req.PathName)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res <- pathDescribeRes{Err: err}
|
2020-10-19 20:17:48 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-05-07 21:07:31 +00:00
|
|
|
err = pm.authenticate(
|
|
|
|
req.IP,
|
|
|
|
req.ValidateCredentials,
|
2021-03-10 14:06:45 +00:00
|
|
|
req.PathName,
|
2021-09-27 08:36:28 +00:00
|
|
|
pathConf.ReadIPs,
|
2021-03-10 14:06:45 +00:00
|
|
|
pathConf.ReadUser,
|
|
|
|
pathConf.ReadPass,
|
2021-05-07 21:07:31 +00:00
|
|
|
)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res <- pathDescribeRes{Err: err}
|
2020-10-19 20:17:48 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// create path if it doesn't exist
|
|
|
|
if _, ok := pm.paths[req.PathName]; !ok {
|
2021-03-10 14:06:45 +00:00
|
|
|
pm.createPath(pathName, pathConf, req.PathName)
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-08-01 15:22:28 +00:00
|
|
|
req.Res <- pathDescribeRes{Path: pm.paths[req.PathName]}
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2021-07-31 18:46:06 +00:00
|
|
|
case req := <-pm.readerSetupPlay:
|
2020-10-24 17:55:47 +00:00
|
|
|
pathName, pathConf, err := pm.findPathConf(req.PathName)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res <- pathReaderSetupPlayRes{Err: err}
|
2020-10-19 20:17:48 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-05-07 21:07:31 +00:00
|
|
|
err = pm.authenticate(
|
|
|
|
req.IP,
|
|
|
|
req.ValidateCredentials,
|
2021-03-10 14:06:45 +00:00
|
|
|
req.PathName,
|
2021-09-27 08:36:28 +00:00
|
|
|
pathConf.ReadIPs,
|
2021-03-10 14:06:45 +00:00
|
|
|
pathConf.ReadUser,
|
|
|
|
pathConf.ReadPass,
|
2021-05-07 21:07:31 +00:00
|
|
|
)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res <- pathReaderSetupPlayRes{Err: err}
|
2020-10-19 20:17:48 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// create path if it doesn't exist
|
|
|
|
if _, ok := pm.paths[req.PathName]; !ok {
|
2021-03-10 14:06:45 +00:00
|
|
|
pm.createPath(pathName, pathConf, req.PathName)
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-08-01 15:22:28 +00:00
|
|
|
req.Res <- pathReaderSetupPlayRes{Path: pm.paths[req.PathName]}
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2021-07-31 18:46:06 +00:00
|
|
|
case req := <-pm.publisherAnnounce:
|
2021-01-31 11:23:54 +00:00
|
|
|
pathName, pathConf, err := pm.findPathConf(req.PathName)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res <- pathPublisherAnnounceRes{Err: err}
|
2020-10-19 20:17:48 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-05-07 21:07:31 +00:00
|
|
|
err = pm.authenticate(
|
|
|
|
req.IP,
|
|
|
|
req.ValidateCredentials,
|
2021-02-18 22:26:45 +00:00
|
|
|
req.PathName,
|
2021-09-27 08:36:28 +00:00
|
|
|
pathConf.PublishIPs,
|
2021-03-10 14:06:45 +00:00
|
|
|
pathConf.PublishUser,
|
|
|
|
pathConf.PublishPass,
|
2021-05-07 21:07:31 +00:00
|
|
|
)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res <- pathPublisherAnnounceRes{Err: err}
|
2020-10-19 20:17:48 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-01-31 11:23:54 +00:00
|
|
|
// create path if it doesn't exist
|
|
|
|
if _, ok := pm.paths[req.PathName]; !ok {
|
2021-03-10 14:06:45 +00:00
|
|
|
pm.createPath(pathName, pathConf, req.PathName)
|
2021-01-31 11:23:54 +00:00
|
|
|
}
|
|
|
|
|
2021-08-01 15:22:28 +00:00
|
|
|
req.Res <- pathPublisherAnnounceRes{Path: pm.paths[req.PathName]}
|
2020-10-19 20:17:48 +00:00
|
|
|
|
2021-07-30 12:49:09 +00:00
|
|
|
case s := <-pm.hlsServerSet:
|
|
|
|
pm.hlsServer = s
|
|
|
|
|
2021-07-04 16:13:49 +00:00
|
|
|
case req := <-pm.apiPathsList:
|
|
|
|
paths := make(map[string]*path)
|
|
|
|
|
|
|
|
for name, pa := range pm.paths {
|
|
|
|
paths[name] = pa
|
|
|
|
}
|
|
|
|
|
2021-11-05 16:53:24 +00:00
|
|
|
req.Res <- pathAPIPathsListRes{
|
2021-07-04 16:13:49 +00:00
|
|
|
Paths: paths,
|
|
|
|
}
|
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
case <-pm.ctx.Done():
|
2020-10-19 20:17:48 +00:00
|
|
|
break outer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
pm.ctxCancel()
|
2021-08-12 09:48:47 +00:00
|
|
|
|
|
|
|
if pm.metrics != nil {
|
2021-10-27 19:01:00 +00:00
|
|
|
pm.metrics.onPathManagerSet(nil)
|
2021-08-12 09:48:47 +00:00
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
func (pm *pathManager) createPath(confName string, conf *conf.PathConf, name string) {
|
|
|
|
pm.paths[name] = newPath(
|
2021-05-11 15:20:32 +00:00
|
|
|
pm.ctx,
|
2021-04-24 16:25:19 +00:00
|
|
|
pm.rtspAddress,
|
2021-02-18 22:26:45 +00:00
|
|
|
pm.readTimeout,
|
|
|
|
pm.writeTimeout,
|
|
|
|
pm.readBufferCount,
|
|
|
|
pm.readBufferSize,
|
|
|
|
confName,
|
|
|
|
conf,
|
|
|
|
name,
|
|
|
|
&pm.wg,
|
|
|
|
pm)
|
|
|
|
}
|
|
|
|
|
2021-07-24 13:55:42 +00:00
|
|
|
func (pm *pathManager) findPathConf(name string) (string, *conf.PathConf, error) {
|
2021-09-26 13:50:35 +00:00
|
|
|
err := conf.IsValidPathName(name)
|
2020-10-19 20:17:48 +00:00
|
|
|
if err != nil {
|
2020-10-24 17:55:47 +00:00
|
|
|
return "", nil, fmt.Errorf("invalid path name: %s (%s)", err, name)
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// normal path
|
2020-10-24 17:55:47 +00:00
|
|
|
if pathConf, ok := pm.pathConfs[name]; ok {
|
|
|
|
return name, pathConf, nil
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// regular expression path
|
2020-10-24 17:55:47 +00:00
|
|
|
for pathName, pathConf := range pm.pathConfs {
|
2020-10-19 20:17:48 +00:00
|
|
|
if pathConf.Regexp != nil && pathConf.Regexp.MatchString(name) {
|
2020-10-24 17:55:47 +00:00
|
|
|
return pathName, pathConf, nil
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-06 11:51:38 +00:00
|
|
|
return "", nil, fmt.Errorf("path '%s' is not configured", name)
|
2020-10-24 17:55:47 +00:00
|
|
|
}
|
|
|
|
|
2021-07-30 18:13:17 +00:00
|
|
|
func (pm *pathManager) authenticate(
|
|
|
|
ip net.IP,
|
2021-09-27 13:45:51 +00:00
|
|
|
validateCredentials func(pathUser conf.Credential, pathPass conf.Credential) error,
|
2021-07-30 18:13:17 +00:00
|
|
|
pathName string,
|
|
|
|
pathIPs []interface{},
|
2021-09-27 13:45:51 +00:00
|
|
|
pathUser conf.Credential,
|
|
|
|
pathPass conf.Credential,
|
2021-07-30 18:13:17 +00:00
|
|
|
) error {
|
|
|
|
// validate ip
|
|
|
|
if pathIPs != nil && ip != nil {
|
|
|
|
if !ipEqualOrInRange(ip, pathIPs) {
|
2021-07-31 18:46:06 +00:00
|
|
|
return pathErrAuthCritical{
|
2021-07-30 18:13:17 +00:00
|
|
|
Message: fmt.Sprintf("IP '%s' not allowed", ip),
|
|
|
|
Response: &base.Response{
|
|
|
|
StatusCode: base.StatusUnauthorized,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// validate user
|
|
|
|
if pathUser != "" && validateCredentials != nil {
|
2021-08-01 14:56:53 +00:00
|
|
|
err := validateCredentials(pathUser, pathPass)
|
2021-07-30 18:13:17 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onConfReload is called by core.
|
|
|
|
func (pm *pathManager) onConfReload(pathConfs map[string]*conf.PathConf) {
|
2021-05-10 19:32:59 +00:00
|
|
|
select {
|
|
|
|
case pm.confReload <- pathConfs:
|
|
|
|
case <-pm.ctx.Done():
|
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onPathSourceReady is called by path.
|
|
|
|
func (pm *pathManager) onPathSourceReady(pa *path) {
|
2021-07-30 12:49:09 +00:00
|
|
|
select {
|
|
|
|
case pm.pathSourceReady <- pa:
|
|
|
|
case <-pm.ctx.Done():
|
|
|
|
}
|
2021-07-29 14:56:40 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onPathClose is called by path.
|
|
|
|
func (pm *pathManager) onPathClose(pa *path) {
|
2021-05-10 19:32:59 +00:00
|
|
|
select {
|
|
|
|
case pm.pathClose <- pa:
|
|
|
|
case <-pm.ctx.Done():
|
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onDescribe is called by a reader or publisher.
|
|
|
|
func (pm *pathManager) onDescribe(req pathDescribeReq) pathDescribeRes {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res = make(chan pathDescribeRes)
|
2021-05-10 19:32:59 +00:00
|
|
|
select {
|
2021-07-31 18:46:06 +00:00
|
|
|
case pm.describe <- req:
|
2021-08-01 15:22:28 +00:00
|
|
|
res := <-req.Res
|
|
|
|
if res.Err != nil {
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
return res.Path.onDescribe(req)
|
2021-08-01 15:22:28 +00:00
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
case <-pm.ctx.Done():
|
2021-07-31 18:46:06 +00:00
|
|
|
return pathDescribeRes{Err: fmt.Errorf("terminated")}
|
2021-05-10 19:32:59 +00:00
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onPublisherAnnounce is called by a publisher.
|
|
|
|
func (pm *pathManager) onPublisherAnnounce(req pathPublisherAnnounceReq) pathPublisherAnnounceRes {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res = make(chan pathPublisherAnnounceRes)
|
2021-05-10 19:32:59 +00:00
|
|
|
select {
|
2021-07-31 18:46:06 +00:00
|
|
|
case pm.publisherAnnounce <- req:
|
2021-08-01 15:22:28 +00:00
|
|
|
res := <-req.Res
|
|
|
|
if res.Err != nil {
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
return res.Path.onPublisherAnnounce(req)
|
2021-08-01 15:22:28 +00:00
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
case <-pm.ctx.Done():
|
2021-07-31 18:46:06 +00:00
|
|
|
return pathPublisherAnnounceRes{Err: fmt.Errorf("terminated")}
|
2021-05-10 19:32:59 +00:00
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onReaderSetupPlay is called by a reader.
|
|
|
|
func (pm *pathManager) onReaderSetupPlay(req pathReaderSetupPlayReq) pathReaderSetupPlayRes {
|
2021-07-31 18:46:06 +00:00
|
|
|
req.Res = make(chan pathReaderSetupPlayRes)
|
2021-05-10 19:32:59 +00:00
|
|
|
select {
|
2021-07-31 18:46:06 +00:00
|
|
|
case pm.readerSetupPlay <- req:
|
2021-08-01 15:22:28 +00:00
|
|
|
res := <-req.Res
|
|
|
|
if res.Err != nil {
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
return res.Path.onReaderSetupPlay(req)
|
2021-08-01 15:22:28 +00:00
|
|
|
|
2021-05-10 19:32:59 +00:00
|
|
|
case <-pm.ctx.Done():
|
2021-07-31 18:46:06 +00:00
|
|
|
return pathReaderSetupPlayRes{Err: fmt.Errorf("terminated")}
|
2021-05-10 19:32:59 +00:00
|
|
|
}
|
2020-10-19 20:17:48 +00:00
|
|
|
}
|
2021-05-07 21:07:31 +00:00
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onHLSServerSet is called by hlsServer.
|
|
|
|
func (pm *pathManager) onHLSServerSet(s pathManagerHLSServer) {
|
2021-07-30 12:49:09 +00:00
|
|
|
select {
|
|
|
|
case pm.hlsServerSet <- s:
|
|
|
|
case <-pm.ctx.Done():
|
|
|
|
}
|
|
|
|
}
|
2021-07-04 16:13:49 +00:00
|
|
|
|
2021-10-27 19:01:00 +00:00
|
|
|
// onAPIPathsList is called by api.
|
2021-11-05 16:53:24 +00:00
|
|
|
func (pm *pathManager) onAPIPathsList(req pathAPIPathsListReq) pathAPIPathsListRes {
|
|
|
|
req.Res = make(chan pathAPIPathsListRes)
|
2021-07-04 16:13:49 +00:00
|
|
|
select {
|
|
|
|
case pm.apiPathsList <- req:
|
2021-11-05 16:14:31 +00:00
|
|
|
res := <-req.Res
|
2021-08-12 09:48:47 +00:00
|
|
|
|
2021-11-05 16:53:24 +00:00
|
|
|
res.Data = &pathAPIPathsListData{
|
|
|
|
Items: make(map[string]pathAPIPathsListItem),
|
2021-08-12 09:48:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-05 16:14:31 +00:00
|
|
|
for _, pa := range res.Paths {
|
2021-11-05 16:53:24 +00:00
|
|
|
pa.onAPIPathsList(pathAPIPathsListSubReq{Data: res.Data})
|
2021-08-12 09:48:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-05 16:14:31 +00:00
|
|
|
return res
|
2021-08-12 09:48:47 +00:00
|
|
|
|
2021-07-04 16:13:49 +00:00
|
|
|
case <-pm.ctx.Done():
|
2021-11-05 16:53:24 +00:00
|
|
|
return pathAPIPathsListRes{Err: fmt.Errorf("terminated")}
|
2021-07-04 16:13:49 +00:00
|
|
|
}
|
|
|
|
}
|