mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
Capture bandwidth switch (#14)
* Handle bitrate change by finding the stream with closest bitrate as peer * Convert video id into bitrate when creating peer or changing bitrate * Try to fix prometheus panic * Revert metrics label name change * minor fixes. * bitrate selector. * skip if moving to the same stream. * no closure for getting target bitrate. * fix: high res switch to lo video, stream bitrate out of range * revert dev config change. * white space. Co-authored-by: Aleksandar Sukovic <aleksandar.sukovic@gmail.com>
This commit is contained in:
@ -22,7 +22,7 @@ type Sample media.Sample
|
||||
type Receiver interface {
|
||||
SetStream(stream StreamSinkManager) error
|
||||
RemoveStream()
|
||||
OnVideoIdChange(f func(string) error)
|
||||
OnBitrateChange(f func(int) error)
|
||||
}
|
||||
|
||||
type BucketsManager interface {
|
||||
@ -46,6 +46,7 @@ type ScreencastManager interface {
|
||||
}
|
||||
|
||||
type StreamSinkManager interface {
|
||||
ID() string
|
||||
Codec() codec.RTPCodec
|
||||
|
||||
AddListener(listener *func(sample Sample)) error
|
||||
@ -70,6 +71,8 @@ type CaptureManager interface {
|
||||
Start()
|
||||
Shutdown() error
|
||||
|
||||
GetBitrateFromVideoID(videoID string) (int, error)
|
||||
|
||||
Broadcast() BroadcastManager
|
||||
Screencast() ScreencastManager
|
||||
Audio() StreamSinkManager
|
||||
@ -83,6 +86,7 @@ type VideoConfig struct {
|
||||
Width string `mapstructure:"width"` // expression
|
||||
Height string `mapstructure:"height"` // expression
|
||||
Fps string `mapstructure:"fps"` // expression
|
||||
Bitrate int `mapstructure:"bitrate"` // pipeline bitrate
|
||||
GstPrefix string `mapstructure:"gst_prefix"` // pipeline prefix, starts with !
|
||||
GstEncoder string `mapstructure:"gst_encoder"` // gst encoder name
|
||||
GstParams map[string]string `mapstructure:"gst_params"` // map of expressions
|
||||
@ -173,3 +177,41 @@ func (config *VideoConfig) GetPipeline(screen ScreenSize) (string, error) {
|
||||
config.GstSuffix,
|
||||
}[:], " "), nil
|
||||
}
|
||||
|
||||
func (config *VideoConfig) GetBitrateFn(getScreen func() *ScreenSize) func() (int, error) {
|
||||
return func() (int, error) {
|
||||
if config.Bitrate > 0 {
|
||||
return config.Bitrate, nil
|
||||
}
|
||||
|
||||
screen := getScreen()
|
||||
if screen == nil {
|
||||
return 0, fmt.Errorf("screen is nil")
|
||||
}
|
||||
|
||||
values := map[string]any{
|
||||
"width": screen.Width,
|
||||
"height": screen.Height,
|
||||
"fps": screen.Rate,
|
||||
}
|
||||
|
||||
language := []gval.Language{
|
||||
gval.Function("round", func(args ...any) (any, error) {
|
||||
return (int)(math.Round(args[0].(float64))), nil
|
||||
}),
|
||||
}
|
||||
|
||||
// TODO: This is only for vp8.
|
||||
expr, ok := config.GstParams["target-bitrate"]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("target-bitrate not found")
|
||||
}
|
||||
|
||||
targetBitrate, err := gval.Evaluate(expr, values, language...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return targetBitrate.(int), nil
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ type SystemDisconnect struct {
|
||||
type SignalProvide struct {
|
||||
SDP string `json:"sdp"`
|
||||
ICEServers []types.ICEServer `json:"iceservers"`
|
||||
Video string `json:"video"`
|
||||
Video string `json:"video"` // TODO: Refactor.
|
||||
}
|
||||
|
||||
type SignalCandidate struct {
|
||||
@ -60,7 +60,8 @@ type SignalDescription struct {
|
||||
}
|
||||
|
||||
type SignalVideo struct {
|
||||
Video string `json:"video"`
|
||||
Video string `json:"video"` // TODO: Refactor.
|
||||
Bitrate int `json:"bitrate"`
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrWebRTCVideoNotFound = errors.New("webrtc video not found")
|
||||
ErrWebRTCDataChannelNotFound = errors.New("webrtc data channel not found")
|
||||
ErrWebRTCConnectionNotFound = errors.New("webrtc connection not found")
|
||||
)
|
||||
@ -25,7 +24,8 @@ type WebRTCPeer interface {
|
||||
SetAnswer(sdp string) error
|
||||
SetCandidate(candidate webrtc.ICECandidateInit) error
|
||||
|
||||
SetVideoID(videoID string) error
|
||||
SetVideoBitrate(bitrate int) error
|
||||
GetVideoId() string
|
||||
SetPaused(isPaused bool) error
|
||||
|
||||
SendCursorPosition(x, y int) error
|
||||
@ -40,6 +40,6 @@ type WebRTCManager interface {
|
||||
|
||||
ICEServers() []ICEServer
|
||||
|
||||
CreatePeer(session Session, videoID string) (*webrtc.SessionDescription, error)
|
||||
CreatePeer(session Session, bitrate int) (*webrtc.SessionDescription, error)
|
||||
SetCursorPosition(x, y int)
|
||||
}
|
||||
|
Reference in New Issue
Block a user