mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
add receiverEstimatedMaximumBitrate.
This commit is contained in:
parent
3fda00bac5
commit
01b5d61e2b
@ -400,6 +400,13 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, videoID strin
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
videoTrack.OnRTCP(func(p rtcp.Packet) {
|
||||||
|
switch rtcpPacket := p.(type) {
|
||||||
|
case *rtcp.ReceiverEstimatedMaximumBitrate: // TODO: Deprecated.
|
||||||
|
manager.metrics.SetReceiverEstimatedMaximumBitrate(session, rtcpPacket.Bitrate)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ticker := time.NewTicker(5 * time.Second)
|
ticker := time.NewTicker(5 * time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
@ -21,6 +21,8 @@ type metrics struct {
|
|||||||
videoIds map[string]prometheus.Gauge
|
videoIds map[string]prometheus.Gauge
|
||||||
videoIdsMu *sync.Mutex
|
videoIdsMu *sync.Mutex
|
||||||
|
|
||||||
|
receiverEstimatedMaximumBitrate prometheus.Gauge
|
||||||
|
|
||||||
iceBytesSent prometheus.Gauge
|
iceBytesSent prometheus.Gauge
|
||||||
iceBytesReceived prometheus.Gauge
|
iceBytesReceived prometheus.Gauge
|
||||||
sctpBytesSent prometheus.Gauge
|
sctpBytesSent prometheus.Gauge
|
||||||
@ -92,6 +94,16 @@ func (m *metricsCtx) getBySession(session types.Session) metrics {
|
|||||||
videoIds: map[string]prometheus.Gauge{},
|
videoIds: map[string]prometheus.Gauge{},
|
||||||
videoIdsMu: &sync.Mutex{},
|
videoIdsMu: &sync.Mutex{},
|
||||||
|
|
||||||
|
receiverEstimatedMaximumBitrate: promauto.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Name: "receiver_estimated_maximum_bitrate",
|
||||||
|
Namespace: "neko",
|
||||||
|
Subsystem: "webrtc",
|
||||||
|
Help: "Receiver Estimated Maximum Bitrate from SCTP.",
|
||||||
|
ConstLabels: map[string]string{
|
||||||
|
"session_id": session.ID(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
iceBytesSent: promauto.NewGauge(prometheus.GaugeOpts{
|
iceBytesSent: promauto.NewGauge(prometheus.GaugeOpts{
|
||||||
Name: "ice_bytes_sent",
|
Name: "ice_bytes_sent",
|
||||||
Namespace: "neko",
|
Namespace: "neko",
|
||||||
@ -205,6 +217,12 @@ func (m *metricsCtx) SetVideoID(session types.Session, videoId string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *metricsCtx) SetReceiverEstimatedMaximumBitrate(session types.Session, bitrate float32) {
|
||||||
|
met := m.getBySession(session)
|
||||||
|
|
||||||
|
met.receiverEstimatedMaximumBitrate.Set(float64(bitrate))
|
||||||
|
}
|
||||||
|
|
||||||
func (m *metricsCtx) SetIceTransportStats(session types.Session, data webrtc.TransportStats) {
|
func (m *metricsCtx) SetIceTransportStats(session types.Session, data webrtc.TransportStats) {
|
||||||
met := m.getBySession(session)
|
met := m.getBySession(session)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pion/rtcp"
|
||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
"github.com/pion/webrtc/v3/pkg/media"
|
"github.com/pion/webrtc/v3/pkg/media"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
@ -51,6 +52,9 @@ type PeerStreamTrack struct {
|
|||||||
|
|
||||||
stream types.StreamSinkManager
|
stream types.StreamSinkManager
|
||||||
streamMu sync.Mutex
|
streamMu sync.Mutex
|
||||||
|
|
||||||
|
onRtcp func(rtcp.Packet)
|
||||||
|
onRtcpMu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (peer *PeerStreamTrack) SetStream(stream types.StreamSinkManager) error {
|
func (peer *PeerStreamTrack) SetStream(stream types.StreamSinkManager) error {
|
||||||
@ -90,9 +94,31 @@ func (peer *PeerStreamTrack) AddToConnection(connection *webrtc.PeerConnection)
|
|||||||
go func() {
|
go func() {
|
||||||
rtcpBuf := make([]byte, 1500)
|
rtcpBuf := make([]byte, 1500)
|
||||||
for {
|
for {
|
||||||
if _, _, err := sender.Read(rtcpBuf); err != nil {
|
n, _, err := sender.Read(rtcpBuf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF || err == io.ErrClosedPipe {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer.logger.Err(err).Msg("RTCP read error")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
packets, err := rtcp.Unmarshal(rtcpBuf[:n])
|
||||||
|
if err != nil {
|
||||||
|
peer.logger.Err(err).Msg("RTCP unmarshal error")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
peer.onRtcpMu.RLock()
|
||||||
|
handler := peer.onRtcp
|
||||||
|
peer.onRtcpMu.RUnlock()
|
||||||
|
|
||||||
|
for _, packet := range packets {
|
||||||
|
if handler != nil {
|
||||||
|
go handler(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -102,3 +128,10 @@ func (peer *PeerStreamTrack) AddToConnection(connection *webrtc.PeerConnection)
|
|||||||
func (peer *PeerStreamTrack) SetPaused(paused bool) {
|
func (peer *PeerStreamTrack) SetPaused(paused bool) {
|
||||||
peer.paused = paused
|
peer.paused = paused
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (peer *PeerStreamTrack) OnRTCP(f func(rtcp.Packet)) {
|
||||||
|
peer.onRtcpMu.Lock()
|
||||||
|
defer peer.onRtcpMu.Unlock()
|
||||||
|
|
||||||
|
peer.onRtcp = f
|
||||||
|
}
|
||||||
|
@ -6,6 +6,18 @@ import (
|
|||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var RTCPFeedback = []webrtc.RTCPFeedback{
|
||||||
|
{Type: webrtc.TypeRTCPFBTransportCC, Parameter: ""},
|
||||||
|
{Type: webrtc.TypeRTCPFBGoogREMB, Parameter: ""},
|
||||||
|
|
||||||
|
// https://www.iana.org/assignments/sdp-parameters/sdp-parameters.xhtml#sdp-parameters-19
|
||||||
|
{Type: webrtc.TypeRTCPFBCCM, Parameter: "fir"},
|
||||||
|
|
||||||
|
// https://www.iana.org/assignments/sdp-parameters/sdp-parameters.xhtml#sdp-parameters-15
|
||||||
|
{Type: webrtc.TypeRTCPFBNACK, Parameter: "pli"},
|
||||||
|
{Type: webrtc.TypeRTCPFBNACK, Parameter: ""},
|
||||||
|
}
|
||||||
|
|
||||||
func ParseRTC(codec webrtc.RTPCodecParameters) (RTPCodec, bool) {
|
func ParseRTC(codec webrtc.RTPCodecParameters) (RTPCodec, bool) {
|
||||||
codecName := strings.Split(codec.RTPCodecCapability.MimeType, "/")[1]
|
codecName := strings.Split(codec.RTPCodecCapability.MimeType, "/")[1]
|
||||||
return ParseStr(codecName)
|
return ParseStr(codecName)
|
||||||
@ -61,7 +73,7 @@ func VP8() RTPCodec {
|
|||||||
ClockRate: 90000,
|
ClockRate: 90000,
|
||||||
Channels: 0,
|
Channels: 0,
|
||||||
SDPFmtpLine: "",
|
SDPFmtpLine: "",
|
||||||
RTCPFeedback: []webrtc.RTCPFeedback{},
|
RTCPFeedback: RTCPFeedback,
|
||||||
},
|
},
|
||||||
// https://gstreamer.freedesktop.org/documentation/vpx/vp8enc.html
|
// https://gstreamer.freedesktop.org/documentation/vpx/vp8enc.html
|
||||||
// gstreamer1.0-plugins-good
|
// gstreamer1.0-plugins-good
|
||||||
@ -80,7 +92,7 @@ func VP9() RTPCodec {
|
|||||||
ClockRate: 90000,
|
ClockRate: 90000,
|
||||||
Channels: 0,
|
Channels: 0,
|
||||||
SDPFmtpLine: "profile-id=0",
|
SDPFmtpLine: "profile-id=0",
|
||||||
RTCPFeedback: []webrtc.RTCPFeedback{},
|
RTCPFeedback: RTCPFeedback,
|
||||||
},
|
},
|
||||||
// https://gstreamer.freedesktop.org/documentation/vpx/vp9enc.html
|
// https://gstreamer.freedesktop.org/documentation/vpx/vp9enc.html
|
||||||
// gstreamer1.0-plugins-good
|
// gstreamer1.0-plugins-good
|
||||||
@ -99,7 +111,7 @@ func H264() RTPCodec {
|
|||||||
ClockRate: 90000,
|
ClockRate: 90000,
|
||||||
Channels: 0,
|
Channels: 0,
|
||||||
SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f",
|
SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f",
|
||||||
RTCPFeedback: []webrtc.RTCPFeedback{},
|
RTCPFeedback: RTCPFeedback,
|
||||||
},
|
},
|
||||||
// https://gstreamer.freedesktop.org/documentation/x264/index.html
|
// https://gstreamer.freedesktop.org/documentation/x264/index.html
|
||||||
// gstreamer1.0-plugins-ugly
|
// gstreamer1.0-plugins-ugly
|
||||||
|
Loading…
Reference in New Issue
Block a user