diff --git a/machinery/go.mod b/machinery/go.mod index 850fb614..5bd543ed 100644 --- a/machinery/go.mod +++ b/machinery/go.mod @@ -2,7 +2,7 @@ module github.com/kerberos-io/agent/machinery go 1.19 -//replace github.com/kerberos-io/joy4 v1.0.60 => ../../../../github.com/kerberos-io/joy4 +//replace github.com/kerberos-io/joy4 v1.0.63 => ../../../../github.com/kerberos-io/joy4 // replace github.com/kerberos-io/onvif v0.0.6 => ../../../../github.com/kerberos-io/onvif @@ -26,7 +26,7 @@ require ( github.com/golang-module/carbon/v2 v2.2.3 github.com/gorilla/websocket v1.5.0 github.com/kellydunn/golang-geo v0.7.0 - github.com/kerberos-io/joy4 v1.0.63 + github.com/kerberos-io/joy4 v1.0.64 github.com/kerberos-io/onvif v0.0.7 github.com/minio/minio-go/v6 v6.0.57 github.com/nsmith5/mjpeg v0.0.0-20200913181537-54b8ada0e53e diff --git a/machinery/go.sum b/machinery/go.sum index 3f9a333b..d40a558d 100644 --- a/machinery/go.sum +++ b/machinery/go.sum @@ -264,8 +264,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kellydunn/golang-geo v0.7.0 h1:A5j0/BvNgGwY6Yb6inXQxzYwlPHc6WVZR+MrarZYNNg= github.com/kellydunn/golang-geo v0.7.0/go.mod h1:YYlQPJ+DPEzrHx8kT3oPHC/NjyvCCXE+IuKGKdrjrcU= -github.com/kerberos-io/joy4 v1.0.63 h1:1VucVzE+WojpWWVKxpVpjmnArnZ2XIQSqn9Sldm6PrE= -github.com/kerberos-io/joy4 v1.0.63/go.mod h1:nZp4AjvKvTOXRrmDyAIOw+Da+JA5OcSo/JundGfOlFU= +github.com/kerberos-io/joy4 v1.0.64 h1:gTUSotHSOhp9mNqEecgq88tQHvpj7TjmrvPUsPm0idg= +github.com/kerberos-io/joy4 v1.0.64/go.mod h1:nZp4AjvKvTOXRrmDyAIOw+Da+JA5OcSo/JundGfOlFU= github.com/kerberos-io/onvif v0.0.7 h1:LIrXjTH7G2W9DN69xZeJSB0uS3W1+C3huFO8kTqx7/A= github.com/kerberos-io/onvif v0.0.7/go.mod h1:Hr2dJOH2LM5SpYKk17gYZ1CMjhGhUl+QlT5kwYogrW0= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= diff --git a/machinery/src/capture/IPCamera.go b/machinery/src/capture/IPCamera.go index b109bcc7..8108d183 100644 --- a/machinery/src/capture/IPCamera.go +++ b/machinery/src/capture/IPCamera.go @@ -16,12 +16,27 @@ import ( "github.com/kerberos-io/joy4/format" ) -func OpenRTSP(ctx context.Context, url string) (av.DemuxCloser, []av.CodecData, error) { +func OpenRTSP(ctx context.Context, url string, withBackChannel bool) (av.DemuxCloser, []av.CodecData, error) { format.RegisterAll() - infile, err := avutil.Open(ctx, url) + + // Try with backchannel first (if variable is set to true) + // If set to true, it will try to open the stream with a backchannel + // If fails we will try again (see below). + infile, err := avutil.Open(ctx, url, withBackChannel) if err == nil { streams, errstreams := infile.Streams() - return infile, streams, errstreams + if len(streams) > 0 { + return infile, streams, errstreams + } else { + // Try again without backchannel + log.Log.Info("OpenRTSP: trying without backchannel") + withBackChannel = false + infile, err := avutil.Open(ctx, url, withBackChannel) + if err == nil { + streams, errstreams := infile.Streams() + return infile, streams, errstreams + } + } } return nil, []av.CodecData{}, err } diff --git a/machinery/src/capture/main.go b/machinery/src/capture/main.go index ff2512d0..31de56d7 100644 --- a/machinery/src/capture/main.go +++ b/machinery/src/capture/main.go @@ -469,7 +469,7 @@ func VerifyCamera(c *gin.Context) { if streamType == "secondary" { rtspUrl = cameraStreams.SubRTSP } - _, codecs, err := OpenRTSP(ctx, rtspUrl) + _, codecs, err := OpenRTSP(ctx, rtspUrl, true) if err == nil { videoIdx := -1 diff --git a/machinery/src/components/Kerberos.go b/machinery/src/components/Kerberos.go index 51eca14c..a10d5416 100644 --- a/machinery/src/components/Kerberos.go +++ b/machinery/src/components/Kerberos.go @@ -118,9 +118,14 @@ func RunAgent(configDirectory string, configuration *models.Configuration, commu status := "not started" // Currently only support H264 encoded cameras, this will change. - // Establishing the camera connection + // Establishing the camera connection without backchannel if no substream rtspUrl := config.Capture.IPCamera.RTSP - infile, streams, err := capture.OpenRTSP(context.Background(), rtspUrl) + withBackChannel := true + subRtspUrl := config.Capture.IPCamera.SubRTSP + if subRtspUrl != "" && subRtspUrl != rtspUrl { + withBackChannel = false + } + infile, streams, err := capture.OpenRTSP(context.Background(), rtspUrl, withBackChannel) // We will initialise the camera settings object // so we can check if the camera settings have changed, and we need @@ -157,7 +162,7 @@ func RunAgent(configDirectory string, configuration *models.Configuration, commu subStreamEnabled := false subRtspUrl := config.Capture.IPCamera.SubRTSP if subRtspUrl != "" && subRtspUrl != rtspUrl { - subInfile, subStreams, err = capture.OpenRTSP(context.Background(), subRtspUrl) + subInfile, subStreams, err = capture.OpenRTSP(context.Background(), subRtspUrl, true) // We'll try to enable backchannel for the substream. if err == nil { log.Log.Info("RunAgent: opened RTSP sub stream " + subRtspUrl) subStreamEnabled = true diff --git a/machinery/src/onvif/main.go b/machinery/src/onvif/main.go index c6b90d06..fab04175 100644 --- a/machinery/src/onvif/main.go +++ b/machinery/src/onvif/main.go @@ -751,24 +751,6 @@ func GoToPresetFromDevice(device *onvif.Device, presetName string) error { return err } -func getXMLNode(xmlBody string, nodeName string) (*xml.Decoder, *xml.StartElement, error) { - xmlBytes := bytes.NewBufferString(xmlBody) - decodedXML := xml.NewDecoder(xmlBytes) - for { - token, err := decodedXML.Token() - if err != nil { - break - } - switch et := token.(type) { - case xml.StartElement: - if et.Name.Local == nodeName { - return decodedXML, &et, nil - } - } - } - return nil, nil, errors.New("error in NodeName - username and password might be wrong") -} - func GetPTZFunctionsFromDevice(configurations ptz.GetConfigurationsResponse) ([]string, bool, bool) { var functions []string canZoom := false @@ -854,3 +836,21 @@ func VerifyOnvifConnection(c *gin.Context) { }) } } + +func getXMLNode(xmlBody string, nodeName string) (*xml.Decoder, *xml.StartElement, error) { + xmlBytes := bytes.NewBufferString(xmlBody) + decodedXML := xml.NewDecoder(xmlBytes) + for { + token, err := decodedXML.Token() + if err != nil { + break + } + switch et := token.(type) { + case xml.StartElement: + if et.Name.Local == nodeName { + return decodedXML, &et, nil + } + } + } + return nil, nil, errors.New("error in NodeName - username and password might be wrong") +}