api: add missing enums and move all enums in dedicated components (#5576)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
extends:
|
||||
- recommended
|
||||
|
||||
rules:
|
||||
operation-4xx-response: off
|
||||
+174
-51
@@ -15,19 +15,158 @@ security: []
|
||||
|
||||
components:
|
||||
schemas:
|
||||
OKStatus:
|
||||
type: string
|
||||
enum: [ok]
|
||||
|
||||
ErrorStatus:
|
||||
type: string
|
||||
enum: [error]
|
||||
|
||||
PathSourceType:
|
||||
type: string
|
||||
enum:
|
||||
- hlsSource
|
||||
- redirect
|
||||
- rpiCameraSource
|
||||
- rtmpConn
|
||||
- rtmpsConn
|
||||
- rtmpSource
|
||||
- rtspSession
|
||||
- rtspSource
|
||||
- rtspsSession
|
||||
- srtConn
|
||||
- srtSource
|
||||
- mpegtsSource
|
||||
- rtpSource
|
||||
- webRTCSession
|
||||
- webRTCSource
|
||||
|
||||
PathReaderType:
|
||||
type: string
|
||||
enum:
|
||||
- hlsMuxer
|
||||
- rpiCameraSecondary
|
||||
- rtmpConn
|
||||
- rtmpsConn
|
||||
- rtspConn
|
||||
- rtspSession
|
||||
- rtspsConn
|
||||
- rtspsSession
|
||||
- srtConn
|
||||
- webRTCSession
|
||||
|
||||
PathTrackCodec:
|
||||
type: string
|
||||
enum:
|
||||
- AV1
|
||||
- VP9
|
||||
- VP8
|
||||
- H265
|
||||
- H264
|
||||
- MPEG-4 Video
|
||||
- MPEG-1 Video
|
||||
- MJPEG
|
||||
- Opus
|
||||
- Vorbis
|
||||
- MPEG-4 Audio
|
||||
- MPEG-4 Audio LATM
|
||||
- MPEG-1 Audio
|
||||
- AC3
|
||||
- Speex
|
||||
- G726
|
||||
- G722
|
||||
- G711
|
||||
- LPCM
|
||||
- MPEG-TS
|
||||
- KLV
|
||||
- Generic
|
||||
|
||||
AlwaysAvailableTrackCodec:
|
||||
type: string
|
||||
enum:
|
||||
- AV1
|
||||
- VP9
|
||||
- H265
|
||||
- H264
|
||||
- MPEG4Audio
|
||||
- Opus
|
||||
- G711
|
||||
- LPCM
|
||||
|
||||
AuthAction:
|
||||
type: string
|
||||
enum:
|
||||
- publish
|
||||
- read
|
||||
- playback
|
||||
- api
|
||||
- metrics
|
||||
- pprof
|
||||
|
||||
AuthMethod:
|
||||
type: string
|
||||
enum: [internal, http, jwt]
|
||||
|
||||
Encryption:
|
||||
type: string
|
||||
enum: [no, optional, strict]
|
||||
|
||||
HLSVariant:
|
||||
type: string
|
||||
enum: [mpegts, fmp4, lowLatency]
|
||||
|
||||
LogDestination:
|
||||
type: string
|
||||
enum: [stdout, file, syslog]
|
||||
|
||||
LogLevel:
|
||||
type: string
|
||||
enum: [error, warn, info, debug]
|
||||
|
||||
RecordFormat:
|
||||
type: string
|
||||
enum: [fmp4, mpegts]
|
||||
|
||||
RTSPAuthMethod:
|
||||
type: string
|
||||
enum: [basic, digest]
|
||||
|
||||
RTSPRangeType:
|
||||
type: string
|
||||
enum: ['', clock, npt, smpte]
|
||||
|
||||
RTSPTransport:
|
||||
type: string
|
||||
enum: [udp, multicast, tcp, automatic]
|
||||
|
||||
RTMPConnState:
|
||||
type: string
|
||||
enum: [idle, read, publish]
|
||||
|
||||
RTSPSessionState:
|
||||
type: string
|
||||
enum: [idle, read, publish]
|
||||
|
||||
SRTConnState:
|
||||
type: string
|
||||
enum: [idle, read, publish]
|
||||
|
||||
WebRTCSessionState:
|
||||
type: string
|
||||
enum: [read, publish]
|
||||
|
||||
OK:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum: [ok]
|
||||
$ref: '#/components/schemas/OKStatus'
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum: [error]
|
||||
$ref: '#/components/schemas/ErrorStatus'
|
||||
error:
|
||||
type: string
|
||||
|
||||
@@ -59,7 +198,7 @@ components:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
$ref: '#/components/schemas/AuthAction'
|
||||
path:
|
||||
type: string
|
||||
|
||||
@@ -68,11 +207,11 @@ components:
|
||||
properties:
|
||||
# General
|
||||
logLevel:
|
||||
type: string
|
||||
$ref: '#/components/schemas/LogLevel'
|
||||
logDestinations:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
$ref: '#/components/schemas/LogDestination'
|
||||
logStructured:
|
||||
type: boolean
|
||||
logFile:
|
||||
@@ -108,7 +247,7 @@ components:
|
||||
|
||||
# Authentication
|
||||
authMethod:
|
||||
type: string
|
||||
$ref: '#/components/schemas/AuthMethod'
|
||||
authInternalUsers:
|
||||
type: array
|
||||
items:
|
||||
@@ -250,17 +389,21 @@ components:
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
enum: [udp, multicast, tcp]
|
||||
deprecated: true
|
||||
rtspTransports:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: [udp, multicast, tcp]
|
||||
encryption:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Encryption'
|
||||
rtspEncryption:
|
||||
type: string
|
||||
$ref: '#/components/schemas/Encryption'
|
||||
rtspAddress:
|
||||
type: string
|
||||
rtspsAddress:
|
||||
@@ -295,12 +438,12 @@ components:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
$ref: '#/components/schemas/RTSPAuthMethod'
|
||||
deprecated: true
|
||||
rtspAuthMethods:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
$ref: '#/components/schemas/RTSPAuthMethod'
|
||||
rtspUDPReadBufferSize:
|
||||
type: integer
|
||||
format: uint64
|
||||
@@ -315,7 +458,7 @@ components:
|
||||
nullable: true
|
||||
deprecated: true
|
||||
rtmpEncryption:
|
||||
type: string
|
||||
$ref: '#/components/schemas/Encryption'
|
||||
rtmpAddress:
|
||||
type: string
|
||||
rtmpsAddress:
|
||||
@@ -355,7 +498,7 @@ components:
|
||||
hlsAlwaysRemux:
|
||||
type: boolean
|
||||
hlsVariant:
|
||||
type: string
|
||||
$ref: '#/components/schemas/HLSVariant'
|
||||
hlsSegmentCount:
|
||||
type: integer
|
||||
format: int64
|
||||
@@ -461,6 +604,8 @@ components:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/RecordFormat'
|
||||
recordPartDuration:
|
||||
type: string
|
||||
nullable: true
|
||||
@@ -523,7 +668,7 @@ components:
|
||||
recordPath:
|
||||
type: string
|
||||
recordFormat:
|
||||
type: string
|
||||
$ref: '#/components/schemas/RecordFormat'
|
||||
recordPartDuration:
|
||||
type: string
|
||||
recordMaxPartSize:
|
||||
@@ -575,19 +720,21 @@ components:
|
||||
|
||||
# RTSP source
|
||||
rtspTransport:
|
||||
type: string
|
||||
$ref: '#/components/schemas/RTSPTransport'
|
||||
rtspAnyPort:
|
||||
type: boolean
|
||||
sourceProtocol:
|
||||
type: string
|
||||
nullable: true
|
||||
deprecated: true
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/RTSPTransport'
|
||||
sourceAnyPortEnable:
|
||||
type: boolean
|
||||
nullable: true
|
||||
deprecated: true
|
||||
rtspRangeType:
|
||||
type: string
|
||||
$ref: '#/components/schemas/RTSPRangeType'
|
||||
rtspRangeStart:
|
||||
type: string
|
||||
rtspUDPReadBufferSize:
|
||||
@@ -801,8 +948,10 @@ components:
|
||||
confName:
|
||||
type: string
|
||||
source:
|
||||
$ref: '#/components/schemas/PathSource'
|
||||
type: object
|
||||
nullable: true
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/PathSource'
|
||||
ready:
|
||||
type: boolean
|
||||
deprecated: true
|
||||
@@ -823,7 +972,7 @@ components:
|
||||
tracks:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
$ref: '#/components/schemas/PathTrackCodec'
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: uint64
|
||||
@@ -853,22 +1002,7 @@ components:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- hlsSource
|
||||
- redirect
|
||||
- rpiCameraSource
|
||||
- rtmpConn
|
||||
- rtmpSource
|
||||
- rtspSession
|
||||
- rtspSource
|
||||
- rtspsSession
|
||||
- srtConn
|
||||
- srtSource
|
||||
- mpegtsSource
|
||||
- rtpSource
|
||||
- webRTCSession
|
||||
- webRTCSource
|
||||
$ref: '#/components/schemas/PathSourceType'
|
||||
id:
|
||||
type: string
|
||||
|
||||
@@ -876,14 +1010,7 @@ components:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- hlsMuxer
|
||||
- rtmpConn
|
||||
- rtspSession
|
||||
- rtspsSession
|
||||
- srtConn
|
||||
- webRTCSession
|
||||
$ref: '#/components/schemas/PathReaderType'
|
||||
id:
|
||||
type: string
|
||||
|
||||
@@ -955,8 +1082,7 @@ components:
|
||||
remoteAddr:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
enum: [idle, read, publish]
|
||||
$ref: '#/components/schemas/RTMPConnState'
|
||||
path:
|
||||
type: string
|
||||
query:
|
||||
@@ -1032,8 +1158,7 @@ components:
|
||||
remoteAddr:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
enum: [idle, read, publish]
|
||||
$ref: '#/components/schemas/RTSPSessionState'
|
||||
path:
|
||||
type: string
|
||||
query:
|
||||
@@ -1107,8 +1232,7 @@ components:
|
||||
remoteAddr:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
enum: [idle, read, publish]
|
||||
$ref: '#/components/schemas/SRTConnState'
|
||||
path:
|
||||
type: string
|
||||
query:
|
||||
@@ -1344,7 +1468,7 @@ components:
|
||||
type: object
|
||||
properties:
|
||||
codec:
|
||||
type: string
|
||||
$ref: '#/components/schemas/AlwaysAvailableTrackCodec'
|
||||
sampleRate:
|
||||
type: integer
|
||||
format: int64
|
||||
@@ -1383,8 +1507,7 @@ components:
|
||||
remoteCandidate:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
enum: [read, publish]
|
||||
$ref: '#/components/schemas/WebRTCSessionState'
|
||||
path:
|
||||
type: string
|
||||
query:
|
||||
|
||||
+4
-4
@@ -223,13 +223,13 @@ func (a *API) writeError(ctx *gin.Context, status int, err error) {
|
||||
|
||||
// add error to response
|
||||
ctx.JSON(status, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
func (a *API) writeOK(ctx *gin.Context) {
|
||||
ctx.JSON(http.StatusOK, &defs.APIOK{Status: "ok"})
|
||||
ctx.JSON(http.StatusOK, &defs.APIOK{Status: defs.APIOKStatusOK})
|
||||
}
|
||||
|
||||
func (a *API) middlewarePreflightRequests(ctx *gin.Context) {
|
||||
@@ -255,7 +255,7 @@ func (a *API) middlewareAuth(ctx *gin.Context) {
|
||||
if err.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
@@ -267,7 +267,7 @@ func (a *API) middlewareAuth(ctx *gin.Context) {
|
||||
<-time.After(auth.PauseAfterError)
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
|
||||
@@ -38,21 +38,21 @@ func TestPathsList(t *testing.T) {
|
||||
"test1": {
|
||||
Name: "test1",
|
||||
ConfName: "test1",
|
||||
Source: &defs.APIPathSource{Type: "publisher", ID: "pub1"},
|
||||
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "pub1"},
|
||||
Ready: true,
|
||||
ReadyTime: &now,
|
||||
Tracks: []string{"H264", "Opus"},
|
||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecOpus},
|
||||
BytesReceived: 1000,
|
||||
BytesSent: 2000,
|
||||
Readers: []defs.APIPathReader{
|
||||
{Type: "reader", ID: "reader1"},
|
||||
{Type: defs.APIPathReaderTypeRTSPSession, ID: "reader1"},
|
||||
},
|
||||
},
|
||||
"test2": {
|
||||
Name: "test2",
|
||||
ConfName: "test2",
|
||||
Ready: false,
|
||||
Tracks: []string{},
|
||||
Tracks: []defs.APIPathTrackCodec{},
|
||||
BytesReceived: 500,
|
||||
BytesSent: 100,
|
||||
Readers: []defs.APIPathReader{},
|
||||
@@ -91,15 +91,15 @@ func TestPathsGet(t *testing.T) {
|
||||
"mystream": {
|
||||
Name: "mystream",
|
||||
ConfName: "mystream",
|
||||
Source: &defs.APIPathSource{Type: "rtspSession", ID: "session123"},
|
||||
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "session123"},
|
||||
Ready: true,
|
||||
ReadyTime: &now,
|
||||
Tracks: []string{"H264", "Opus"},
|
||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecOpus},
|
||||
BytesReceived: 123456,
|
||||
BytesSent: 789012,
|
||||
Readers: []defs.APIPathReader{
|
||||
{Type: "hlsMuxer", ID: "muxer1"},
|
||||
{Type: "webRTCSession", ID: "session456"},
|
||||
{Type: defs.APIPathReaderTypeHLSMuxer, ID: "muxer1"},
|
||||
{Type: defs.APIPathReaderTypeWebRTCSession, ID: "session456"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -128,7 +128,7 @@ func TestPathsGet(t *testing.T) {
|
||||
require.Equal(t, "mystream", out.ConfName)
|
||||
require.True(t, out.Ready)
|
||||
require.NotNil(t, out.Source)
|
||||
require.Equal(t, "rtspSession", out.Source.Type)
|
||||
require.Equal(t, defs.APIPathSourceTypeRTSPSession, out.Source.Type)
|
||||
require.Len(t, out.Tracks, 2)
|
||||
require.Len(t, out.Readers, 2)
|
||||
require.Equal(t, uint64(123456), out.BytesReceived)
|
||||
|
||||
@@ -6,29 +6,9 @@ import (
|
||||
"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper"
|
||||
)
|
||||
|
||||
// Codec is a codec of AlwaysAvailableTrack.
|
||||
type Codec string
|
||||
|
||||
// available codecs.
|
||||
const (
|
||||
CodecAV1 Codec = "AV1"
|
||||
CodecVP9 Codec = "VP9"
|
||||
CodecH265 Codec = "H265"
|
||||
CodecH264 Codec = "H264"
|
||||
CodecMPEG4Audio Codec = "MPEG4Audio"
|
||||
CodecOpus Codec = "Opus"
|
||||
CodecG711 Codec = "G711"
|
||||
CodecLPCM Codec = "LPCM"
|
||||
)
|
||||
|
||||
// UnmarshalEnv implements env.Unmarshaler.
|
||||
func (d *Codec) UnmarshalEnv(_ string, v string) error {
|
||||
return jsonwrapper.Unmarshal([]byte(`"`+v+`"`), d)
|
||||
}
|
||||
|
||||
// AlwaysAvailableTrack is an item of alwaysAvailableTracks.
|
||||
type AlwaysAvailableTrack struct {
|
||||
Codec Codec `json:"codec"`
|
||||
Codec AlwaysAvailableTrackCodec `json:"codec"`
|
||||
SampleRate int `json:"sampleRate"`
|
||||
ChannelCount int `json:"channelCount"`
|
||||
MULaw bool `json:"muLaw"`
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package conf
|
||||
|
||||
import "github.com/bluenviron/mediamtx/internal/conf/jsonwrapper"
|
||||
|
||||
// AlwaysAvailableTrackCodec is a codec of AlwaysAvailableTrack.
|
||||
type AlwaysAvailableTrackCodec string
|
||||
|
||||
// available codecs.
|
||||
const (
|
||||
CodecAV1 AlwaysAvailableTrackCodec = "AV1"
|
||||
CodecVP9 AlwaysAvailableTrackCodec = "VP9"
|
||||
CodecH265 AlwaysAvailableTrackCodec = "H265"
|
||||
CodecH264 AlwaysAvailableTrackCodec = "H264"
|
||||
CodecMPEG4Audio AlwaysAvailableTrackCodec = "MPEG4Audio"
|
||||
CodecOpus AlwaysAvailableTrackCodec = "Opus"
|
||||
CodecG711 AlwaysAvailableTrackCodec = "G711"
|
||||
CodecLPCM AlwaysAvailableTrackCodec = "LPCM"
|
||||
)
|
||||
|
||||
// UnmarshalEnv implements env.Unmarshaler.
|
||||
func (d *AlwaysAvailableTrackCodec) UnmarshalEnv(_ string, v string) error {
|
||||
return jsonwrapper.Unmarshal([]byte(`"`+v+`"`), d)
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
pwebrtc "github.com/pion/webrtc/v4"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/bluenviron/mediamtx/internal/defs"
|
||||
"github.com/bluenviron/mediamtx/internal/protocols/webrtc"
|
||||
"github.com/bluenviron/mediamtx/internal/protocols/whip"
|
||||
"github.com/bluenviron/mediamtx/internal/test"
|
||||
@@ -82,7 +83,7 @@ func TestAPIPathsList(t *testing.T) {
|
||||
Name string `json:"name"`
|
||||
Source pathSource `json:"source"`
|
||||
Ready bool `json:"ready"`
|
||||
Tracks []string `json:"tracks"`
|
||||
Tracks []defs.APIPathTrackCodec `json:"tracks"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
@@ -136,7 +137,7 @@ func TestAPIPathsList(t *testing.T) {
|
||||
Type: "rtspSession",
|
||||
},
|
||||
Ready: true,
|
||||
Tracks: []string{"H264", "MPEG-4 Audio"},
|
||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecMPEG4Audio},
|
||||
BytesReceived: 17,
|
||||
}},
|
||||
}, out)
|
||||
@@ -184,7 +185,7 @@ func TestAPIPathsList(t *testing.T) {
|
||||
Type: "rtspsSession",
|
||||
},
|
||||
Ready: true,
|
||||
Tracks: []string{"H264", "MPEG-4 Audio"},
|
||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecMPEG4Audio},
|
||||
}},
|
||||
}, out)
|
||||
})
|
||||
@@ -213,7 +214,7 @@ func TestAPIPathsList(t *testing.T) {
|
||||
Type: "rtspSource",
|
||||
},
|
||||
Ready: false,
|
||||
Tracks: []string{},
|
||||
Tracks: []defs.APIPathTrackCodec{},
|
||||
}},
|
||||
}, out)
|
||||
})
|
||||
@@ -242,7 +243,7 @@ func TestAPIPathsList(t *testing.T) {
|
||||
Type: "rtmpSource",
|
||||
},
|
||||
Ready: false,
|
||||
Tracks: []string{},
|
||||
Tracks: []defs.APIPathTrackCodec{},
|
||||
}},
|
||||
}, out)
|
||||
})
|
||||
@@ -271,7 +272,7 @@ func TestAPIPathsList(t *testing.T) {
|
||||
Type: "hlsSource",
|
||||
},
|
||||
Ready: false,
|
||||
Tracks: []string{},
|
||||
Tracks: []defs.APIPathTrackCodec{},
|
||||
}},
|
||||
}, out)
|
||||
})
|
||||
@@ -298,7 +299,7 @@ func TestAPIPathsGet(t *testing.T) {
|
||||
Name string `json:"name"`
|
||||
Source pathSource `json:"source"`
|
||||
Ready bool `json:"Ready"`
|
||||
Tracks []string `json:"tracks"`
|
||||
Tracks []defs.APIPathTrackCodec `json:"tracks"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
@@ -329,7 +330,7 @@ func TestAPIPathsGet(t *testing.T) {
|
||||
Type: "rtspSession",
|
||||
},
|
||||
Ready: true,
|
||||
Tracks: []string{"H264"},
|
||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264},
|
||||
}, out)
|
||||
} else {
|
||||
res, err := hc.Get("http://localhost:9997/v3/paths/get/" + pathName)
|
||||
|
||||
@@ -655,9 +655,9 @@ func (pa *path) doAPIPathsGet(req pathAPIPathsGetReq) {
|
||||
v := pa.source.APISourceDescribe()
|
||||
return v
|
||||
}(),
|
||||
Tracks: func() []string {
|
||||
Tracks: func() []defs.APIPathTrackCodec {
|
||||
if !pa.isAvailable() {
|
||||
return []string{}
|
||||
return []defs.APIPathTrackCodec{}
|
||||
}
|
||||
return defs.MediasToCodecs(pa.stream.Desc.Medias)
|
||||
}(),
|
||||
|
||||
@@ -14,7 +14,7 @@ func (*sourceRedirect) Log(logger.Level, string, ...any) {
|
||||
// APISourceDescribe implements source.
|
||||
func (*sourceRedirect) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "redirect",
|
||||
Type: defs.APIPathSourceTypeRedirect,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
+14
-387
@@ -3,61 +3,33 @@ package defs
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/bluenviron/mediamtx/internal/conf"
|
||||
)
|
||||
|
||||
// APIPathManager contains methods used by the API and Metrics server.
|
||||
type APIPathManager interface {
|
||||
APIPathsList() (*APIPathList, error)
|
||||
APIPathsGet(string) (*APIPath, error)
|
||||
}
|
||||
// APIOKStatus is the status of a successful response.
|
||||
type APIOKStatus string
|
||||
|
||||
// APIHLSServer contains methods used by the API and Metrics server.
|
||||
type APIHLSServer interface {
|
||||
APIMuxersList() (*APIHLSMuxerList, error)
|
||||
APIMuxersGet(string) (*APIHLSMuxer, error)
|
||||
}
|
||||
// statuses.
|
||||
const (
|
||||
APIOKStatusOK APIOKStatus = "ok"
|
||||
)
|
||||
|
||||
// APIRTSPServer contains methods used by the API and Metrics server.
|
||||
type APIRTSPServer interface {
|
||||
APIConnsList() (*APIRTSPConnsList, error)
|
||||
APIConnsGet(uuid.UUID) (*APIRTSPConn, error)
|
||||
APISessionsList() (*APIRTSPSessionList, error)
|
||||
APISessionsGet(uuid.UUID) (*APIRTSPSession, error)
|
||||
APISessionsKick(uuid.UUID) error
|
||||
}
|
||||
// APIErrorStatus is the status of an error response.
|
||||
type APIErrorStatus string
|
||||
|
||||
// APIRTMPServer contains methods used by the API and Metrics server.
|
||||
type APIRTMPServer interface {
|
||||
APIConnsList() (*APIRTMPConnList, error)
|
||||
APIConnsGet(uuid.UUID) (*APIRTMPConn, error)
|
||||
APIConnsKick(uuid.UUID) error
|
||||
}
|
||||
|
||||
// APISRTServer contains methods used by the API and Metrics server.
|
||||
type APISRTServer interface {
|
||||
APIConnsList() (*APISRTConnList, error)
|
||||
APIConnsGet(uuid.UUID) (*APISRTConn, error)
|
||||
APIConnsKick(uuid.UUID) error
|
||||
}
|
||||
|
||||
// APIWebRTCServer contains methods used by the API and Metrics server.
|
||||
type APIWebRTCServer interface {
|
||||
APISessionsList() (*APIWebRTCSessionList, error)
|
||||
APISessionsGet(uuid.UUID) (*APIWebRTCSession, error)
|
||||
APISessionsKick(uuid.UUID) error
|
||||
}
|
||||
// statuses.
|
||||
const (
|
||||
APIErrorStatusError APIErrorStatus = "error"
|
||||
)
|
||||
|
||||
// APIOK is returned on success.
|
||||
type APIOK struct {
|
||||
Status string `json:"status"`
|
||||
Status APIOKStatus `json:"status"`
|
||||
}
|
||||
|
||||
// APIError is a generic error.
|
||||
type APIError struct {
|
||||
Status string `json:"status"`
|
||||
Status APIErrorStatus `json:"status"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
@@ -73,348 +45,3 @@ type APIPathConfList struct {
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []conf.Path `json:"items"`
|
||||
}
|
||||
|
||||
// APIPathSource is a source.
|
||||
type APIPathSource struct {
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// APIPathReader is a reader.
|
||||
type APIPathReader struct {
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// APIPath is a path.
|
||||
type APIPath struct {
|
||||
Name string `json:"name"`
|
||||
ConfName string `json:"confName"`
|
||||
Ready bool `json:"ready" deprecated:"true"`
|
||||
ReadyTime *time.Time `json:"readyTime" deprecated:"true"`
|
||||
Available bool `json:"available"`
|
||||
AvailableTime *time.Time `json:"availableTime"`
|
||||
Online bool `json:"online"`
|
||||
OnlineTime *time.Time `json:"onlineTime"`
|
||||
Source *APIPathSource `json:"source"`
|
||||
Tracks []string `json:"tracks"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
Readers []APIPathReader `json:"readers"`
|
||||
}
|
||||
|
||||
// APIPathList is a list of paths.
|
||||
type APIPathList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIPath `json:"items"`
|
||||
}
|
||||
|
||||
// APIHLSMuxer is an HLS muxer.
|
||||
type APIHLSMuxer struct {
|
||||
Path string `json:"path"`
|
||||
Created time.Time `json:"created"`
|
||||
LastRequest time.Time `json:"lastRequest"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
|
||||
// APIHLSMuxerList is a list of HLS muxers.
|
||||
type APIHLSMuxerList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIHLSMuxer `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTMPConnState is the state of a RTMP connection.
|
||||
type APIRTMPConnState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APIRTMPConnStateIdle APIRTMPConnState = "idle"
|
||||
APIRTMPConnStateRead APIRTMPConnState = "read"
|
||||
APIRTMPConnStatePublish APIRTMPConnState = "publish"
|
||||
)
|
||||
|
||||
// APIRTMPConn is a RTMP connection.
|
||||
type APIRTMPConn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
State APIRTMPConnState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
|
||||
// APIRTMPConnList is a list of RTMP connections.
|
||||
type APIRTMPConnList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTMPConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTSPConn is a RTSP connection.
|
||||
type APIRTSPConn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
Session *uuid.UUID `json:"session"`
|
||||
Tunnel string `json:"tunnel"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
|
||||
// APIRTSPConnsList is a list of RTSP connections.
|
||||
type APIRTSPConnsList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTSPConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTSPSessionState is the state of a RTSP session.
|
||||
type APIRTSPSessionState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APIRTSPSessionStateIdle APIRTSPSessionState = "idle"
|
||||
APIRTSPSessionStateRead APIRTSPSessionState = "read"
|
||||
APIRTSPSessionStatePublish APIRTSPSessionState = "publish"
|
||||
)
|
||||
|
||||
// APIRTSPSession is a RTSP session.
|
||||
type APIRTSPSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
State APIRTSPSessionState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
Transport *string `json:"transport"`
|
||||
Profile *string `json:"profile"`
|
||||
Conns []uuid.UUID `json:"conns"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
RTPPacketsReceived uint64 `json:"rtpPacketsReceived"`
|
||||
RTPPacketsSent uint64 `json:"rtpPacketsSent"`
|
||||
RTPPacketsLost uint64 `json:"rtpPacketsLost"`
|
||||
RTPPacketsInError uint64 `json:"rtpPacketsInError"`
|
||||
RTPPacketsJitter float64 `json:"rtpPacketsJitter"`
|
||||
RTCPPacketsReceived uint64 `json:"rtcpPacketsReceived"`
|
||||
RTCPPacketsSent uint64 `json:"rtcpPacketsSent"`
|
||||
RTCPPacketsInError uint64 `json:"rtcpPacketsInError"`
|
||||
}
|
||||
|
||||
// APIRTSPSessionList is a list of RTSP sessions.
|
||||
type APIRTSPSessionList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTSPSession `json:"items"`
|
||||
}
|
||||
|
||||
// APISRTConnState is the state of a SRT connection.
|
||||
type APISRTConnState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APISRTConnStateIdle APISRTConnState = "idle"
|
||||
APISRTConnStateRead APISRTConnState = "read"
|
||||
APISRTConnStatePublish APISRTConnState = "publish"
|
||||
)
|
||||
|
||||
// APISRTConn is a SRT connection.
|
||||
type APISRTConn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
State APISRTConnState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
|
||||
// The metric names/comments are pulled from GoSRT
|
||||
|
||||
// The total number of sent DATA packets, including retransmitted packets
|
||||
PacketsSent uint64 `json:"packetsSent"`
|
||||
// The total number of received DATA packets, including retransmitted packets
|
||||
PacketsReceived uint64 `json:"packetsReceived"`
|
||||
// The total number of unique DATA packets sent by the SRT sender
|
||||
PacketsSentUnique uint64 `json:"packetsSentUnique"`
|
||||
// The total number of unique original, retransmitted or recovered by the packet filter DATA packets
|
||||
// received in time, decrypted without errors and, as a result, scheduled for delivery to the
|
||||
// upstream application by the SRT receiver.
|
||||
PacketsReceivedUnique uint64 `json:"packetsReceivedUnique"`
|
||||
// The total number of data packets considered or reported as lost at the sender side.
|
||||
// Does not correspond to the packets detected as lost at the receiver side.
|
||||
PacketsSendLoss uint64 `json:"packetsSendLoss"`
|
||||
// The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||
PacketsReceivedLoss uint64 `json:"packetsReceivedLoss"`
|
||||
// The total number of retransmitted packets sent by the SRT sender
|
||||
PacketsRetrans uint64 `json:"packetsRetrans"`
|
||||
// The total number of retransmitted packets registered at the receiver side
|
||||
PacketsReceivedRetrans uint64 `json:"packetsReceivedRetrans"`
|
||||
// The total number of sent ACK (Acknowledgement) control packets
|
||||
PacketsSentACK uint64 `json:"packetsSentACK"`
|
||||
// The total number of received ACK (Acknowledgement) control packets
|
||||
PacketsReceivedACK uint64 `json:"packetsReceivedACK"`
|
||||
// The total number of sent NAK (Negative Acknowledgement) control packets
|
||||
PacketsSentNAK uint64 `json:"packetsSentNAK"`
|
||||
// The total number of received NAK (Negative Acknowledgement) control packets
|
||||
PacketsReceivedNAK uint64 `json:"packetsReceivedNAK"`
|
||||
// The total number of sent KM (Key Material) control packets
|
||||
PacketsSentKM uint64 `json:"packetsSentKM"`
|
||||
// The total number of received KM (Key Material) control packets
|
||||
PacketsReceivedKM uint64 `json:"packetsReceivedKM"`
|
||||
// The total accumulated time in microseconds, during which the SRT sender has some data to transmit,
|
||||
// including packets that have been sent, but not yet acknowledged
|
||||
UsSndDuration uint64 `json:"usSndDuration"`
|
||||
// ??
|
||||
PacketsReceivedBelated uint64 `json:"packetsReceivedBelated"`
|
||||
// The total number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
|
||||
PacketsSendDrop uint64 `json:"packetsSendDrop"`
|
||||
// The total number of dropped by the SRT receiver and, as a result,
|
||||
// not delivered to the upstream application DATA packets
|
||||
PacketsReceivedDrop uint64 `json:"packetsReceivedDrop"`
|
||||
// The total number of packets that failed to be decrypted at the receiver side
|
||||
PacketsReceivedUndecrypt uint64 `json:"packetsReceivedUndecrypt"`
|
||||
|
||||
// Same as packetsReceived, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
// Same as packetsSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
// Same as packetsSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesSentUnique uint64 `json:"bytesSentUnique"`
|
||||
// Same as packetsReceivedUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedUnique uint64 `json:"bytesReceivedUnique"`
|
||||
// Same as packetsReceivedLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT),
|
||||
// bytes for the presently missing (either reordered or lost) packets' payloads are estimated
|
||||
// based on the average packet size
|
||||
BytesReceivedLoss uint64 `json:"bytesReceivedLoss"`
|
||||
// Same as packetsRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesRetrans uint64 `json:"bytesRetrans"`
|
||||
// Same as packetsReceivedRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedRetrans uint64 `json:"bytesReceivedRetrans"`
|
||||
// Same as PacketsReceivedBelated, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedBelated uint64 `json:"bytesReceivedBelated"`
|
||||
// Same as packetsSendDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesSendDrop uint64 `json:"bytesSendDrop"`
|
||||
// Same as packetsReceivedDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedDrop uint64 `json:"bytesReceivedDrop"`
|
||||
// Same as packetsReceivedUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedUndecrypt uint64 `json:"bytesReceivedUndecrypt"`
|
||||
|
||||
// Current minimum time interval between which consecutive packets are sent, in microseconds
|
||||
UsPacketsSendPeriod float64 `json:"usPacketsSendPeriod"`
|
||||
// The maximum number of packets that can be "in flight"
|
||||
PacketsFlowWindow uint64 `json:"packetsFlowWindow"`
|
||||
// The number of packets in flight
|
||||
PacketsFlightSize uint64 `json:"packetsFlightSize"`
|
||||
// Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA)
|
||||
// of an endpoint's RTT samples, in milliseconds
|
||||
MsRTT float64 `json:"msRTT"`
|
||||
// Current transmission bandwidth, in Mbps
|
||||
MbpsSendRate float64 `json:"mbpsSendRate"`
|
||||
// Current receiving bandwidth, in Mbps
|
||||
MbpsReceiveRate float64 `json:"mbpsReceiveRate"`
|
||||
// Estimated capacity of the network link, in Mbps
|
||||
MbpsLinkCapacity float64 `json:"mbpsLinkCapacity"`
|
||||
// The available space in the sender's buffer, in bytes
|
||||
BytesAvailSendBuf uint64 `json:"bytesAvailSendBuf"`
|
||||
// The available space in the receiver's buffer, in bytes
|
||||
BytesAvailReceiveBuf uint64 `json:"bytesAvailReceiveBuf"`
|
||||
// Transmission bandwidth limit, in Mbps
|
||||
MbpsMaxBW float64 `json:"mbpsMaxBW"`
|
||||
// Maximum Segment Size (MSS), in bytes
|
||||
ByteMSS uint64 `json:"byteMSS"`
|
||||
// The number of packets in the sender's buffer that are already scheduled
|
||||
// for sending or even possibly sent, but not yet acknowledged
|
||||
PacketsSendBuf uint64 `json:"packetsSendBuf"`
|
||||
// Instantaneous (current) value of packetsSndBuf, but expressed in bytes,
|
||||
// including payload and all headers (IP, TCP, SRT)
|
||||
BytesSendBuf uint64 `json:"bytesSendBuf"`
|
||||
// The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
|
||||
MsSendBuf uint64 `json:"msSendBuf"`
|
||||
// Timestamp-based Packet Delivery Delay value of the peer
|
||||
MsSendTsbPdDelay uint64 `json:"msSendTsbPdDelay"`
|
||||
// The number of acknowledged packets in receiver's buffer
|
||||
PacketsReceiveBuf uint64 `json:"packetsReceiveBuf"`
|
||||
// Instantaneous (current) value of packetsRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
BytesReceiveBuf uint64 `json:"bytesReceiveBuf"`
|
||||
// The timespan (msec) of acknowledged packets in the receiver's buffer
|
||||
MsReceiveBuf uint64 `json:"msReceiveBuf"`
|
||||
// Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
|
||||
MsReceiveTsbPdDelay uint64 `json:"msReceiveTsbPdDelay"`
|
||||
// Instant value of the packet reorder tolerance
|
||||
PacketsReorderTolerance uint64 `json:"packetsReorderTolerance"`
|
||||
// Accumulated difference between the current time and the time-to-play of a packet that is received late
|
||||
PacketsReceivedAvgBelatedTime uint64 `json:"packetsReceivedAvgBelatedTime"`
|
||||
// Percentage of resent data vs. sent data
|
||||
PacketsSendLossRate float64 `json:"packetsSendLossRate"`
|
||||
// Percentage of retransmitted data vs. received data
|
||||
PacketsReceivedLossRate float64 `json:"packetsReceivedLossRate"`
|
||||
}
|
||||
|
||||
// APISRTConnList is a list of SRT connections.
|
||||
type APISRTConnList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APISRTConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIWebRTCSessionState is the state of a WebRTC connection.
|
||||
type APIWebRTCSessionState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APIWebRTCSessionStateRead APIWebRTCSessionState = "read"
|
||||
APIWebRTCSessionStatePublish APIWebRTCSessionState = "publish"
|
||||
)
|
||||
|
||||
// APIWebRTCSession is a WebRTC session.
|
||||
type APIWebRTCSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
PeerConnectionEstablished bool `json:"peerConnectionEstablished"`
|
||||
LocalCandidate string `json:"localCandidate"`
|
||||
RemoteCandidate string `json:"remoteCandidate"`
|
||||
State APIWebRTCSessionState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
RTPPacketsReceived uint64 `json:"rtpPacketsReceived"`
|
||||
RTPPacketsSent uint64 `json:"rtpPacketsSent"`
|
||||
RTPPacketsLost uint64 `json:"rtpPacketsLost"`
|
||||
RTPPacketsJitter float64 `json:"rtpPacketsJitter"`
|
||||
RTCPPacketsReceived uint64 `json:"rtcpPacketsReceived"`
|
||||
RTCPPacketsSent uint64 `json:"rtcpPacketsSent"`
|
||||
}
|
||||
|
||||
// APIWebRTCSessionList is a list of WebRTC sessions.
|
||||
type APIWebRTCSessionList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIWebRTCSession `json:"items"`
|
||||
}
|
||||
|
||||
// APIRecordingSegment is a recording segment.
|
||||
type APIRecordingSegment struct {
|
||||
Start time.Time `json:"start"`
|
||||
}
|
||||
|
||||
// APIRecording is a recording.
|
||||
type APIRecording struct {
|
||||
Name string `json:"name"`
|
||||
Segments []APIRecordingSegment `json:"segments"`
|
||||
}
|
||||
|
||||
// APIRecordingList is a list of recordings.
|
||||
type APIRecordingList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRecording `json:"items"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package defs
|
||||
|
||||
import "time"
|
||||
|
||||
// APIHLSServer contains methods used by the API and Metrics server.
|
||||
type APIHLSServer interface {
|
||||
APIMuxersList() (*APIHLSMuxerList, error)
|
||||
APIMuxersGet(string) (*APIHLSMuxer, error)
|
||||
}
|
||||
|
||||
// APIHLSMuxer is an HLS muxer.
|
||||
type APIHLSMuxer struct {
|
||||
Path string `json:"path"`
|
||||
Created time.Time `json:"created"`
|
||||
LastRequest time.Time `json:"lastRequest"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
|
||||
// APIHLSMuxerList is a list of HLS muxers.
|
||||
type APIHLSMuxerList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIHLSMuxer `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// APIPathManager contains methods used by the API and Metrics server.
|
||||
type APIPathManager interface {
|
||||
APIPathsList() (*APIPathList, error)
|
||||
APIPathsGet(string) (*APIPath, error)
|
||||
}
|
||||
|
||||
// APIPathSourceType is the type of a path source.
|
||||
type APIPathSourceType string
|
||||
|
||||
// source types.
|
||||
const (
|
||||
APIPathSourceTypeHLSSource APIPathSourceType = "hlsSource"
|
||||
APIPathSourceTypeRedirect APIPathSourceType = "redirect"
|
||||
APIPathSourceTypeRPICameraSource APIPathSourceType = "rpiCameraSource"
|
||||
APIPathSourceTypeRTMPConn APIPathSourceType = "rtmpConn"
|
||||
APIPathSourceTypeRTMPSConn APIPathSourceType = "rtmpsConn"
|
||||
APIPathSourceTypeRTMPSource APIPathSourceType = "rtmpSource"
|
||||
APIPathSourceTypeRTSPSession APIPathSourceType = "rtspSession"
|
||||
APIPathSourceTypeRTSPSource APIPathSourceType = "rtspSource"
|
||||
APIPathSourceTypeRTSPSSession APIPathSourceType = "rtspsSession"
|
||||
APIPathSourceTypeSRTConn APIPathSourceType = "srtConn"
|
||||
APIPathSourceTypeSRTSource APIPathSourceType = "srtSource"
|
||||
APIPathSourceTypeMPEGTSSource APIPathSourceType = "mpegtsSource"
|
||||
APIPathSourceTypeRTPSource APIPathSourceType = "rtpSource"
|
||||
APIPathSourceTypeWebRTCSession APIPathSourceType = "webRTCSession"
|
||||
APIPathSourceTypeWebRTCSource APIPathSourceType = "webRTCSource"
|
||||
)
|
||||
|
||||
// APIPathSource is a source.
|
||||
type APIPathSource struct {
|
||||
Type APIPathSourceType `json:"type"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// APIPathReaderType is the type of a path reader.
|
||||
type APIPathReaderType string
|
||||
|
||||
// reader types.
|
||||
const (
|
||||
APIPathReaderTypeHLSMuxer APIPathReaderType = "hlsMuxer"
|
||||
APIPathReaderTypeRTMPConn APIPathReaderType = "rtmpConn"
|
||||
APIPathReaderTypeRTMPSConn APIPathReaderType = "rtmpsConn"
|
||||
APIPathReaderTypeRTSPConn APIPathReaderType = "rtspConn"
|
||||
APIPathReaderTypeRPICameraSecondary APIPathReaderType = "rpiCameraSecondary"
|
||||
APIPathReaderTypeRTSPSession APIPathReaderType = "rtspSession"
|
||||
APIPathReaderTypeRTSPSConn APIPathReaderType = "rtspsConn"
|
||||
APIPathReaderTypeRTSPSSession APIPathReaderType = "rtspsSession"
|
||||
APIPathReaderTypeSRTConn APIPathReaderType = "srtConn"
|
||||
APIPathReaderTypeWebRTCSession APIPathReaderType = "webRTCSession"
|
||||
)
|
||||
|
||||
// APIPathReader is a reader.
|
||||
type APIPathReader struct {
|
||||
Type APIPathReaderType `json:"type"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// APIPath is a path.
|
||||
type APIPath struct {
|
||||
Name string `json:"name"`
|
||||
ConfName string `json:"confName"`
|
||||
Ready bool `json:"ready" deprecated:"true"`
|
||||
ReadyTime *time.Time `json:"readyTime" deprecated:"true"`
|
||||
Available bool `json:"available"`
|
||||
AvailableTime *time.Time `json:"availableTime"`
|
||||
Online bool `json:"online"`
|
||||
OnlineTime *time.Time `json:"onlineTime"`
|
||||
Source *APIPathSource `json:"source"`
|
||||
Tracks []APIPathTrackCodec `json:"tracks"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
Readers []APIPathReader `json:"readers"`
|
||||
}
|
||||
|
||||
// APIPathList is a list of paths.
|
||||
type APIPathList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIPath `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"github.com/bluenviron/gortsplib/v5/pkg/description"
|
||||
"github.com/bluenviron/gortsplib/v5/pkg/format"
|
||||
)
|
||||
|
||||
// APIPathTrackCodec is a path track codec.
|
||||
type APIPathTrackCodec string
|
||||
|
||||
// path track codecs.
|
||||
const (
|
||||
// video
|
||||
APIPathTrackCodecAV1 APIPathTrackCodec = "AV1"
|
||||
APIPathTrackCodecVP9 APIPathTrackCodec = "VP9"
|
||||
APIPathTrackCodecVP8 APIPathTrackCodec = "VP8"
|
||||
APIPathTrackCodecH265 APIPathTrackCodec = "H265"
|
||||
APIPathTrackCodecH264 APIPathTrackCodec = "H264"
|
||||
APIPathTrackCodecMPEG4Video APIPathTrackCodec = "MPEG-4 Video"
|
||||
APIPathTrackCodecMPEG1Video APIPathTrackCodec = "MPEG-1 Video"
|
||||
APIPathTrackCodecMJPEG APIPathTrackCodec = "MJPEG"
|
||||
// audio
|
||||
APIPathTrackCodecOpus APIPathTrackCodec = "Opus"
|
||||
APIPathTrackCodecVorbis APIPathTrackCodec = "Vorbis"
|
||||
APIPathTrackCodecMPEG4Audio APIPathTrackCodec = "MPEG-4 Audio"
|
||||
APIPathTrackCodecMPEG4AudioLATM APIPathTrackCodec = "MPEG-4 Audio LATM"
|
||||
APIPathTrackCodecMPEG1Audio APIPathTrackCodec = "MPEG-1 Audio"
|
||||
APIPathTrackCodecAC3 APIPathTrackCodec = "AC3"
|
||||
APIPathTrackCodecSpeex APIPathTrackCodec = "Speex"
|
||||
APIPathTrackCodecG726 APIPathTrackCodec = "G726"
|
||||
APIPathTrackCodecG722 APIPathTrackCodec = "G722"
|
||||
APIPathTrackCodecG711 APIPathTrackCodec = "G711"
|
||||
APIPathTrackCodecLPCM APIPathTrackCodec = "LPCM"
|
||||
// other
|
||||
APIPathTrackCodecMPEGTS APIPathTrackCodec = "MPEG-TS"
|
||||
APIPathTrackCodecKLV APIPathTrackCodec = "KLV"
|
||||
APIPathTrackCodecGeneric APIPathTrackCodec = "Generic"
|
||||
)
|
||||
|
||||
// FormatsToCodecs returns codecs of given formats.
|
||||
func FormatsToCodecs(formats []format.Format) []APIPathTrackCodec {
|
||||
ret := make([]APIPathTrackCodec, len(formats))
|
||||
|
||||
for i, forma := range formats {
|
||||
switch forma.(type) {
|
||||
// video
|
||||
case *format.AV1:
|
||||
ret[i] = APIPathTrackCodecAV1
|
||||
case *format.VP9:
|
||||
ret[i] = APIPathTrackCodecVP9
|
||||
case *format.VP8:
|
||||
ret[i] = APIPathTrackCodecVP8
|
||||
case *format.H265:
|
||||
ret[i] = APIPathTrackCodecH265
|
||||
case *format.H264:
|
||||
ret[i] = APIPathTrackCodecH264
|
||||
case *format.MPEG4Video:
|
||||
ret[i] = APIPathTrackCodecMPEG4Video
|
||||
case *format.MPEG1Video:
|
||||
ret[i] = APIPathTrackCodecMPEG1Video
|
||||
case *format.MJPEG:
|
||||
ret[i] = APIPathTrackCodecMJPEG
|
||||
// audio
|
||||
case *format.Opus:
|
||||
ret[i] = APIPathTrackCodecOpus
|
||||
case *format.Vorbis:
|
||||
ret[i] = APIPathTrackCodecVorbis
|
||||
case *format.MPEG4Audio:
|
||||
ret[i] = APIPathTrackCodecMPEG4Audio
|
||||
case *format.MPEG4AudioLATM:
|
||||
ret[i] = APIPathTrackCodecMPEG4AudioLATM
|
||||
case *format.MPEG1Audio:
|
||||
ret[i] = APIPathTrackCodecMPEG1Audio
|
||||
case *format.AC3:
|
||||
ret[i] = APIPathTrackCodecAC3
|
||||
case *format.Speex:
|
||||
ret[i] = APIPathTrackCodecSpeex
|
||||
case *format.G726:
|
||||
ret[i] = APIPathTrackCodecG726
|
||||
case *format.G722:
|
||||
ret[i] = APIPathTrackCodecG722
|
||||
case *format.G711:
|
||||
ret[i] = APIPathTrackCodecG711
|
||||
case *format.LPCM:
|
||||
ret[i] = APIPathTrackCodecLPCM
|
||||
// other
|
||||
case *format.MPEGTS:
|
||||
ret[i] = APIPathTrackCodecMPEGTS
|
||||
case *format.KLV:
|
||||
ret[i] = APIPathTrackCodecKLV
|
||||
default:
|
||||
ret[i] = APIPathTrackCodecGeneric
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func gatherFormats(medias []*description.Media) []format.Format {
|
||||
n := 0
|
||||
for _, media := range medias {
|
||||
n += len(media.Formats)
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
formats := make([]format.Format, n)
|
||||
n = 0
|
||||
|
||||
for _, media := range medias {
|
||||
n += copy(formats[n:], media.Formats)
|
||||
}
|
||||
|
||||
return formats
|
||||
}
|
||||
|
||||
// MediasToCodecs returns codecs of given medias.
|
||||
func MediasToCodecs(medias []*description.Media) []APIPathTrackCodec {
|
||||
return FormatsToCodecs(gatherFormats(medias))
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bluenviron/gortsplib/v5/pkg/format"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFormatsToCodecs(t *testing.T) {
|
||||
codecs := FormatsToCodecs([]format.Format{
|
||||
&format.AV1{},
|
||||
&format.VP9{},
|
||||
&format.VP8{},
|
||||
&format.H265{},
|
||||
&format.H264{},
|
||||
&format.MPEG4Video{},
|
||||
&format.MPEG1Video{},
|
||||
&format.MJPEG{},
|
||||
&format.Opus{},
|
||||
&format.Vorbis{},
|
||||
&format.MPEG4Audio{},
|
||||
&format.MPEG4AudioLATM{},
|
||||
&format.MPEG1Audio{},
|
||||
&format.AC3{},
|
||||
&format.Speex{},
|
||||
&format.G726{},
|
||||
&format.G722{},
|
||||
&format.G711{},
|
||||
&format.LPCM{},
|
||||
&format.MPEGTS{},
|
||||
&format.KLV{},
|
||||
&format.Generic{},
|
||||
})
|
||||
|
||||
require.Equal(t, []APIPathTrackCodec{
|
||||
APIPathTrackCodecAV1,
|
||||
APIPathTrackCodecVP9,
|
||||
APIPathTrackCodecVP8,
|
||||
APIPathTrackCodecH265,
|
||||
APIPathTrackCodecH264,
|
||||
APIPathTrackCodecMPEG4Video,
|
||||
APIPathTrackCodecMPEG1Video,
|
||||
APIPathTrackCodecMJPEG,
|
||||
APIPathTrackCodecOpus,
|
||||
APIPathTrackCodecVorbis,
|
||||
APIPathTrackCodecMPEG4Audio,
|
||||
APIPathTrackCodecMPEG4AudioLATM,
|
||||
APIPathTrackCodecMPEG1Audio,
|
||||
APIPathTrackCodecAC3,
|
||||
APIPathTrackCodecSpeex,
|
||||
APIPathTrackCodecG726,
|
||||
APIPathTrackCodecG722,
|
||||
APIPathTrackCodecG711,
|
||||
APIPathTrackCodecLPCM,
|
||||
APIPathTrackCodecMPEGTS,
|
||||
APIPathTrackCodecKLV,
|
||||
APIPathTrackCodecGeneric,
|
||||
}, codecs)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package defs
|
||||
|
||||
import "time"
|
||||
|
||||
// APIRecordingSegment is a recording segment.
|
||||
type APIRecordingSegment struct {
|
||||
Start time.Time `json:"start"`
|
||||
}
|
||||
|
||||
// APIRecording is a recording.
|
||||
type APIRecording struct {
|
||||
Name string `json:"name"`
|
||||
Segments []APIRecordingSegment `json:"segments"`
|
||||
}
|
||||
|
||||
// APIRecordingList is a list of recordings.
|
||||
type APIRecordingList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRecording `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// APIRTMPServer contains methods used by the API and Metrics server.
|
||||
type APIRTMPServer interface {
|
||||
APIConnsList() (*APIRTMPConnList, error)
|
||||
APIConnsGet(uuid.UUID) (*APIRTMPConn, error)
|
||||
APIConnsKick(uuid.UUID) error
|
||||
}
|
||||
|
||||
// APIRTMPConnState is the state of a RTMP connection.
|
||||
type APIRTMPConnState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APIRTMPConnStateIdle APIRTMPConnState = "idle"
|
||||
APIRTMPConnStateRead APIRTMPConnState = "read"
|
||||
APIRTMPConnStatePublish APIRTMPConnState = "publish"
|
||||
)
|
||||
|
||||
// APIRTMPConn is a RTMP connection.
|
||||
type APIRTMPConn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
State APIRTMPConnState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
|
||||
// APIRTMPConnList is a list of RTMP connections.
|
||||
type APIRTMPConnList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTMPConn `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// APIRTSPServer contains methods used by the API and Metrics server.
|
||||
type APIRTSPServer interface {
|
||||
APIConnsList() (*APIRTSPConnsList, error)
|
||||
APIConnsGet(uuid.UUID) (*APIRTSPConn, error)
|
||||
APISessionsList() (*APIRTSPSessionList, error)
|
||||
APISessionsGet(uuid.UUID) (*APIRTSPSession, error)
|
||||
APISessionsKick(uuid.UUID) error
|
||||
}
|
||||
|
||||
// APIRTSPConn is a RTSP connection.
|
||||
type APIRTSPConn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
Session *uuid.UUID `json:"session"`
|
||||
Tunnel string `json:"tunnel"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
}
|
||||
|
||||
// APIRTSPConnsList is a list of RTSP connections.
|
||||
type APIRTSPConnsList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTSPConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTSPSessionState is the state of a RTSP session.
|
||||
type APIRTSPSessionState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APIRTSPSessionStateIdle APIRTSPSessionState = "idle"
|
||||
APIRTSPSessionStateRead APIRTSPSessionState = "read"
|
||||
APIRTSPSessionStatePublish APIRTSPSessionState = "publish"
|
||||
)
|
||||
|
||||
// APIRTSPSession is a RTSP session.
|
||||
type APIRTSPSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
State APIRTSPSessionState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
Transport *string `json:"transport"`
|
||||
Profile *string `json:"profile"`
|
||||
Conns []uuid.UUID `json:"conns"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
RTPPacketsReceived uint64 `json:"rtpPacketsReceived"`
|
||||
RTPPacketsSent uint64 `json:"rtpPacketsSent"`
|
||||
RTPPacketsLost uint64 `json:"rtpPacketsLost"`
|
||||
RTPPacketsInError uint64 `json:"rtpPacketsInError"`
|
||||
RTPPacketsJitter float64 `json:"rtpPacketsJitter"`
|
||||
RTCPPacketsReceived uint64 `json:"rtcpPacketsReceived"`
|
||||
RTCPPacketsSent uint64 `json:"rtcpPacketsSent"`
|
||||
RTCPPacketsInError uint64 `json:"rtcpPacketsInError"`
|
||||
}
|
||||
|
||||
// APIRTSPSessionList is a list of RTSP sessions.
|
||||
type APIRTSPSessionList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTSPSession `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// APISRTServer contains methods used by the API and Metrics server.
|
||||
type APISRTServer interface {
|
||||
APIConnsList() (*APISRTConnList, error)
|
||||
APIConnsGet(uuid.UUID) (*APISRTConn, error)
|
||||
APIConnsKick(uuid.UUID) error
|
||||
}
|
||||
|
||||
// APISRTConnState is the state of a SRT connection.
|
||||
type APISRTConnState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APISRTConnStateIdle APISRTConnState = "idle"
|
||||
APISRTConnStateRead APISRTConnState = "read"
|
||||
APISRTConnStatePublish APISRTConnState = "publish"
|
||||
)
|
||||
|
||||
// APISRTConn is a SRT connection.
|
||||
type APISRTConn struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
State APISRTConnState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
|
||||
// The metric names/comments are pulled from GoSRT
|
||||
|
||||
// The total number of sent DATA packets, including retransmitted packets
|
||||
PacketsSent uint64 `json:"packetsSent"`
|
||||
// The total number of received DATA packets, including retransmitted packets
|
||||
PacketsReceived uint64 `json:"packetsReceived"`
|
||||
// The total number of unique DATA packets sent by the SRT sender
|
||||
PacketsSentUnique uint64 `json:"packetsSentUnique"`
|
||||
// The total number of unique original, retransmitted or recovered by the packet filter DATA packets
|
||||
// received in time, decrypted without errors and, as a result, scheduled for delivery to the
|
||||
// upstream application by the SRT receiver.
|
||||
PacketsReceivedUnique uint64 `json:"packetsReceivedUnique"`
|
||||
// The total number of data packets considered or reported as lost at the sender side.
|
||||
// Does not correspond to the packets detected as lost at the receiver side.
|
||||
PacketsSendLoss uint64 `json:"packetsSendLoss"`
|
||||
// The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||
PacketsReceivedLoss uint64 `json:"packetsReceivedLoss"`
|
||||
// The total number of retransmitted packets sent by the SRT sender
|
||||
PacketsRetrans uint64 `json:"packetsRetrans"`
|
||||
// The total number of retransmitted packets registered at the receiver side
|
||||
PacketsReceivedRetrans uint64 `json:"packetsReceivedRetrans"`
|
||||
// The total number of sent ACK (Acknowledgement) control packets
|
||||
PacketsSentACK uint64 `json:"packetsSentACK"`
|
||||
// The total number of received ACK (Acknowledgement) control packets
|
||||
PacketsReceivedACK uint64 `json:"packetsReceivedACK"`
|
||||
// The total number of sent NAK (Negative Acknowledgement) control packets
|
||||
PacketsSentNAK uint64 `json:"packetsSentNAK"`
|
||||
// The total number of received NAK (Negative Acknowledgement) control packets
|
||||
PacketsReceivedNAK uint64 `json:"packetsReceivedNAK"`
|
||||
// The total number of sent KM (Key Material) control packets
|
||||
PacketsSentKM uint64 `json:"packetsSentKM"`
|
||||
// The total number of received KM (Key Material) control packets
|
||||
PacketsReceivedKM uint64 `json:"packetsReceivedKM"`
|
||||
// The total accumulated time in microseconds, during which the SRT sender has some data to transmit,
|
||||
// including packets that have been sent, but not yet acknowledged
|
||||
UsSndDuration uint64 `json:"usSndDuration"`
|
||||
// ??
|
||||
PacketsReceivedBelated uint64 `json:"packetsReceivedBelated"`
|
||||
// The total number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
|
||||
PacketsSendDrop uint64 `json:"packetsSendDrop"`
|
||||
// The total number of dropped by the SRT receiver and, as a result,
|
||||
// not delivered to the upstream application DATA packets
|
||||
PacketsReceivedDrop uint64 `json:"packetsReceivedDrop"`
|
||||
// The total number of packets that failed to be decrypted at the receiver side
|
||||
PacketsReceivedUndecrypt uint64 `json:"packetsReceivedUndecrypt"`
|
||||
|
||||
// Same as packetsReceived, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
// Same as packetsSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
// Same as packetsSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesSentUnique uint64 `json:"bytesSentUnique"`
|
||||
// Same as packetsReceivedUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedUnique uint64 `json:"bytesReceivedUnique"`
|
||||
// Same as packetsReceivedLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT),
|
||||
// bytes for the presently missing (either reordered or lost) packets' payloads are estimated
|
||||
// based on the average packet size
|
||||
BytesReceivedLoss uint64 `json:"bytesReceivedLoss"`
|
||||
// Same as packetsRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesRetrans uint64 `json:"bytesRetrans"`
|
||||
// Same as packetsReceivedRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedRetrans uint64 `json:"bytesReceivedRetrans"`
|
||||
// Same as PacketsReceivedBelated, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedBelated uint64 `json:"bytesReceivedBelated"`
|
||||
// Same as packetsSendDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesSendDrop uint64 `json:"bytesSendDrop"`
|
||||
// Same as packetsReceivedDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedDrop uint64 `json:"bytesReceivedDrop"`
|
||||
// Same as packetsReceivedUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
BytesReceivedUndecrypt uint64 `json:"bytesReceivedUndecrypt"`
|
||||
|
||||
// Current minimum time interval between which consecutive packets are sent, in microseconds
|
||||
UsPacketsSendPeriod float64 `json:"usPacketsSendPeriod"`
|
||||
// The maximum number of packets that can be "in flight"
|
||||
PacketsFlowWindow uint64 `json:"packetsFlowWindow"`
|
||||
// The number of packets in flight
|
||||
PacketsFlightSize uint64 `json:"packetsFlightSize"`
|
||||
// Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA)
|
||||
// of an endpoint's RTT samples, in milliseconds
|
||||
MsRTT float64 `json:"msRTT"`
|
||||
// Current transmission bandwidth, in Mbps
|
||||
MbpsSendRate float64 `json:"mbpsSendRate"`
|
||||
// Current receiving bandwidth, in Mbps
|
||||
MbpsReceiveRate float64 `json:"mbpsReceiveRate"`
|
||||
// Estimated capacity of the network link, in Mbps
|
||||
MbpsLinkCapacity float64 `json:"mbpsLinkCapacity"`
|
||||
// The available space in the sender's buffer, in bytes
|
||||
BytesAvailSendBuf uint64 `json:"bytesAvailSendBuf"`
|
||||
// The available space in the receiver's buffer, in bytes
|
||||
BytesAvailReceiveBuf uint64 `json:"bytesAvailReceiveBuf"`
|
||||
// Transmission bandwidth limit, in Mbps
|
||||
MbpsMaxBW float64 `json:"mbpsMaxBW"`
|
||||
// Maximum Segment Size (MSS), in bytes
|
||||
ByteMSS uint64 `json:"byteMSS"`
|
||||
// The number of packets in the sender's buffer that are already scheduled
|
||||
// for sending or even possibly sent, but not yet acknowledged
|
||||
PacketsSendBuf uint64 `json:"packetsSendBuf"`
|
||||
// Instantaneous (current) value of packetsSndBuf, but expressed in bytes,
|
||||
// including payload and all headers (IP, TCP, SRT)
|
||||
BytesSendBuf uint64 `json:"bytesSendBuf"`
|
||||
// The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
|
||||
MsSendBuf uint64 `json:"msSendBuf"`
|
||||
// Timestamp-based Packet Delivery Delay value of the peer
|
||||
MsSendTsbPdDelay uint64 `json:"msSendTsbPdDelay"`
|
||||
// The number of acknowledged packets in receiver's buffer
|
||||
PacketsReceiveBuf uint64 `json:"packetsReceiveBuf"`
|
||||
// Instantaneous (current) value of packetsRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
BytesReceiveBuf uint64 `json:"bytesReceiveBuf"`
|
||||
// The timespan (msec) of acknowledged packets in the receiver's buffer
|
||||
MsReceiveBuf uint64 `json:"msReceiveBuf"`
|
||||
// Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
|
||||
MsReceiveTsbPdDelay uint64 `json:"msReceiveTsbPdDelay"`
|
||||
// Instant value of the packet reorder tolerance
|
||||
PacketsReorderTolerance uint64 `json:"packetsReorderTolerance"`
|
||||
// Accumulated difference between the current time and the time-to-play of a packet that is received late
|
||||
PacketsReceivedAvgBelatedTime uint64 `json:"packetsReceivedAvgBelatedTime"`
|
||||
// Percentage of resent data vs. sent data
|
||||
PacketsSendLossRate float64 `json:"packetsSendLossRate"`
|
||||
// Percentage of retransmitted data vs. received data
|
||||
PacketsReceivedLossRate float64 `json:"packetsReceivedLossRate"`
|
||||
}
|
||||
|
||||
// APISRTConnList is a list of SRT connections.
|
||||
type APISRTConnList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APISRTConn `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package defs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// APIWebRTCServer contains methods used by the API and Metrics server.
|
||||
type APIWebRTCServer interface {
|
||||
APISessionsList() (*APIWebRTCSessionList, error)
|
||||
APISessionsGet(uuid.UUID) (*APIWebRTCSession, error)
|
||||
APISessionsKick(uuid.UUID) error
|
||||
}
|
||||
|
||||
// APIWebRTCSessionState is the state of a WebRTC connection.
|
||||
type APIWebRTCSessionState string
|
||||
|
||||
// states.
|
||||
const (
|
||||
APIWebRTCSessionStateRead APIWebRTCSessionState = "read"
|
||||
APIWebRTCSessionStatePublish APIWebRTCSessionState = "publish"
|
||||
)
|
||||
|
||||
// APIWebRTCSession is a WebRTC session.
|
||||
type APIWebRTCSession struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Created time.Time `json:"created"`
|
||||
RemoteAddr string `json:"remoteAddr"`
|
||||
PeerConnectionEstablished bool `json:"peerConnectionEstablished"`
|
||||
LocalCandidate string `json:"localCandidate"`
|
||||
RemoteCandidate string `json:"remoteCandidate"`
|
||||
State APIWebRTCSessionState `json:"state"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query"`
|
||||
User string `json:"user"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
RTPPacketsReceived uint64 `json:"rtpPacketsReceived"`
|
||||
RTPPacketsSent uint64 `json:"rtpPacketsSent"`
|
||||
RTPPacketsLost uint64 `json:"rtpPacketsLost"`
|
||||
RTPPacketsJitter float64 `json:"rtpPacketsJitter"`
|
||||
RTCPPacketsReceived uint64 `json:"rtcpPacketsReceived"`
|
||||
RTCPPacketsSent uint64 `json:"rtcpPacketsSent"`
|
||||
}
|
||||
|
||||
// APIWebRTCSessionList is a list of WebRTC sessions.
|
||||
type APIWebRTCSessionList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIWebRTCSession `json:"items"`
|
||||
}
|
||||
+7
-35
@@ -20,17 +20,14 @@ type Source interface {
|
||||
APISourceDescribe() *APIPathSource
|
||||
}
|
||||
|
||||
// FormatsToCodecs returns the name of codecs of given formats.
|
||||
func FormatsToCodecs(formats []format.Format) []string {
|
||||
ret := make([]string, len(formats))
|
||||
for i, forma := range formats {
|
||||
ret[i] = forma.Codec()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// FormatsInfo returns a description of formats.
|
||||
func FormatsInfo(formats []format.Format) string {
|
||||
codecs := FormatsToCodecs(formats)
|
||||
codecNames := make([]string, len(codecs))
|
||||
for i, codec := range codecs {
|
||||
codecNames[i] = string(codec)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%d %s (%s)",
|
||||
len(formats),
|
||||
func() string {
|
||||
@@ -39,32 +36,7 @@ func FormatsInfo(formats []format.Format) string {
|
||||
}
|
||||
return "tracks"
|
||||
}(),
|
||||
strings.Join(FormatsToCodecs(formats), ", "))
|
||||
}
|
||||
|
||||
func gatherFormats(medias []*description.Media) []format.Format {
|
||||
n := 0
|
||||
for _, media := range medias {
|
||||
n += len(media.Formats)
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
formats := make([]format.Format, n)
|
||||
n = 0
|
||||
|
||||
for _, media := range medias {
|
||||
n += copy(formats[n:], media.Formats)
|
||||
}
|
||||
|
||||
return formats
|
||||
}
|
||||
|
||||
// MediasToCodecs returns the name of codecs of given formats.
|
||||
func MediasToCodecs(medias []*description.Media) []string {
|
||||
return FormatsToCodecs(gatherFormats(medias))
|
||||
strings.Join(codecNames, ", "))
|
||||
}
|
||||
|
||||
// MediasInfo returns a description of medias.
|
||||
|
||||
@@ -28,7 +28,7 @@ func OnConnect(params OnConnectParams) func() {
|
||||
_, port, _ := net.SplitHostPort(params.RTSPAddress)
|
||||
env = externalcmd.Environment{
|
||||
"RTSP_PORT": port,
|
||||
"MTX_CONN_TYPE": params.Desc.Type,
|
||||
"MTX_CONN_TYPE": string(params.Desc.Type),
|
||||
"MTX_CONN_ID": params.Desc.ID,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ func OnRead(params OnReadParams) func() {
|
||||
env = params.ExternalCmdEnv
|
||||
desc := params.Reader
|
||||
env["MTX_QUERY"] = params.Query
|
||||
env["MTX_READER_TYPE"] = desc.Type
|
||||
env["MTX_READER_TYPE"] = string(desc.Type)
|
||||
env["MTX_READER_ID"] = desc.ID
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ func OnReady(params OnReadyParams) func() {
|
||||
env = params.ExternalCmdEnv
|
||||
env["MTX_QUERY"] = params.Query
|
||||
if params.Desc != nil {
|
||||
env["MTX_SOURCE_TYPE"] = params.Desc.Type
|
||||
env["MTX_SOURCE_TYPE"] = string(params.Desc.Type)
|
||||
env["MTX_SOURCE_ID"] = params.Desc.ID
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,32 @@ type openAPIProperty struct {
|
||||
Ref string `yaml:"$ref"`
|
||||
Type string `yaml:"type"`
|
||||
Format string `yaml:"format"`
|
||||
AllOf []openAPIProperty `yaml:"allOf"`
|
||||
Nullable bool `yaml:"nullable"`
|
||||
Deprecated bool `yaml:"deprecated"`
|
||||
Enum []string `yaml:"enum"`
|
||||
Items *openAPIProperty `yaml:"items"`
|
||||
}
|
||||
|
||||
func wrapRef(rt reflect.Type, p openAPIProperty) openAPIProperty {
|
||||
if p.Ref == "" {
|
||||
return p
|
||||
}
|
||||
|
||||
if _, ok := goEnumToApi(rt); ok {
|
||||
p.Type = "string"
|
||||
} else if rt.Kind() == reflect.Struct {
|
||||
p.Type = "object"
|
||||
}
|
||||
|
||||
p.AllOf = []openAPIProperty{{Ref: p.Ref}}
|
||||
p.Ref = ""
|
||||
return p
|
||||
}
|
||||
|
||||
type openAPISchema struct {
|
||||
Type string `yaml:"type"`
|
||||
Enum []string `yaml:"enum"`
|
||||
Properties map[string]openAPIProperty `yaml:"properties"`
|
||||
}
|
||||
|
||||
@@ -36,13 +55,28 @@ type openAPI struct {
|
||||
} `yaml:"components"`
|
||||
}
|
||||
|
||||
func fillProperty(t *testing.T, rt reflect.Type) openAPIProperty {
|
||||
func schemaName(rt reflect.Type) string {
|
||||
name := strings.TrimPrefix(rt.Name(), "API")
|
||||
|
||||
if rt.PkgPath() == "github.com/bluenviron/mediamtx/internal/conf" && name == "Path" {
|
||||
return "PathConf"
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func goStructToApi(t *testing.T, rt reflect.Type) openAPIProperty {
|
||||
if rt.Kind() == reflect.Pointer {
|
||||
prop := fillProperty(t, rt.Elem())
|
||||
prop := goStructToApi(t, rt.Elem())
|
||||
prop = wrapRef(rt.Elem(), prop)
|
||||
prop.Nullable = true
|
||||
return prop
|
||||
}
|
||||
|
||||
if _, ok := goEnumToApi(rt); ok {
|
||||
return openAPIProperty{Ref: "#/components/schemas/" + schemaName(rt)}
|
||||
}
|
||||
|
||||
switch {
|
||||
case rt == reflect.TypeOf(""):
|
||||
return openAPIProperty{Type: "string"}
|
||||
@@ -69,22 +103,7 @@ func fillProperty(t *testing.T, rt reflect.Type) openAPIProperty {
|
||||
rt == reflect.TypeOf(conf.Duration(0)) ||
|
||||
rt == reflect.TypeOf(conf.IPNetwork{}) ||
|
||||
rt == reflect.TypeOf(conf.Credential("")) ||
|
||||
rt == reflect.TypeOf(conf.RecordFormat("")) ||
|
||||
rt == reflect.TypeOf(conf.AuthAction("")) ||
|
||||
rt == reflect.TypeOf(conf.Encryption("")) ||
|
||||
rt == reflect.TypeOf(conf.RTSPTransport{}) ||
|
||||
rt == reflect.TypeOf(conf.StringSize(0)) ||
|
||||
rt == reflect.TypeOf(conf.RTSPRangeType("")) ||
|
||||
rt == reflect.TypeOf(conf.LogLevel(0)) ||
|
||||
rt == reflect.TypeOf(conf.AuthMethod("")) ||
|
||||
rt == reflect.TypeOf(conf.LogDestination(0)) ||
|
||||
rt == reflect.TypeOf(conf.RTSPAuthMethod(0)) ||
|
||||
rt == reflect.TypeOf(conf.HLSVariant(0)) ||
|
||||
rt == reflect.TypeOf(defs.APIRTMPConnState("")) ||
|
||||
rt == reflect.TypeOf(defs.APIWebRTCSessionState("")) ||
|
||||
rt == reflect.TypeOf(defs.APISRTConnState("")) ||
|
||||
rt == reflect.TypeOf(defs.APIRTSPSessionState("")) ||
|
||||
rt == reflect.TypeOf(conf.Codec("")):
|
||||
rt == reflect.TypeOf(conf.StringSize(0)):
|
||||
return openAPIProperty{Type: "string"}
|
||||
|
||||
case rt == reflect.TypeOf(conf.RTSPTransports{}):
|
||||
@@ -92,21 +111,17 @@ func fillProperty(t *testing.T, rt reflect.Type) openAPIProperty {
|
||||
Type: "array",
|
||||
Items: &openAPIProperty{
|
||||
Type: "string",
|
||||
Enum: []string{"udp", "multicast", "tcp"},
|
||||
},
|
||||
}
|
||||
|
||||
case rt.Kind() == reflect.Struct:
|
||||
schemaName := strings.TrimPrefix(rt.Name(), "API")
|
||||
if rt.PkgPath() == "github.com/bluenviron/mediamtx/internal/conf" && schemaName == "Path" {
|
||||
schemaName = "PathConf"
|
||||
}
|
||||
|
||||
return openAPIProperty{
|
||||
Ref: "#/components/schemas/" + schemaName,
|
||||
Ref: "#/components/schemas/" + schemaName(rt),
|
||||
}
|
||||
|
||||
case rt.Kind() == reflect.Slice:
|
||||
items := fillProperty(t, rt.Elem())
|
||||
items := goStructToApi(t, rt.Elem())
|
||||
return openAPIProperty{
|
||||
Type: "array",
|
||||
Items: &items,
|
||||
@@ -118,6 +133,175 @@ func fillProperty(t *testing.T, rt reflect.Type) openAPIProperty {
|
||||
}
|
||||
}
|
||||
|
||||
func goEnumToApi(rt reflect.Type) (openAPISchema, bool) {
|
||||
switch rt {
|
||||
case reflect.TypeOf(defs.APIOKStatus("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{"ok"}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIErrorStatus("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{"error"}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIPathSourceType("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"hlsSource",
|
||||
"redirect",
|
||||
"rpiCameraSource",
|
||||
"rtmpConn",
|
||||
"rtmpsConn",
|
||||
"rtmpSource",
|
||||
"rtspSession",
|
||||
"rtspSource",
|
||||
"rtspsSession",
|
||||
"srtConn",
|
||||
"srtSource",
|
||||
"mpegtsSource",
|
||||
"rtpSource",
|
||||
"webRTCSession",
|
||||
"webRTCSource",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIPathReaderType("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"hlsMuxer",
|
||||
"rpiCameraSecondary",
|
||||
"rtmpConn",
|
||||
"rtmpsConn",
|
||||
"rtspConn",
|
||||
"rtspSession",
|
||||
"rtspsConn",
|
||||
"rtspsSession",
|
||||
"srtConn",
|
||||
"webRTCSession",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIPathTrackCodec("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"AV1",
|
||||
"VP9",
|
||||
"VP8",
|
||||
"H265",
|
||||
"H264",
|
||||
"MPEG-4 Video",
|
||||
"MPEG-1 Video",
|
||||
"MJPEG",
|
||||
"Opus",
|
||||
"Vorbis",
|
||||
"MPEG-4 Audio",
|
||||
"MPEG-4 Audio LATM",
|
||||
"MPEG-1 Audio",
|
||||
"AC3",
|
||||
"Speex",
|
||||
"G726",
|
||||
"G722",
|
||||
"G711",
|
||||
"LPCM",
|
||||
"MPEG-TS",
|
||||
"KLV",
|
||||
"Generic",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.AlwaysAvailableTrackCodec("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"AV1",
|
||||
"VP9",
|
||||
"H265",
|
||||
"H264",
|
||||
"MPEG4Audio",
|
||||
"Opus",
|
||||
"G711",
|
||||
"LPCM",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.AuthAction("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"publish",
|
||||
"read",
|
||||
"playback",
|
||||
"api",
|
||||
"metrics",
|
||||
"pprof",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.AuthMethod("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"internal",
|
||||
"http",
|
||||
"jwt",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.Encryption("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"no",
|
||||
"optional",
|
||||
"strict",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.HLSVariant(0)):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"mpegts",
|
||||
"fmp4",
|
||||
"lowLatency",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.LogDestination(0)):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"stdout",
|
||||
"file",
|
||||
"syslog",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.LogLevel(0)):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"error",
|
||||
"warn",
|
||||
"info",
|
||||
"debug",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.RecordFormat("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"fmp4",
|
||||
"mpegts",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.RTSPAuthMethod(0)):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"basic",
|
||||
"digest",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.RTSPRangeType("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"",
|
||||
"clock",
|
||||
"npt",
|
||||
"smpte",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(conf.RTSPTransport{}):
|
||||
return openAPISchema{Type: "string", Enum: []string{
|
||||
"udp",
|
||||
"multicast",
|
||||
"tcp",
|
||||
"automatic",
|
||||
}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIRTMPConnState("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{"idle", "read", "publish"}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIWebRTCSessionState("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{"read", "publish"}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APISRTConnState("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{"idle", "read", "publish"}}, true
|
||||
|
||||
case reflect.TypeOf(defs.APIRTSPSessionState("")):
|
||||
return openAPISchema{Type: "string", Enum: []string{"idle", "read", "publish"}}, true
|
||||
}
|
||||
|
||||
return openAPISchema{}, false
|
||||
}
|
||||
|
||||
func TestGo2API(t *testing.T) {
|
||||
byts, err := os.ReadFile("../../../api/openapi.yaml")
|
||||
require.NoError(t, err)
|
||||
@@ -126,6 +310,7 @@ func TestGo2API(t *testing.T) {
|
||||
err = yaml.Unmarshal(byts, &doc)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("structs", func(t *testing.T) {
|
||||
for _, ca := range []struct {
|
||||
openAPIKey string
|
||||
goStruct any
|
||||
@@ -253,8 +438,11 @@ func TestGo2API(t *testing.T) {
|
||||
|
||||
if name != "" && name != "-" && name != "paths" && name != "pathDefaults" &&
|
||||
(!strings.Contains(js, ",omitempty") || deprecated) {
|
||||
prop := fillProperty(t, sf.Type)
|
||||
prop := goStructToApi(t, sf.Type)
|
||||
prop.Deprecated = deprecated
|
||||
if deprecated {
|
||||
prop = wrapRef(sf.Type, prop)
|
||||
}
|
||||
content2.Properties[name] = prop
|
||||
}
|
||||
}
|
||||
@@ -262,4 +450,37 @@ func TestGo2API(t *testing.T) {
|
||||
require.Equal(t, content2, content1)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("enums", func(t *testing.T) {
|
||||
for _, rt := range []reflect.Type{
|
||||
reflect.TypeOf(defs.APIOKStatus("")),
|
||||
reflect.TypeOf(defs.APIErrorStatus("")),
|
||||
reflect.TypeOf(defs.APIPathSourceType("")),
|
||||
reflect.TypeOf(defs.APIPathReaderType("")),
|
||||
reflect.TypeOf(defs.APIPathTrackCodec("")),
|
||||
reflect.TypeOf(conf.AlwaysAvailableTrackCodec("")),
|
||||
reflect.TypeOf(conf.AuthAction("")),
|
||||
reflect.TypeOf(conf.AuthMethod("")),
|
||||
reflect.TypeOf(conf.Encryption("")),
|
||||
reflect.TypeOf(conf.HLSVariant(0)),
|
||||
reflect.TypeOf(conf.LogDestination(0)),
|
||||
reflect.TypeOf(conf.LogLevel(0)),
|
||||
reflect.TypeOf(conf.RecordFormat("")),
|
||||
reflect.TypeOf(conf.RTSPAuthMethod(0)),
|
||||
reflect.TypeOf(conf.RTSPRangeType("")),
|
||||
reflect.TypeOf(conf.RTSPTransport{}),
|
||||
reflect.TypeOf(defs.APIRTMPConnState("")),
|
||||
reflect.TypeOf(defs.APIRTSPSessionState("")),
|
||||
reflect.TypeOf(defs.APISRTConnState("")),
|
||||
reflect.TypeOf(defs.APIWebRTCSessionState("")),
|
||||
} {
|
||||
t.Run(rt.Name(), func(t *testing.T) {
|
||||
content1 := doc.Components.Schemas[schemaName(rt)]
|
||||
content2, ok := goEnumToApi(rt)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, content2, content1)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ func (m *Metrics) middlewareAuth(ctx *gin.Context) {
|
||||
if err.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
@@ -173,7 +173,7 @@ func (m *Metrics) middlewareAuth(ctx *gin.Context) {
|
||||
<-time.After(auth.PauseAfterError)
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
|
||||
@@ -32,17 +32,17 @@ func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
|
||||
Name: "mypath",
|
||||
ConfName: "mypathconf",
|
||||
Source: &defs.APIPathSource{
|
||||
Type: "testing",
|
||||
Type: defs.APIPathSourceTypeRTSPSession,
|
||||
ID: "123324354",
|
||||
},
|
||||
Ready: true,
|
||||
ReadyTime: ptrOf(time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC)),
|
||||
Tracks: []string{"H264", "H265"},
|
||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecH265},
|
||||
BytesReceived: 123,
|
||||
BytesSent: 456,
|
||||
Readers: []defs.APIPathReader{
|
||||
{
|
||||
Type: "testing",
|
||||
Type: defs.APIPathReaderTypeRTSPSession,
|
||||
ID: "345234423",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -129,7 +129,7 @@ func (s *Server) doAuth(ctx *gin.Context, pathName string) bool {
|
||||
if err.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return false
|
||||
@@ -142,7 +142,7 @@ func (s *Server) doAuth(ctx *gin.Context, pathName string) bool {
|
||||
<-time.After(auth.PauseAfterError)
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return false
|
||||
|
||||
@@ -108,7 +108,7 @@ func (pp *PPROF) middlewareAuth(ctx *gin.Context) {
|
||||
if err.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
@@ -120,7 +120,7 @@ func (pp *PPROF) middlewareAuth(ctx *gin.Context) {
|
||||
<-time.After(auth.PauseAfterError)
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
|
||||
@@ -161,7 +161,7 @@ func (s *httpServer) onRequest(ctx *gin.Context) {
|
||||
if terr.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
@@ -173,7 +173,7 @@ func (s *httpServer) onRequest(ctx *gin.Context) {
|
||||
<-time.After(auth.PauseAfterError)
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
|
||||
@@ -249,7 +249,7 @@ func (m *muxer) getInstance() *muxerInstance {
|
||||
// APIReaderDescribe implements reader.
|
||||
func (m *muxer) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "hlsMuxer",
|
||||
Type: defs.APIPathReaderTypeHLSMuxer,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,11 +291,11 @@ func (c *conn) runPublish() error {
|
||||
// APIReaderDescribe implements reader.
|
||||
func (c *conn) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: func() string {
|
||||
Type: func() defs.APIPathReaderType {
|
||||
if c.isTLS {
|
||||
return "rtmpsConn"
|
||||
return defs.APIPathReaderTypeRTMPSConn
|
||||
}
|
||||
return "rtmpConn"
|
||||
return defs.APIPathReaderTypeRTMPConn
|
||||
}(),
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
@@ -304,11 +304,11 @@ func (c *conn) APIReaderDescribe() *defs.APIPathReader {
|
||||
// APISourceDescribe implements source.
|
||||
func (c *conn) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: func() string {
|
||||
Type: func() defs.APIPathSourceType {
|
||||
if c.isTLS {
|
||||
return "rtmpsConn"
|
||||
return defs.APIPathSourceTypeRTMPSConn
|
||||
}
|
||||
return "rtmpConn"
|
||||
return defs.APIPathSourceTypeRTMPConn
|
||||
}(),
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
|
||||
@@ -86,11 +86,11 @@ func (c *conn) initialize() {
|
||||
RunOnDisconnect: c.runOnDisconnect,
|
||||
RTSPAddress: c.rtspAddress,
|
||||
Desc: defs.APIPathReader{
|
||||
Type: func() string {
|
||||
Type: func() defs.APIPathReaderType {
|
||||
if c.isTLS {
|
||||
return "rtspsConn"
|
||||
return defs.APIPathReaderTypeRTSPSConn
|
||||
}
|
||||
return "rtspConn"
|
||||
return defs.APIPathReaderTypeRTSPConn
|
||||
}(),
|
||||
ID: c.uuid.String(),
|
||||
},
|
||||
|
||||
@@ -380,11 +380,11 @@ func (s *session) onPause(_ *gortsplib.ServerHandlerOnPauseCtx) (*base.Response,
|
||||
// APIReaderDescribe implements reader.
|
||||
func (s *session) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: func() string {
|
||||
Type: func() defs.APIPathReaderType {
|
||||
if s.isTLS {
|
||||
return "rtspsSession"
|
||||
return defs.APIPathReaderTypeRTSPSSession
|
||||
}
|
||||
return "rtspSession"
|
||||
return defs.APIPathReaderTypeRTSPSession
|
||||
}(),
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
@@ -393,11 +393,11 @@ func (s *session) APIReaderDescribe() *defs.APIPathReader {
|
||||
// APISourceDescribe implements source.
|
||||
func (s *session) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: func() string {
|
||||
Type: func() defs.APIPathSourceType {
|
||||
if s.isTLS {
|
||||
return "rtspsSession"
|
||||
return defs.APIPathSourceTypeRTSPSSession
|
||||
}
|
||||
return "rtspSession"
|
||||
return defs.APIPathSourceTypeRTSPSession
|
||||
}(),
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ func (c *conn) runRead(streamID *streamID) error {
|
||||
// APIReaderDescribe implements reader.
|
||||
func (c *conn) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "srtConn",
|
||||
Type: defs.APIPathReaderTypeSRTConn,
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
}
|
||||
@@ -355,7 +355,7 @@ func (c *conn) APIReaderDescribe() *defs.APIPathReader {
|
||||
// APISourceDescribe implements source.
|
||||
func (c *conn) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "srtConn",
|
||||
Type: defs.APIPathSourceTypeSRTConn,
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func mergePathAndQuery(path string, rawQuery string) string {
|
||||
|
||||
func writeError(ctx *gin.Context, statusCode int, err error) {
|
||||
ctx.JSON(statusCode, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: err.Error(),
|
||||
})
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func (s *httpServer) checkAuthOutsideSession(ctx *gin.Context, pathName string,
|
||||
if terr.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return false
|
||||
@@ -208,7 +208,7 @@ func (s *httpServer) onWHIPPost(ctx *gin.Context, pathName string, publish bool)
|
||||
if terr.AskCredentials {
|
||||
ctx.Header("WWW-Authenticate", `Basic realm="mediamtx"`)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
@@ -220,7 +220,7 @@ func (s *httpServer) onWHIPPost(ctx *gin.Context, pathName string, publish bool)
|
||||
<-time.After(auth.PauseAfterError)
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, &defs.APIError{
|
||||
Status: "error",
|
||||
Status: defs.APIErrorStatusError,
|
||||
Error: "authentication error",
|
||||
})
|
||||
return
|
||||
@@ -288,7 +288,7 @@ func (s *httpServer) onWHIPPatch(ctx *gin.Context, pathName string, rawSecret st
|
||||
}
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusNoContent, &defs.APIOK{
|
||||
Status: "ok",
|
||||
Status: defs.APIOKStatusOK,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ func (s *httpServer) onWHIPDelete(ctx *gin.Context, pathName string, rawSecret s
|
||||
}
|
||||
|
||||
ctx.AbortWithStatusJSON(http.StatusOK, &defs.APIOK{
|
||||
Status: "ok",
|
||||
Status: defs.APIOKStatusOK,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@ func (s *session) addCandidates(
|
||||
// APIReaderDescribe implements reader.
|
||||
func (s *session) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "webRTCSession",
|
||||
Type: defs.APIPathReaderTypeWebRTCSession,
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
}
|
||||
@@ -459,7 +459,7 @@ func (s *session) APIReaderDescribe() *defs.APIPathReader {
|
||||
// APISourceDescribe implements source.
|
||||
func (s *session) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "webRTCSession",
|
||||
Type: defs.APIPathSourceTypeWebRTCSession,
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "hlsSource",
|
||||
Type: defs.APIPathSourceTypeHLSSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ func (s *Source) runReader(nc net.Conn) error {
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "mpegtsSource",
|
||||
Type: defs.APIPathSourceTypeMPEGTSSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func (r *secondaryReader) Close() {
|
||||
// APIReaderDescribe implements reader.
|
||||
func (*secondaryReader) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "rpiCameraSecondary",
|
||||
Type: defs.APIPathReaderTypeRPICameraSecondary,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
@@ -361,7 +361,7 @@ func (s *Source) waitForPrimary(
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rpiCameraSource",
|
||||
Type: defs.APIPathSourceTypeRPICameraSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ func (s *Source) runReader(conn *gortmplib.Client) error {
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rtmpSource",
|
||||
Type: defs.APIPathSourceTypeRTMPSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ func (s *Source) runReader(desc *description.Session, nc net.Conn) error {
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rtpSource",
|
||||
Type: defs.APIPathSourceTypeRTPSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ func (s *Source) runInner(c *gortsplib.Client, u *base.URL, pathConf *conf.Path)
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rtspSource",
|
||||
Type: defs.APIPathSourceTypeRTSPSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ func (s *Source) runReader(sconn srt.Conn) error {
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "srtSource",
|
||||
Type: defs.APIPathSourceTypeSRTSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "webRTCSource",
|
||||
Type: defs.APIPathSourceTypeWebRTCSource,
|
||||
ID: "",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user