api: add tunnel and profile to RTSP conns and sessions (#4985)

This commit is contained in:
Alessandro Ros
2025-09-17 22:18:21 +02:00
committed by GitHub
parent 890d4272cd
commit 558d1c3818
8 changed files with 54 additions and 6 deletions

View File

@@ -746,6 +746,8 @@ components:
session: session:
type: string type: string
nullable: true nullable: true
tunnel:
type: string
RTSPConnList: RTSPConnList:
type: object type: object
@@ -780,6 +782,9 @@ components:
transport: transport:
type: string type: string
nullable: true nullable: true
profile:
type: string
nullable: true
bytesReceived: bytesReceived:
type: integer type: integer
format: int64 format: int64

2
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/asticode/go-astits v1.13.0 github.com/asticode/go-astits v1.13.0
github.com/bluenviron/gohlslib/v2 v2.2.3 github.com/bluenviron/gohlslib/v2 v2.2.3
github.com/bluenviron/gortmplib v0.0.0-20250916095243-72b6eaffb6a4 github.com/bluenviron/gortmplib v0.0.0-20250916095243-72b6eaffb6a4
github.com/bluenviron/gortsplib/v5 v5.0.0-20250916102828-1616c8c63415 github.com/bluenviron/gortsplib/v5 v5.0.0-20250917174653-288b637b2301
github.com/bluenviron/mediacommon/v2 v2.4.2 github.com/bluenviron/mediacommon/v2 v2.4.2
github.com/datarhei/gosrt v0.9.0 github.com/datarhei/gosrt v0.9.0
github.com/fsnotify/fsnotify v1.9.0 github.com/fsnotify/fsnotify v1.9.0

4
go.sum
View File

@@ -35,8 +35,8 @@ github.com/bluenviron/gohlslib/v2 v2.2.3 h1:1R/Jnh1kNR9UB09KAX6xjS2GcdKFRLuPd9wM
github.com/bluenviron/gohlslib/v2 v2.2.3/go.mod h1:z4Viks+Mdgcl7OcOVJ1fgSmuUwCCJBxYJPLN49n7Vnw= github.com/bluenviron/gohlslib/v2 v2.2.3/go.mod h1:z4Viks+Mdgcl7OcOVJ1fgSmuUwCCJBxYJPLN49n7Vnw=
github.com/bluenviron/gortmplib v0.0.0-20250916095243-72b6eaffb6a4 h1:ZDsCiFpmOoEy2eWcJBEhV8jb0sA9MxO/BzYmyrmm4hE= github.com/bluenviron/gortmplib v0.0.0-20250916095243-72b6eaffb6a4 h1:ZDsCiFpmOoEy2eWcJBEhV8jb0sA9MxO/BzYmyrmm4hE=
github.com/bluenviron/gortmplib v0.0.0-20250916095243-72b6eaffb6a4/go.mod h1:73VbUEJLkaixSRPRI/imEkVRkBccvR1GKrd6SUOdkrQ= github.com/bluenviron/gortmplib v0.0.0-20250916095243-72b6eaffb6a4/go.mod h1:73VbUEJLkaixSRPRI/imEkVRkBccvR1GKrd6SUOdkrQ=
github.com/bluenviron/gortsplib/v5 v5.0.0-20250916102828-1616c8c63415 h1:FErClZLSuXkZEPfIsAtD4DH6CKmQ6z7gtod1eHi4Efg= github.com/bluenviron/gortsplib/v5 v5.0.0-20250917174653-288b637b2301 h1:dLEqNi4/uTN6lUM3djwWXhO0uqs9/TbRSg4AfDOJjH8=
github.com/bluenviron/gortsplib/v5 v5.0.0-20250916102828-1616c8c63415/go.mod h1:un/XrjuE+yaglJw4Fd75OUXowPxioaHHqNOUC28byFA= github.com/bluenviron/gortsplib/v5 v5.0.0-20250917174653-288b637b2301/go.mod h1:zp5tDI2tkjVMgyWiy+B2tRQowqYq/GwHjdAdYFQAxrU=
github.com/bluenviron/mediacommon/v2 v2.4.2 h1:rggs61nTaqPcR1+RhlIE8/nDqfF5PO57QxpxBzSFfrw= github.com/bluenviron/mediacommon/v2 v2.4.2 h1:rggs61nTaqPcR1+RhlIE8/nDqfF5PO57QxpxBzSFfrw=
github.com/bluenviron/mediacommon/v2 v2.4.2/go.mod h1:zy1fODPuS/kBd93ftgJS1Jhvjq7LFWfAo32KP7By9AE= github.com/bluenviron/mediacommon/v2 v2.4.2/go.mod h1:zy1fODPuS/kBd93ftgJS1Jhvjq7LFWfAo32KP7By9AE=
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=

View File

@@ -367,8 +367,7 @@ func TestAPIProtocolListGet(t *testing.T) {
switch ca { switch ca {
case "rtsps conns", "rtsps sessions": case "rtsps conns", "rtsps sessions":
conf += "rtspTransports: [tcp]\n" + conf += "rtspEncryption: strict\n" +
"rtspEncryption: strict\n" +
"rtspServerCert: " + serverCertFpath + "\n" + "rtspServerCert: " + serverCertFpath + "\n" +
"rtspServerKey: " + serverKeyFpath + "\n" "rtspServerKey: " + serverKeyFpath + "\n"
@@ -621,6 +620,7 @@ func TestAPIProtocolListGet(t *testing.T) {
"id": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["id"], "id": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["id"],
"remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"], "remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"],
"session": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["session"], "session": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["session"],
"tunnel": "none",
}, },
}, },
}, out1) }, out1)
@@ -640,6 +640,7 @@ func TestAPIProtocolListGet(t *testing.T) {
"remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"], "remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"],
"state": "publish", "state": "publish",
"transport": "UDP", "transport": "UDP",
"profile": "AVP",
"rtpPacketsReceived": float64(0), "rtpPacketsReceived": float64(0),
"rtpPacketsSent": float64(0), "rtpPacketsSent": float64(0),
"rtpPacketsLost": float64(0), "rtpPacketsLost": float64(0),
@@ -664,6 +665,7 @@ func TestAPIProtocolListGet(t *testing.T) {
"id": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["id"], "id": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["id"],
"remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"], "remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"],
"session": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["session"], "session": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["session"],
"tunnel": "none",
}, },
}, },
}, out1) }, out1)
@@ -682,7 +684,8 @@ func TestAPIProtocolListGet(t *testing.T) {
"query": "key=val", "query": "key=val",
"remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"], "remoteAddr": out1.(map[string]interface{})["items"].([]interface{})[0].(map[string]interface{})["remoteAddr"],
"state": "publish", "state": "publish",
"transport": "TCP", "transport": "UDP",
"profile": "SAVP",
"rtpPacketsReceived": float64(0), "rtpPacketsReceived": float64(0),
"rtpPacketsSent": float64(0), "rtpPacketsSent": float64(0),
"rtpPacketsLost": float64(0), "rtpPacketsLost": float64(0),

