mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-09-26 19:51:26 +08:00
api: add tunnel and profile to RTSP conns and sessions (#4985)
This commit is contained in:
@@ -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
2
go.mod
@@ -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
4
go.sum
@@ -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=
|
||||||
|
@@ -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),
|
||||||
|
@@ -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"`
|
||||||
|
@@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
@@ -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"}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user