move webrtc congestion control to connection.

This commit is contained in:
Miroslav Šedivý 2021-06-19 18:51:14 +02:00
parent daff2552a3
commit 071f97fb1b
2 changed files with 45 additions and 41 deletions

View File

@ -1,5 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import * as EVENT from '../types/events'
import { NekoWebSocket } from './websocket' import { NekoWebSocket } from './websocket'
import { NekoWebRTC, WebRTCStats } from './webrtc' import { NekoWebRTC, WebRTCStats } from './webrtc'
@ -69,6 +70,41 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
Vue.set(this._state, 'status', 'disconnected') Vue.set(this._state, 'status', 'disconnected')
} }
}) })
let webrtcCongestion: number = 0
this.webrtc.on('stats', (stats: WebRTCStats) => {
Vue.set(this._state.webrtc, 'stats', stats)
// if automatic quality adjusting is turned off
if (!this._state.webrtc.auto) return
// if there are no or just one quality, no switching can be done
if (this._state.webrtc.videos.length <= 1) return
// current quality is not known
if (this._state.webrtc.video == null) return
// check if video is not playing
if (stats.fps) {
webrtcCongestion = 0
return
}
// try to downgrade quality if it happend many times
if (++webrtcCongestion >= 3) {
const index = this._state.webrtc.videos.indexOf(this._state.webrtc.video)
// edge case: current quality is not in qualities list
if (index === -1) return
// current quality is the lowest one
if (index + 1 == this._state.webrtc.videos.length) return
// downgrade video quality
this.setVideo(this._state.webrtc.videos[index + 1])
webrtcCongestion = 0
}
})
} }
public setUrl(url: string) { public setUrl(url: string) {
@ -79,6 +115,14 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
this._token = token this._token = token
} }
public setVideo(video: string) {
if (!this._state.webrtc.videos.includes(video)) {
throw new Error('video id not found')
}
this.websocket.send(EVENT.SIGNAL_VIDEO, { video: video })
}
public async connect(): Promise<void> { public async connect(): Promise<void> {
let url = this._url let url = this._url
if (this._token) { if (this._token) {

View File

@ -314,13 +314,8 @@
this.connection.websocket.send(EVENT.SCREEN_SET, { width, height, rate }) this.connection.websocket.send(EVENT.SCREEN_SET, { width, height, rate })
} }
// TODO: Refactor.
public setWebRTCVideo(video: string) { public setWebRTCVideo(video: string) {
if (!this.state.connection.webrtc.videos.includes(video)) { this.connection.setVideo(video)
throw new Error('video id not found')
}
this.connection.websocket.send(EVENT.SIGNAL_VIDEO, { video: video })
} }
// TODO: Refactor. // TODO: Refactor.
@ -392,41 +387,6 @@
} }
}) })
let webrtcCongestion: number = 0
this.connection.webrtc.on('stats', (stats: WebRTCStats) => {
Vue.set(this.state.connection.webrtc, 'stats', stats)
// if automatic quality adjusting is turned off
if (!this.state.connection.webrtc.auto) return
// if there are no or just one quality, no switching can be done
if (this.state.connection.webrtc.videos.length <= 1) return
// current quality is not known
if (this.state.connection.webrtc.video == null) return
// check if video is not playing
if (stats.fps) {
webrtcCongestion = 0
return
}
// try to downgrade quality if it happend many times
if (++webrtcCongestion >= 3) {
let index = this.state.connection.webrtc.videos.indexOf(this.state.connection.webrtc.video)
// edge case: current quality is not in qualities list
if (index === -1) return
// current quality is the lowest one
if (index + 1 == this.state.connection.webrtc.videos.length) return
// downgrade video quality
this.setWebRTCVideo(this.state.connection.webrtc.videos[index + 1])
webrtcCongestion = 0
}
})
// unmute on users first interaction // unmute on users first interaction
if (this.autoplay) { if (this.autoplay) {
document.addEventListener('click', this.unmute, { once: true }) document.addEventListener('click', this.unmute, { once: true })