View File

@@ -140,6 +140,7 @@ type APIRTSPConn struct {
BytesReceived uint64 `json:"bytesReceived"` BytesReceived uint64 `json:"bytesReceived"`
BytesSent uint64 `json:"bytesSent"` BytesSent uint64 `json:"bytesSent"`
Session *uuid.UUID `json:"session"` Session *uuid.UUID `json:"session"`
Tunnel string `json:"tunnel"`
} }
// APIRTSPConnsList is a list of RTSP connections. // APIRTSPConnsList is a list of RTSP connections.
@@ -168,6 +169,7 @@ type APIRTSPSession struct {
Path string `json:"path"` Path string `json:"path"`
Query string `json:"query"` Query string `json:"query"`
Transport *string `json:"transport"` Transport *string `json:"transport"`
Profile *string `json:"profile"`
BytesReceived uint64 `json:"bytesReceived"` BytesReceived uint64 `json:"bytesReceived"`
BytesSent uint64 `json:"bytesSent"` BytesSent uint64 `json:"bytesSent"`
RTPPacketsReceived uint64 `json:"rtpPacketsReceived"` RTPPacketsReceived uint64 `json:"rtpPacketsReceived"`

View File

@@ -43,6 +43,18 @@ func credentialsProvided(req *base.Request) bool {
return err == nil && auth.Username != "" return err == nil && auth.Username != ""
} }
func tunnelLabel(t gortsplib.Tunnel) string {
switch t {
case gortsplib.TunnelHTTP:
return "http"
case gortsplib.TunnelWebSocket:
return "websocket"
case gortsplib.TunnelNone:
return "none"
}
return "unknown"
}
type connParent interface { type connParent interface {
logger.Writer logger.Writer
findSessionByRSessionUnsafe(rsession *gortsplib.ServerSession) *session findSessionByRSessionUnsafe(rsession *gortsplib.ServerSession) *session
@@ -229,5 +241,6 @@ func (c *conn) apiItem() *defs.APIRTSPConn {
} }
return nil return nil
}(), }(),
Tunnel: tunnelLabel(c.rconn.Transport().Tunnel),
} }
} }

