api: improve openapi definition (#5380)
add uint64, uint, uuid, move WebRTCICEServer into dedicated schema
This commit is contained in:
+96
-87
@@ -91,7 +91,7 @@ components:
|
||||
format: int64
|
||||
udpReadBufferSize:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
runOnConnect:
|
||||
type: string
|
||||
runOnConnectRestart:
|
||||
@@ -336,16 +336,7 @@ components:
|
||||
webrtcICEServers2:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
clientOnly:
|
||||
type: boolean
|
||||
$ref: '#/components/schemas/WebRTCICEServer'
|
||||
webrtcHandshakeTimeout:
|
||||
type: string
|
||||
webrtcTrackGatherTimeout:
|
||||
@@ -429,15 +420,15 @@ components:
|
||||
# Raspberry Pi Camera source
|
||||
rpiCameraCamID:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraSecondary:
|
||||
type: boolean
|
||||
rpiCameraWidth:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraHeight:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraHFlip:
|
||||
type: boolean
|
||||
rpiCameraVFlip:
|
||||
@@ -469,7 +460,7 @@ components:
|
||||
type: string
|
||||
rpiCameraShutter:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraMetering:
|
||||
type: string
|
||||
rpiCameraGain:
|
||||
@@ -502,7 +493,7 @@ components:
|
||||
type: string
|
||||
rpiCameraFlickerPeriod:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraTextOverlayEnable:
|
||||
type: boolean
|
||||
rpiCameraTextOverlay:
|
||||
@@ -511,10 +502,10 @@ components:
|
||||
type: string
|
||||
rpiCameraIDRPeriod:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraBitrate:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rpiCameraHardwareH264Profile:
|
||||
type: string
|
||||
rpiCameraHardwareH264Level:
|
||||
@@ -525,7 +516,7 @@ components:
|
||||
type: string
|
||||
rpiCameraMJPEGQuality:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
|
||||
# Hooks
|
||||
runOnInit:
|
||||
@@ -594,10 +585,10 @@ components:
|
||||
type: string
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
readers:
|
||||
type: array
|
||||
items:
|
||||
@@ -666,7 +657,7 @@ components:
|
||||
type: string
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
|
||||
HLSMuxerList:
|
||||
type: object
|
||||
@@ -717,6 +708,7 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
created:
|
||||
type: string
|
||||
remoteAddr:
|
||||
@@ -730,10 +722,10 @@ components:
|
||||
type: string
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
|
||||
RTMPConnList:
|
||||
type: object
|
||||
@@ -754,18 +746,20 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
created:
|
||||
type: string
|
||||
remoteAddr:
|
||||
type: string
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
session:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
tunnel:
|
||||
type: string
|
||||
@@ -789,6 +783,7 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
created:
|
||||
type: string
|
||||
remoteAddr:
|
||||
@@ -808,34 +803,34 @@ components:
|
||||
nullable: true
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsLost:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsInError:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsJitter:
|
||||
type: number
|
||||
format: double
|
||||
rtcpPacketsReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtcpPacketsSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtcpPacketsInError:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
|
||||
RTSPSessionList:
|
||||
type: object
|
||||
@@ -856,6 +851,7 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
created:
|
||||
type: string
|
||||
remoteAddr:
|
||||
@@ -869,121 +865,121 @@ components:
|
||||
type: string
|
||||
packetsSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of sent DATA packets, including retransmitted packets
|
||||
packetsReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of received DATA packets, including retransmitted packets
|
||||
packetsReceivedBelated:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
packetsSentUnique:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of unique DATA packets sent by the SRT sender
|
||||
packetsReceivedUnique:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: 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.
|
||||
packetsSendLoss:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: 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.
|
||||
packetsReceivedLoss:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||
packetsRetrans:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of retransmitted packets sent by the SRT sender
|
||||
packetsReceivedRetrans:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of retransmitted packets registered at the receiver side
|
||||
packetsSentACK:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of sent ACK (Acknowledgement) control packets
|
||||
packetsReceivedACK:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of received ACK (Acknowledgement) control packets
|
||||
packetsSentNAK:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of sent NAK (Negative Acknowledgement) control packets
|
||||
packetsReceivedNAK:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of received NAK (Negative Acknowledgement) control packets
|
||||
packetsSentKM:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of sent KM (Key Material) control packets
|
||||
packetsReceivedKM:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of received KM (Key Material) control packets
|
||||
usSndDuration:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: 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
|
||||
packetsSendDrop:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
|
||||
packetsReceivedDrop:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of dropped by the SRT receiver and, as a result, not delivered to the upstream application DATA packets
|
||||
packetsReceivedUndecrypt:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The total number of packets that failed to be decrypted at the receiver side
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsReceived, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceivedBelated:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
bytesSentUnique:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceivedUnique:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsReceivedUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceivedLoss:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: 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
|
||||
bytesRetrans:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceivedRetrans:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsReceivedRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesSendDrop:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsSendDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceivedDrop:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsReceivedDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
bytesReceivedUndecrypt:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Same as packetsReceivedUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
usPacketsSendPeriod:
|
||||
type: number
|
||||
@@ -991,11 +987,11 @@ components:
|
||||
description: Current minimum time interval between which consecutive packets are sent, in microseconds
|
||||
packetsFlowWindow:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The maximum number of packets that can be "in flight"
|
||||
packetsFlightSize:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The number of packets in flight
|
||||
msRTT:
|
||||
type: number
|
||||
@@ -1015,11 +1011,11 @@ components:
|
||||
description: Estimated capacity of the network link, in Mbps
|
||||
bytesAvailSendBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The available space in the sender's buffer, in bytes
|
||||
bytesAvailReceiveBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The available space in the receiver's buffer, in bytes
|
||||
mbpsMaxBW:
|
||||
type: number
|
||||
@@ -1027,47 +1023,47 @@ components:
|
||||
description: Transmission bandwidth limit, in Mbps
|
||||
byteMSS:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Maximum Segment Size (MSS), in bytes
|
||||
packetsSendBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The number of packets in the sender's buffer that are already scheduled for sending or even possibly sent, but not yet acknowledged
|
||||
bytesSendBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Instantaneous (current) value of packetsSndBuf, but expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
msSendBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
|
||||
msSendTsbPdDelay:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Timestamp-based Packet Delivery Delay value of the peer
|
||||
packetsReceiveBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The number of acknowledged packets in receiver's buffer
|
||||
bytesReceiveBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Instantaneous (current) value of packetsRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
msReceiveBuf:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: The timespan (msec) of acknowledged packets in the receiver's buffer
|
||||
msReceiveTsbPdDelay:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
|
||||
packetsReorderTolerance:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Instant value of the packet reorder tolerance
|
||||
packetsReceivedAvgBelatedTime:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
description: Accumulated difference between the current time and the time-to-play of a packet that is received late
|
||||
packetsSendLossRate:
|
||||
type: number
|
||||
@@ -1092,11 +1088,24 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/SRTConn'
|
||||
|
||||
WebRTCICEServer:
|
||||
type: object
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
clientOnly:
|
||||
type: boolean
|
||||
|
||||
WebRTCSession:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
created:
|
||||
type: string
|
||||
remoteAddr:
|
||||
@@ -1116,28 +1125,28 @@ components:
|
||||
type: string
|
||||
bytesReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
bytesSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsLost:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtpPacketsJitter:
|
||||
type: number
|
||||
format: double
|
||||
rtcpPacketsReceived:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
rtcpPacketsSent:
|
||||
type: integer
|
||||
format: int64
|
||||
format: uint64
|
||||
|
||||
WebRTCSessionList:
|
||||
type: object
|
||||
|
||||
+2
-2
@@ -54,10 +54,10 @@ func recordingsOfPath(
|
||||
|
||||
segments, _ := recordstore.FindSegments(pathConf, pathName, nil, nil)
|
||||
|
||||
ret.Segments = make([]*defs.APIRecordingSegment, len(segments))
|
||||
ret.Segments = make([]defs.APIRecordingSegment, len(segments))
|
||||
|
||||
for i, seg := range segments {
|
||||
ret.Segments[i] = &defs.APIRecordingSegment{
|
||||
ret.Segments[i] = defs.APIRecordingSegment{
|
||||
Start: seg.Start,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ func (a *API) onConfigPathsList(ctx *gin.Context) {
|
||||
a.mutex.RUnlock()
|
||||
|
||||
data := &defs.APIPathConfList{
|
||||
Items: make([]*conf.Path, len(c.Paths)),
|
||||
Items: make([]conf.Path, len(c.Paths)),
|
||||
}
|
||||
|
||||
for i, key := range sortedKeys(c.Paths) {
|
||||
data.Items[i] = c.Paths[key]
|
||||
data.Items[i] = *c.Paths[key]
|
||||
}
|
||||
|
||||
data.ItemCount = len(data.Items)
|
||||
|
||||
@@ -17,9 +17,9 @@ type testHLSServer struct {
|
||||
}
|
||||
|
||||
func (s *testHLSServer) APIMuxersList() (*defs.APIHLSMuxerList, error) {
|
||||
items := make([]*defs.APIHLSMuxer, 0, len(s.muxers))
|
||||
items := make([]defs.APIHLSMuxer, 0, len(s.muxers))
|
||||
for _, muxer := range s.muxers {
|
||||
items = append(items, muxer)
|
||||
items = append(items, *muxer)
|
||||
}
|
||||
return &defs.APIHLSMuxerList{Items: items}, nil
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ type testPathManager struct {
|
||||
}
|
||||
|
||||
func (m *testPathManager) APIPathsList() (*defs.APIPathList, error) {
|
||||
items := make([]*defs.APIPath, 0, len(m.paths))
|
||||
items := make([]defs.APIPath, 0, len(m.paths))
|
||||
for _, path := range m.paths {
|
||||
items = append(items, path)
|
||||
items = append(items, *path)
|
||||
}
|
||||
return &defs.APIPathList{Items: items}, nil
|
||||
}
|
||||
@@ -38,13 +38,13 @@ func TestPathsList(t *testing.T) {
|
||||
"test1": {
|
||||
Name: "test1",
|
||||
ConfName: "test1",
|
||||
Source: &defs.APIPathSourceOrReader{Type: "publisher", ID: "pub1"},
|
||||
Source: &defs.APIPathSource{Type: "publisher", ID: "pub1"},
|
||||
Ready: true,
|
||||
ReadyTime: &now,
|
||||
Tracks: []string{"H264", "Opus"},
|
||||
BytesReceived: 1000,
|
||||
BytesSent: 2000,
|
||||
Readers: []defs.APIPathSourceOrReader{
|
||||
Readers: []defs.APIPathReader{
|
||||
{Type: "reader", ID: "reader1"},
|
||||
},
|
||||
},
|
||||
@@ -55,7 +55,7 @@ func TestPathsList(t *testing.T) {
|
||||
Tracks: []string{},
|
||||
BytesReceived: 500,
|
||||
BytesSent: 100,
|
||||
Readers: []defs.APIPathSourceOrReader{},
|
||||
Readers: []defs.APIPathReader{},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -91,13 +91,13 @@ func TestPathsGet(t *testing.T) {
|
||||
"mystream": {
|
||||
Name: "mystream",
|
||||
ConfName: "mystream",
|
||||
Source: &defs.APIPathSourceOrReader{Type: "rtspSession", ID: "session123"},
|
||||
Source: &defs.APIPathSource{Type: "rtspSession", ID: "session123"},
|
||||
Ready: true,
|
||||
ReadyTime: &now,
|
||||
Tracks: []string{"H264", "Opus"},
|
||||
BytesReceived: 123456,
|
||||
BytesSent: 789012,
|
||||
Readers: []defs.APIPathSourceOrReader{
|
||||
Readers: []defs.APIPathReader{
|
||||
{Type: "hlsMuxer", ID: "muxer1"},
|
||||
{Type: "webRTCSession", ID: "session456"},
|
||||
},
|
||||
|
||||
@@ -30,11 +30,11 @@ func (a *API) onRecordingsList(ctx *gin.Context) {
|
||||
}
|
||||
data.PageCount = pageCount
|
||||
|
||||
data.Items = make([]*defs.APIRecording, len(pathNames))
|
||||
data.Items = make([]defs.APIRecording, len(pathNames))
|
||||
|
||||
for i, pathName := range pathNames {
|
||||
pathConf, _, _ := conf.FindPathConf(c.Paths, pathName)
|
||||
data.Items[i] = recordingsOfPath(pathConf, pathName)
|
||||
data.Items[i] = *recordingsOfPath(pathConf, pathName)
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, data)
|
||||
|
||||
@@ -19,9 +19,9 @@ type testRTMPServer struct {
|
||||
}
|
||||
|
||||
func (s *testRTMPServer) APIConnsList() (*defs.APIRTMPConnList, error) {
|
||||
items := make([]*defs.APIRTMPConn, 0, len(s.conns))
|
||||
items := make([]defs.APIRTMPConn, 0, len(s.conns))
|
||||
for _, conn := range s.conns {
|
||||
items = append(items, conn)
|
||||
items = append(items, *conn)
|
||||
}
|
||||
return &defs.APIRTMPConnList{Items: items}, nil
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ type testRTSPServer struct {
|
||||
}
|
||||
|
||||
func (s *testRTSPServer) APIConnsList() (*defs.APIRTSPConnsList, error) {
|
||||
items := make([]*defs.APIRTSPConn, 0, len(s.conns))
|
||||
items := make([]defs.APIRTSPConn, 0, len(s.conns))
|
||||
for _, conn := range s.conns {
|
||||
items = append(items, conn)
|
||||
items = append(items, *conn)
|
||||
}
|
||||
return &defs.APIRTSPConnsList{Items: items}, nil
|
||||
}
|
||||
@@ -37,9 +37,9 @@ func (s *testRTSPServer) APIConnsGet(id uuid.UUID) (*defs.APIRTSPConn, error) {
|
||||
}
|
||||
|
||||
func (s *testRTSPServer) APISessionsList() (*defs.APIRTSPSessionList, error) {
|
||||
items := make([]*defs.APIRTSPSession, 0, len(s.sessions))
|
||||
items := make([]defs.APIRTSPSession, 0, len(s.sessions))
|
||||
for _, session := range s.sessions {
|
||||
items = append(items, session)
|
||||
items = append(items, *session)
|
||||
}
|
||||
return &defs.APIRTSPSessionList{Items: items}, nil
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ type testSRTServer struct {
|
||||
}
|
||||
|
||||
func (s *testSRTServer) APIConnsList() (*defs.APISRTConnList, error) {
|
||||
items := make([]*defs.APISRTConn, 0, len(s.conns))
|
||||
items := make([]defs.APISRTConn, 0, len(s.conns))
|
||||
for _, conn := range s.conns {
|
||||
items = append(items, conn)
|
||||
items = append(items, *conn)
|
||||
}
|
||||
return &defs.APISRTConnList{Items: items}, nil
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ type testWebRTCServer struct {
|
||||
}
|
||||
|
||||
func (s *testWebRTCServer) APISessionsList() (*defs.APIWebRTCSessionList, error) {
|
||||
items := make([]*defs.APIWebRTCSession, 0, len(s.sessions))
|
||||
items := make([]defs.APIWebRTCSession, 0, len(s.sessions))
|
||||
for _, session := range s.sessions {
|
||||
items = append(items, session)
|
||||
items = append(items, *session)
|
||||
}
|
||||
return &defs.APIWebRTCSessionList{Items: items}, nil
|
||||
}
|
||||
|
||||
@@ -550,12 +550,12 @@ func (pa *path) doAPIPathsGet(req pathAPIPathsGetReq) {
|
||||
data: &defs.APIPath{
|
||||
Name: pa.name,
|
||||
ConfName: pa.conf.Name,
|
||||
Source: func() *defs.APIPathSourceOrReader {
|
||||
Source: func() *defs.APIPathSource {
|
||||
if pa.source == nil {
|
||||
return nil
|
||||
}
|
||||
v := pa.source.APISourceDescribe()
|
||||
return &v
|
||||
return v
|
||||
}(),
|
||||
Ready: pa.isReady(),
|
||||
ReadyTime: func() *time.Time {
|
||||
@@ -583,11 +583,11 @@ func (pa *path) doAPIPathsGet(req pathAPIPathsGetReq) {
|
||||
}
|
||||
return pa.stream.BytesSent()
|
||||
}(),
|
||||
Readers: func() []defs.APIPathSourceOrReader {
|
||||
ret := make([]defs.APIPathSourceOrReader, len(pa.readers))
|
||||
Readers: func() []defs.APIPathReader {
|
||||
ret := make([]defs.APIPathReader, len(pa.readers))
|
||||
i := 0
|
||||
for r := range pa.readers {
|
||||
ret[i] = r.APIReaderDescribe()
|
||||
ret[i] = *r.APIReaderDescribe()
|
||||
i++
|
||||
}
|
||||
return ret
|
||||
@@ -713,7 +713,7 @@ func (pa *path) setReady(desc *description.Session, useRTPPackets bool, replaceN
|
||||
ExternalCmdPool: pa.externalCmdPool,
|
||||
Conf: pa.conf,
|
||||
ExternalCmdEnv: pa.ExternalCmdEnv(),
|
||||
Desc: pa.source.APISourceDescribe(),
|
||||
Desc: *pa.source.APISourceDescribe(),
|
||||
Query: pa.publisherQuery,
|
||||
})
|
||||
|
||||
|
||||
@@ -594,13 +594,13 @@ func (pm *pathManager) APIPathsList() (*defs.APIPathList, error) {
|
||||
res := <-req.res
|
||||
|
||||
res.data = &defs.APIPathList{
|
||||
Items: []*defs.APIPath{},
|
||||
Items: []defs.APIPath{},
|
||||
}
|
||||
|
||||
for _, pa := range res.paths {
|
||||
item, err := pa.APIPathsGet(pathAPIPathsGetReq{})
|
||||
if err == nil {
|
||||
res.data.Items = append(res.data.Items, item)
|
||||
res.data.Items = append(res.data.Items, *item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ func (*sourceRedirect) Log(logger.Level, string, ...any) {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements source.
|
||||
func (*sourceRedirect) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*sourceRedirect) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "redirect",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
+46
-40
@@ -69,35 +69,41 @@ type APIInfo struct {
|
||||
|
||||
// APIPathConfList is a list of path configurations.
|
||||
type APIPathConfList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*conf.Path `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []conf.Path `json:"items"`
|
||||
}
|
||||
|
||||
// APIPathSourceOrReader is a source or a reader.
|
||||
type APIPathSourceOrReader struct {
|
||||
// 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"`
|
||||
Source *APIPathSourceOrReader `json:"source"`
|
||||
Ready bool `json:"ready"`
|
||||
ReadyTime *time.Time `json:"readyTime"`
|
||||
Tracks []string `json:"tracks"`
|
||||
BytesReceived uint64 `json:"bytesReceived"`
|
||||
BytesSent uint64 `json:"bytesSent"`
|
||||
Readers []APIPathSourceOrReader `json:"readers"`
|
||||
Name string `json:"name"`
|
||||
ConfName string `json:"confName"`
|
||||
Source *APIPathSource `json:"source"`
|
||||
Ready bool `json:"ready"`
|
||||
ReadyTime *time.Time `json:"readyTime"`
|
||||
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"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIPath `json:"items"`
|
||||
}
|
||||
|
||||
// APIHLSMuxer is an HLS muxer.
|
||||
@@ -110,9 +116,9 @@ type APIHLSMuxer struct {
|
||||
|
||||
// APIHLSMuxerList is a list of HLS muxers.
|
||||
type APIHLSMuxerList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*APIHLSMuxer `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIHLSMuxer `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTMPConnState is the state of a RTMP connection.
|
||||
@@ -139,9 +145,9 @@ type APIRTMPConn struct {
|
||||
|
||||
// APIRTMPConnList is a list of RTMP connections.
|
||||
type APIRTMPConnList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*APIRTMPConn `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTMPConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTSPConn is a RTSP connection.
|
||||
@@ -157,9 +163,9 @@ type APIRTSPConn struct {
|
||||
|
||||
// APIRTSPConnsList is a list of RTSP connections.
|
||||
type APIRTSPConnsList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*APIRTSPConn `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTSPConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIRTSPSessionState is the state of a RTSP session.
|
||||
@@ -196,9 +202,9 @@ type APIRTSPSession struct {
|
||||
|
||||
// APIRTSPSessionList is a list of RTSP sessions.
|
||||
type APIRTSPSessionList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*APIRTSPSession `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRTSPSession `json:"items"`
|
||||
}
|
||||
|
||||
// APISRTConnState is the state of a SRT connection.
|
||||
@@ -344,9 +350,9 @@ type APISRTConn struct {
|
||||
|
||||
// APISRTConnList is a list of SRT connections.
|
||||
type APISRTConnList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*APISRTConn `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APISRTConn `json:"items"`
|
||||
}
|
||||
|
||||
// APIWebRTCSessionState is the state of a WebRTC connection.
|
||||
@@ -381,9 +387,9 @@ type APIWebRTCSession struct {
|
||||
|
||||
// APIWebRTCSessionList is a list of WebRTC sessions.
|
||||
type APIWebRTCSessionList struct {
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []*APIWebRTCSession `json:"items"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIWebRTCSession `json:"items"`
|
||||
}
|
||||
|
||||
// APIRecordingSegment is a recording segment.
|
||||
@@ -393,13 +399,13 @@ type APIRecordingSegment struct {
|
||||
|
||||
// APIRecording is a recording.
|
||||
type APIRecording struct {
|
||||
Name string `json:"name"`
|
||||
Segments []*APIRecordingSegment `json:"segments"`
|
||||
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"`
|
||||
ItemCount int `json:"itemCount"`
|
||||
PageCount int `json:"pageCount"`
|
||||
Items []APIRecording `json:"items"`
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ package defs
|
||||
// Reader is an entity that can read a stream.
|
||||
type Reader interface {
|
||||
Close()
|
||||
APIReaderDescribe() APIPathSourceOrReader
|
||||
APIReaderDescribe() *APIPathReader
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// - core.sourceRedirect
|
||||
type Source interface {
|
||||
logger.Writer
|
||||
APISourceDescribe() APIPathSourceOrReader
|
||||
APISourceDescribe() *APIPathSource
|
||||
}
|
||||
|
||||
// FormatsToCodecs returns the name of codecs of given formats.
|
||||
|
||||
@@ -16,7 +16,7 @@ type OnConnectParams struct {
|
||||
RunOnConnectRestart bool
|
||||
RunOnDisconnect string
|
||||
RTSPAddress string
|
||||
Desc defs.APIPathSourceOrReader
|
||||
Desc defs.APIPathReader
|
||||
}
|
||||
|
||||
// OnConnect is the OnConnect hook.
|
||||
|
||||
@@ -13,7 +13,7 @@ type OnReadParams struct {
|
||||
ExternalCmdPool *externalcmd.Pool
|
||||
Conf *conf.Path
|
||||
ExternalCmdEnv externalcmd.Environment
|
||||
Reader defs.APIPathSourceOrReader
|
||||
Reader defs.APIPathReader
|
||||
Query string
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ type OnReadyParams struct {
|
||||
ExternalCmdPool *externalcmd.Pool
|
||||
Conf *conf.Path
|
||||
ExternalCmdEnv externalcmd.Environment
|
||||
Desc defs.APIPathSourceOrReader
|
||||
Desc defs.APIPathSource
|
||||
Query string
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
|
||||
return &defs.APIPathList{
|
||||
ItemCount: 1,
|
||||
PageCount: 1,
|
||||
Items: []*defs.APIPath{{
|
||||
Items: []defs.APIPath{{
|
||||
Name: "mypath",
|
||||
ConfName: "mypathconf",
|
||||
Source: &defs.APIPathSourceOrReader{
|
||||
Source: &defs.APIPathSource{
|
||||
Type: "testing",
|
||||
ID: "123324354",
|
||||
},
|
||||
@@ -38,7 +38,7 @@ func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
|
||||
Tracks: []string{"H264", "H265"},
|
||||
BytesReceived: 123,
|
||||
BytesSent: 456,
|
||||
Readers: []defs.APIPathSourceOrReader{
|
||||
Readers: []defs.APIPathReader{
|
||||
{
|
||||
Type: "testing",
|
||||
ID: "345234423",
|
||||
@@ -58,7 +58,7 @@ func (dummyHLSServer) APIMuxersList() (*defs.APIHLSMuxerList, error) {
|
||||
return &defs.APIHLSMuxerList{
|
||||
ItemCount: 1,
|
||||
PageCount: 1,
|
||||
Items: []*defs.APIHLSMuxer{{
|
||||
Items: []defs.APIHLSMuxer{{
|
||||
Path: "mypath",
|
||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||
LastRequest: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||
@@ -77,7 +77,7 @@ func (dummyRTSPServer) APIConnsList() (*defs.APIRTSPConnsList, error) {
|
||||
return &defs.APIRTSPConnsList{
|
||||
ItemCount: 1,
|
||||
PageCount: 1,
|
||||
Items: []*defs.APIRTSPConn{{
|
||||
Items: []defs.APIRTSPConn{{
|
||||
ID: uuid.MustParse("18294761-f9d1-4ea9-9a35-fe265b62eb41"),
|
||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||
RemoteAddr: "124.5.5.5:34542",
|
||||
@@ -96,7 +96,7 @@ func (dummyRTSPServer) APISessionsList() (*defs.APIRTSPSessionList, error) {
|
||||
return &defs.APIRTSPSessionList{
|
||||
ItemCount: 1,
|
||||
PageCount: 1,
|
||||
Items: []*defs.APIRTSPSession{{
|
||||
Items: []defs.APIRTSPSession{{
|
||||
ID: uuid.MustParse("124b22ce-9c34-4387-b045-44caf98049f7"),
|
||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||
RemoteAddr: "124.5.5.5:34542",
|
||||
@@ -132,7 +132,7 @@ func (dummyRTMPServer) APIConnsList() (*defs.APIRTMPConnList, error) {
|
||||
return &defs.APIRTMPConnList{
|
||||
ItemCount: 1,
|
||||
PageCount: 1,
|
||||
Items: []*defs.APIRTMPConn{{
|
||||
Items: []defs.APIRTMPConn{{
|
||||
ID: uuid.MustParse("9a07afe4-fc07-4c9b-be6e-6255720c36d0"),
|
||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||
RemoteAddr: "3.3.3.3:5678",
|
||||
@@ -159,7 +159,7 @@ func (dummyWebRTCServer) APISessionsList() (*defs.APIWebRTCSessionList, error) {
|
||||
return &defs.APIWebRTCSessionList{
|
||||
ItemCount: 1,
|
||||
PageCount: 1,
|
||||
Items: []*defs.APIWebRTCSession{{
|
||||
Items: []defs.APIWebRTCSession{{
|
||||
ID: uuid.MustParse("f47ac10b-58cc-4372-a567-0e02b2c3d479"),
|
||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||
RemoteAddr: "127.0.0.1:3455",
|
||||
|
||||
@@ -245,8 +245,8 @@ func (m *muxer) getInstance() *muxerInstance {
|
||||
}
|
||||
|
||||
// APIReaderDescribe implements reader.
|
||||
func (m *muxer) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (m *muxer) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "hlsMuxer",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -217,11 +217,11 @@ outer:
|
||||
|
||||
case req := <-s.chAPIMuxerList:
|
||||
data := &defs.APIHLSMuxerList{
|
||||
Items: []*defs.APIHLSMuxer{},
|
||||
Items: []defs.APIHLSMuxer{},
|
||||
}
|
||||
|
||||
for _, muxer := range s.muxers {
|
||||
data.Items = append(data.Items, muxer.apiItem())
|
||||
data.Items = append(data.Items, *muxer.apiItem())
|
||||
}
|
||||
|
||||
sort.Slice(data.Items, func(i, j int) bool {
|
||||
|
||||
@@ -89,7 +89,7 @@ func (c *conn) run() { //nolint:dupl
|
||||
RunOnConnectRestart: c.runOnConnectRestart,
|
||||
RunOnDisconnect: c.runOnDisconnect,
|
||||
RTSPAddress: c.rtspAddress,
|
||||
Desc: c.APIReaderDescribe(),
|
||||
Desc: *c.APIReaderDescribe(),
|
||||
})
|
||||
defer onDisconnectHook()
|
||||
|
||||
@@ -198,7 +198,7 @@ func (c *conn) runRead() error {
|
||||
ExternalCmdPool: c.externalCmdPool,
|
||||
Conf: path.SafeConf(),
|
||||
ExternalCmdEnv: path.ExternalCmdEnv(),
|
||||
Reader: c.APISourceDescribe(),
|
||||
Reader: *c.APIReaderDescribe(),
|
||||
Query: c.rconn.URL.RawQuery,
|
||||
})
|
||||
defer onUnreadHook()
|
||||
@@ -285,8 +285,8 @@ func (c *conn) runPublish() error {
|
||||
}
|
||||
|
||||
// APIReaderDescribe implements reader.
|
||||
func (c *conn) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (c *conn) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: func() string {
|
||||
if c.isTLS {
|
||||
return "rtmpsConn"
|
||||
@@ -298,8 +298,16 @@ func (c *conn) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements source.
|
||||
func (c *conn) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return c.APIReaderDescribe()
|
||||
func (c *conn) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: func() string {
|
||||
if c.isTLS {
|
||||
return "rtmpsConn"
|
||||
}
|
||||
return "rtmpConn"
|
||||
}(),
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *conn) apiItem() *defs.APIRTMPConn {
|
||||
|
||||
@@ -227,11 +227,11 @@ outer:
|
||||
|
||||
case req := <-s.chAPIConnsList:
|
||||
data := &defs.APIRTMPConnList{
|
||||
Items: []*defs.APIRTMPConn{},
|
||||
Items: []defs.APIRTMPConn{},
|
||||
}
|
||||
|
||||
for c := range s.conns {
|
||||
data.Items = append(data.Items, c.apiItem())
|
||||
data.Items = append(data.Items, *c.apiItem())
|
||||
}
|
||||
|
||||
sort.Slice(data.Items, func(i, j int) bool {
|
||||
|
||||
@@ -78,16 +78,6 @@ func (c *conn) initialize() {
|
||||
|
||||
c.Log(logger.Info, "opened")
|
||||
|
||||
desc := defs.APIPathSourceOrReader{
|
||||
Type: func() string {
|
||||
if c.isTLS {
|
||||
return "rtspsConn"
|
||||
}
|
||||
return "rtspConn"
|
||||
}(),
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
|
||||
c.onDisconnectHook = hooks.OnConnect(hooks.OnConnectParams{
|
||||
Logger: c,
|
||||
ExternalCmdPool: c.externalCmdPool,
|
||||
@@ -95,7 +85,15 @@ func (c *conn) initialize() {
|
||||
RunOnConnectRestart: c.runOnConnectRestart,
|
||||
RunOnDisconnect: c.runOnDisconnect,
|
||||
RTSPAddress: c.rtspAddress,
|
||||
Desc: desc,
|
||||
Desc: defs.APIPathReader{
|
||||
Type: func() string {
|
||||
if c.isTLS {
|
||||
return "rtspsConn"
|
||||
}
|
||||
return "rtspConn"
|
||||
}(),
|
||||
ID: c.uuid.String(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -407,11 +407,11 @@ func (s *Server) APIConnsList() (*defs.APIRTSPConnsList, error) {
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
data := &defs.APIRTSPConnsList{
|
||||
Items: []*defs.APIRTSPConn{},
|
||||
Items: []defs.APIRTSPConn{},
|
||||
}
|
||||
|
||||
for _, c := range s.conns {
|
||||
data.Items = append(data.Items, c.apiItem())
|
||||
data.Items = append(data.Items, *c.apiItem())
|
||||
}
|
||||
|
||||
sort.Slice(data.Items, func(i, j int) bool {
|
||||
@@ -452,11 +452,11 @@ func (s *Server) APISessionsList() (*defs.APIRTSPSessionList, error) {
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
data := &defs.APIRTSPSessionList{
|
||||
Items: []*defs.APIRTSPSession{},
|
||||
Items: []defs.APIRTSPSession{},
|
||||
}
|
||||
|
||||
for _, s := range s.sessions {
|
||||
data.Items = append(data.Items, s.apiItem())
|
||||
data.Items = append(data.Items, *s.apiItem())
|
||||
}
|
||||
|
||||
sort.Slice(data.Items, func(i, j int) bool {
|
||||
|
||||
@@ -297,7 +297,7 @@ func (s *session) onPlay(_ *gortsplib.ServerHandlerOnPlayCtx) (*base.Response, e
|
||||
ExternalCmdPool: s.externalCmdPool,
|
||||
Conf: s.path.SafeConf(),
|
||||
ExternalCmdEnv: s.path.ExternalCmdEnv(),
|
||||
Reader: s.APIReaderDescribe(),
|
||||
Reader: *s.APIReaderDescribe(),
|
||||
Query: s.rsession.Query(),
|
||||
})
|
||||
}
|
||||
@@ -360,8 +360,8 @@ func (s *session) onPause(_ *gortsplib.ServerHandlerOnPauseCtx) (*base.Response,
|
||||
}
|
||||
|
||||
// APIReaderDescribe implements reader.
|
||||
func (s *session) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (s *session) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: func() string {
|
||||
if s.isTLS {
|
||||
return "rtspsSession"
|
||||
@@ -373,8 +373,16 @@ func (s *session) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements source.
|
||||
func (s *session) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return s.APIReaderDescribe()
|
||||
func (s *session) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: func() string {
|
||||
if s.isTLS {
|
||||
return "rtspsSession"
|
||||
}
|
||||
return "rtspSession"
|
||||
}(),
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// onPacketLost is called by rtspServer.
|
||||
|
||||
@@ -103,7 +103,7 @@ func (c *conn) run() { //nolint:dupl
|
||||
RunOnConnectRestart: c.runOnConnectRestart,
|
||||
RunOnDisconnect: c.runOnDisconnect,
|
||||
RTSPAddress: c.rtspAddress,
|
||||
Desc: c.APIReaderDescribe(),
|
||||
Desc: *c.APIReaderDescribe(),
|
||||
})
|
||||
defer onDisconnectHook()
|
||||
|
||||
@@ -317,7 +317,7 @@ func (c *conn) runRead(streamID *streamID) error {
|
||||
ExternalCmdPool: c.externalCmdPool,
|
||||
Conf: path.SafeConf(),
|
||||
ExternalCmdEnv: path.ExternalCmdEnv(),
|
||||
Reader: c.APIReaderDescribe(),
|
||||
Reader: *c.APIReaderDescribe(),
|
||||
Query: streamID.query,
|
||||
})
|
||||
defer onUnreadHook()
|
||||
@@ -338,16 +338,19 @@ func (c *conn) runRead(streamID *streamID) error {
|
||||
}
|
||||
|
||||
// APIReaderDescribe implements reader.
|
||||
func (c *conn) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (c *conn) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "srtConn",
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// APISourceDescribe implements source.
|
||||
func (c *conn) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return c.APIReaderDescribe()
|
||||
func (c *conn) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "srtConn",
|
||||
ID: c.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *conn) apiItem() *defs.APISRTConn {
|
||||
|
||||
@@ -195,11 +195,11 @@ outer:
|
||||
|
||||
case req := <-s.chAPIConnsList:
|
||||
data := &defs.APISRTConnList{
|
||||
Items: []*defs.APISRTConn{},
|
||||
Items: []defs.APISRTConn{},
|
||||
}
|
||||
|
||||
for c := range s.conns {
|
||||
data.Items = append(data.Items, c.apiItem())
|
||||
data.Items = append(data.Items, *c.apiItem())
|
||||
}
|
||||
|
||||
sort.Slice(data.Items, func(i, j int) bool {
|
||||
|
||||
@@ -399,11 +399,11 @@ outer:
|
||||
|
||||
case req := <-s.chAPISessionsList:
|
||||
data := &defs.APIWebRTCSessionList{
|
||||
Items: []*defs.APIWebRTCSession{},
|
||||
Items: []defs.APIWebRTCSession{},
|
||||
}
|
||||
|
||||
for sx := range s.sessions {
|
||||
data.Items = append(data.Items, sx.apiItem())
|
||||
data.Items = append(data.Items, *sx.apiItem())
|
||||
}
|
||||
|
||||
sort.Slice(data.Items, func(i, j int) bool {
|
||||
|
||||
@@ -373,7 +373,7 @@ func (s *session) runRead() (int, error) {
|
||||
ExternalCmdPool: s.externalCmdPool,
|
||||
Conf: path.SafeConf(),
|
||||
ExternalCmdEnv: path.ExternalCmdEnv(),
|
||||
Reader: s.APIReaderDescribe(),
|
||||
Reader: *s.APIReaderDescribe(),
|
||||
Query: s.req.httpRequest.URL.RawQuery,
|
||||
})
|
||||
defer onUnreadHook()
|
||||
@@ -443,16 +443,19 @@ func (s *session) addCandidates(
|
||||
}
|
||||
|
||||
// APIReaderDescribe implements reader.
|
||||
func (s *session) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (s *session) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "webRTCSession",
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// APISourceDescribe implements source.
|
||||
func (s *session) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return s.APIReaderDescribe()
|
||||
func (s *session) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "webRTCSession",
|
||||
ID: s.uuid.String(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *session) apiItem() *defs.APIWebRTCSession {
|
||||
|
||||
@@ -47,7 +47,7 @@ func resolveSource(s string, matches []string, query string) string {
|
||||
type staticSource interface {
|
||||
logger.Writer
|
||||
Run(defs.StaticSourceRunParams) error
|
||||
APISourceDescribe() defs.APIPathSourceOrReader
|
||||
APISourceDescribe() *defs.APIPathSource
|
||||
}
|
||||
|
||||
type handlerPathManager interface {
|
||||
@@ -300,7 +300,7 @@ func (s *Handler) ReloadConf(newConf *conf.Path) {
|
||||
}
|
||||
|
||||
// APISourceDescribe instanceements source.
|
||||
func (s *Handler) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
func (s *Handler) APISourceDescribe() *defs.APIPathSource {
|
||||
return s.instance.APISourceDescribe()
|
||||
}
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "hlsSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -143,8 +143,8 @@ func (s *Source) runReader(nc net.Conn) error {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "mpegtsSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -93,8 +93,8 @@ func (r *secondaryReader) Close() {
|
||||
}
|
||||
|
||||
// APIReaderDescribe implements reader.
|
||||
func (*secondaryReader) APIReaderDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*secondaryReader) APIReaderDescribe() *defs.APIPathReader {
|
||||
return &defs.APIPathReader{
|
||||
Type: "rpiCameraSecondary",
|
||||
ID: "",
|
||||
}
|
||||
@@ -359,8 +359,8 @@ func (s *Source) waitForPrimary(
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rpiCameraSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ func (s *Source) runReader(conn *gortmplib.Client) error {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rtmpSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -217,8 +217,8 @@ func (s *Source) runReader(desc *description.Session, nc net.Conn) error {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rtpSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -270,8 +270,8 @@ func (s *Source) runInner(c *gortsplib.Client, u *base.URL, pathConf *conf.Path)
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "rtspSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -128,8 +128,8 @@ func (s *Source) runReader(sconn srt.Conn) error {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "srtSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -114,8 +114,8 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
|
||||
}
|
||||
|
||||
// APISourceDescribe implements StaticSource.
|
||||
func (*Source) APISourceDescribe() defs.APIPathSourceOrReader {
|
||||
return defs.APIPathSourceOrReader{
|
||||
func (*Source) APISourceDescribe() *defs.APIPathSource {
|
||||
return &defs.APIPathSource{
|
||||
Type: "webRTCSource",
|
||||
ID: "",
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/bluenviron/gortsplib/v5/pkg/auth"
|
||||
"github.com/bluenviron/mediamtx/internal/conf"
|
||||
"github.com/bluenviron/mediamtx/internal/conf/yamlwrapper"
|
||||
"github.com/bluenviron/mediamtx/internal/defs"
|
||||
"github.com/bluenviron/mediamtx/internal/logger"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -32,6 +36,98 @@ type openAPI struct {
|
||||
} `json:"components"`
|
||||
}
|
||||
|
||||
func fillProperty(t *testing.T, rt reflect.Type, existing openAPIProperty) openAPIProperty {
|
||||
switch {
|
||||
case rt == reflect.TypeOf(""):
|
||||
return openAPIProperty{Type: "string"}
|
||||
|
||||
case rt == reflect.PointerTo(reflect.TypeOf("")):
|
||||
return openAPIProperty{
|
||||
Type: "string",
|
||||
Nullable: true,
|
||||
}
|
||||
|
||||
case rt == reflect.TypeOf(int(0)):
|
||||
return openAPIProperty{Type: "integer", Format: "int64"}
|
||||
|
||||
case rt == reflect.TypeOf(uint(0)):
|
||||
return openAPIProperty{Type: "integer", Format: "uint64"}
|
||||
|
||||
case rt == reflect.TypeOf(uint64(0)):
|
||||
return openAPIProperty{Type: "integer", Format: "uint64"}
|
||||
|
||||
case rt == reflect.TypeOf(float64(0)):
|
||||
return openAPIProperty{Type: "number", Format: "double"}
|
||||
|
||||
case rt == reflect.TypeOf(false):
|
||||
return openAPIProperty{Type: "boolean"}
|
||||
|
||||
case rt == reflect.TypeOf(&time.Time{}):
|
||||
return openAPIProperty{Type: "string", Nullable: true}
|
||||
|
||||
case rt == reflect.TypeOf(uuid.UUID{}):
|
||||
return openAPIProperty{Type: "string", Format: "uuid"}
|
||||
|
||||
case rt == reflect.PointerTo(reflect.TypeOf(uuid.UUID{})):
|
||||
return openAPIProperty{Type: "string", Format: "uuid", Nullable: true}
|
||||
|
||||
case rt == reflect.TypeOf(time.Time{}) ||
|
||||
rt == reflect.TypeOf(conf.Duration(0)) ||
|
||||
rt == reflect.TypeOf(net.IPNet{}) ||
|
||||
rt == reflect.TypeOf(conf.Credential("")) ||
|
||||
rt == reflect.TypeOf(conf.RecordFormat(0)) ||
|
||||
rt == reflect.TypeOf(conf.AuthAction("")) ||
|
||||
rt == reflect.TypeOf(conf.Encryption(0)) ||
|
||||
rt == reflect.TypeOf(conf.RTSPTransport{}) ||
|
||||
rt == reflect.TypeOf(conf.StringSize(0)) ||
|
||||
rt == reflect.TypeOf(conf.RTSPRangeType(0)) ||
|
||||
rt == reflect.TypeOf(conf.LogLevel(0)) ||
|
||||
rt == reflect.TypeOf(conf.AuthMethod(0)) ||
|
||||
rt == reflect.TypeOf(logger.Destination(0)) ||
|
||||
rt == reflect.TypeOf(auth.VerifyMethod(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("")):
|
||||
return openAPIProperty{Type: "string"}
|
||||
|
||||
case rt == reflect.TypeOf(conf.RTSPTransports{}):
|
||||
return openAPIProperty{
|
||||
Type: "array",
|
||||
Items: &openAPIProperty{
|
||||
Type: "string",
|
||||
},
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
case rt.Kind() == reflect.Pointer && rt.Elem().Kind() == reflect.Struct:
|
||||
prop := fillProperty(t, rt.Elem(), existing)
|
||||
prop.Nullable = true
|
||||
return prop
|
||||
|
||||
case rt.Kind() == reflect.Slice:
|
||||
items := fillProperty(t, rt.Elem(), *existing.Items)
|
||||
return openAPIProperty{
|
||||
Type: "array",
|
||||
Items: &items,
|
||||
}
|
||||
|
||||
default:
|
||||
t.Errorf("unhandled type: %v", rt)
|
||||
return openAPIProperty{}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPIDocs(t *testing.T) {
|
||||
byts, err := os.ReadFile("../../api/openapi.yaml")
|
||||
require.NoError(t, err)
|
||||
@@ -78,11 +174,11 @@ func TestAPIDocs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"PathSource",
|
||||
defs.APIPathSourceOrReader{},
|
||||
defs.APIPathSource{},
|
||||
},
|
||||
{
|
||||
"PathReader",
|
||||
defs.APIPathSourceOrReader{},
|
||||
defs.APIPathReader{},
|
||||
},
|
||||
{
|
||||
"HLSMuxer",
|
||||
@@ -152,54 +248,15 @@ func TestAPIDocs(t *testing.T) {
|
||||
Type: "object",
|
||||
Properties: make(map[string]openAPIProperty),
|
||||
}
|
||||
|
||||
ty := reflect.TypeOf(ca.goStruct)
|
||||
|
||||
for i := range ty.NumField() {
|
||||
sf := ty.Field(i)
|
||||
js := sf.Tag.Get("json")
|
||||
|
||||
if js != "-" && js != "paths" && js != "pathDefaults" && !strings.Contains(js, ",omitempty") {
|
||||
switch {
|
||||
case sf.Type == reflect.TypeOf(""):
|
||||
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)):
|
||||
content2.Properties[js] = openAPIProperty{Type: "integer", Format: "int64"}
|
||||
|
||||
case sf.Type == reflect.TypeOf(float64(0)):
|
||||
content2.Properties[js] = openAPIProperty{Type: "number", Format: "double"}
|
||||
|
||||
case sf.Type == reflect.TypeOf(false):
|
||||
content2.Properties[js] = openAPIProperty{Type: "boolean"}
|
||||
|
||||
case sf.Type == reflect.TypeOf(time.Time{}):
|
||||
content2.Properties[js] = openAPIProperty{Type: "string"}
|
||||
|
||||
case sf.Type == reflect.TypeOf(&time.Time{}):
|
||||
content2.Properties[js] = openAPIProperty{
|
||||
Type: "string",
|
||||
Nullable: true,
|
||||
}
|
||||
|
||||
case sf.Type == reflect.TypeOf(conf.AuthInternalUserPermissions{}):
|
||||
content2.Properties[js] = openAPIProperty{
|
||||
Type: "array",
|
||||
Items: &openAPIProperty{
|
||||
Ref: "#/components/schemas/AuthInternalUserPermission",
|
||||
},
|
||||
}
|
||||
|
||||
default:
|
||||
if existing, ok := content1.Properties[js]; ok {
|
||||
content2.Properties[js] = existing
|
||||
} else {
|
||||
t.Errorf("missing item: '%s'", js)
|
||||
}
|
||||
}
|
||||
content2.Properties[js] = fillProperty(t, sf.Type, content1.Properties[js])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user