View File

@@ -11,6 +11,7 @@ import (
"github.com/bluenviron/gortsplib/v5" "github.com/bluenviron/gortsplib/v5"
rtspauth "github.com/bluenviron/gortsplib/v5/pkg/auth" rtspauth "github.com/bluenviron/gortsplib/v5/pkg/auth"
"github.com/bluenviron/gortsplib/v5/pkg/base" "github.com/bluenviron/gortsplib/v5/pkg/base"
"github.com/bluenviron/gortsplib/v5/pkg/headers"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/bluenviron/mediamtx/internal/auth" "github.com/bluenviron/mediamtx/internal/auth"
@@ -24,6 +25,16 @@ import (
"github.com/bluenviron/mediamtx/internal/stream" "github.com/bluenviron/mediamtx/internal/stream"
) )
func profileLabel(p headers.TransportProfile) string {
switch p {
case headers.TransportProfileSAVP:
return "SAVP"
case headers.TransportProfileAVP:
return "AVP"
}
return "unknown"
}
type session struct { type session struct {
isTLS bool isTLS bool
transports conf.RTSPTransports transports conf.RTSPTransports
@@ -408,6 +419,14 @@ func (s *session) apiItem() *defs.APIRTSPSession {
v := transport.Protocol.String() v := transport.Protocol.String()
return &v return &v
}(), }(),
Profile: func() *string {
transport := s.rsession.Transport()
if transport == nil {
return nil
}
v := profileLabel(transport.Profile)
return &v
}(),
BytesReceived: stats.BytesReceived, BytesReceived: stats.BytesReceived,
BytesSent: stats.BytesSent, BytesSent: stats.BytesSent,
RTPPacketsReceived: stats.RTPPacketsReceived, RTPPacketsReceived: stats.RTPPacketsReceived,

View File

@@ -157,6 +157,12 @@ func TestAPIDocs(t *testing.T) {
case sf.Type == reflect.TypeOf(""): case sf.Type == reflect.TypeOf(""):
content2.Properties[js] = openAPIProperty{Type: "string"} content2.Properties[js] = openAPIProperty{Type: "string"}
case sf.Type == reflect.PointerTo(reflect.TypeOf("")):
content2.Properties[js] = openAPIProperty{
Type: "string",
Nullable: true,
}
case sf.Type == reflect.TypeOf(int(0)): case sf.Type == reflect.TypeOf(int(0)):
content2.Properties[js] = openAPIProperty{Type: "integer", Format: "int64"} content2.Properties[js] = openAPIProperty{Type: "integer", Format: "int64"}