diff --git a/src/component/internal/connection.ts b/src/component/internal/connection.ts index dc719e06..43f0f9c1 100644 --- a/src/component/internal/connection.ts +++ b/src/component/internal/connection.ts @@ -1,6 +1,7 @@ import Vue from 'vue' import EventEmitter from 'eventemitter3' import * as EVENT from '../types/events' +import * as webrtcTypes from '../types/webrtc' import { NekoWebSocket } from './websocket' import { NekoLoggerFactory } from './logger' @@ -24,6 +25,7 @@ export interface NekoConnectionEvents { export class NekoConnection extends EventEmitter { private _open = false private _closing = false + private _peerRequest?: webrtcTypes.PeerRequest public websocket = new NekoWebSocket() public logger = new NekoLoggerFactory(this.websocket) @@ -62,7 +64,14 @@ export class NekoConnection extends EventEmitter { } if (this.websocket.connected && !this.webrtc.connected) { - this._reconnector.webrtc.connect() + // if custom peer request is set, send custom peer request + if (this._peerRequest) { + this.websocket.send(EVENT.SIGNAL_REQUEST, this._peerRequest) + this._peerRequest = undefined + } else { + // otherwise use reconnectors connect method + this._reconnector.webrtc.connect() + } } } @@ -109,10 +118,10 @@ export class NekoConnection extends EventEmitter { this._webrtcCongestionControlHandle = (stats: WebRTCStats) => { // if automatic quality adjusting is turned off - if (this._state.webrtc.auto) return + if (this._state.webrtc.video.auto) return - // when connection is paused, 0fps and muted track is expected - if (stats.paused) return + // when connection is paused or video disabled, 0fps and muted track is expected + if (stats.paused || this._state.webrtc.video.disabled) return // if automatic quality adjusting is turned off if (!this._reconnector.webrtc.isOpen) return @@ -121,7 +130,7 @@ export class NekoConnection extends EventEmitter { if (this._state.webrtc.videos.length <= 1) return // current quality is not known - if (this._state.webrtc.video == null) return + if (this._state.webrtc.video.id == '') return // check if video is not playing smoothly if (stats.fps && stats.packetLoss < WEBRTC_RECONN_MAX_LOSS && !stats.muted) { @@ -142,7 +151,7 @@ export class NekoConnection extends EventEmitter { webrtcCongestion = 0 - const quality = this._webrtcQualityDowngrade(this._state.webrtc.video) + const quality = this._webrtcQualityDowngrade(this._state.webrtc.video.id) // downgrade if lower video quality exists if (quality && this.webrtc.connected) { @@ -176,27 +185,13 @@ export class NekoConnection extends EventEmitter { return this.logger.new(scope) } - public open(video?: string, auto?: boolean) { + public open(peerRequest?: webrtcTypes.PeerRequest) { if (this._open) { throw new Error('connection already open') } this._open = true - - if (video) { - if (!this._state.webrtc.videos.includes(video)) { - throw new Error('video id not found') - } - - Vue.set(this._state.webrtc, 'video', video) - } - - // if we didn't specify auto - if (typeof auto == 'undefined') { - // if we didn't specify video, set auto to true - auto = !video - } - Vue.set(this._state.webrtc, 'auto', auto) + this._peerRequest = peerRequest Vue.set(this._state, 'status', 'connecting') diff --git a/src/component/internal/messages.ts b/src/component/internal/messages.ts index 9e1993b3..42147520 100644 --- a/src/component/internal/messages.ts +++ b/src/component/internal/messages.ts @@ -147,7 +147,7 @@ export class NekoMessages extends EventEmitter { // Signal Events ///////////////////////////// - protected async [EVENT.SIGNAL_PROVIDE]({ sdp, iceservers }: message.SignalProvide) { + protected async [EVENT.SIGNAL_PROVIDE]({ sdp, iceservers, video, audio }: message.SignalProvide) { this._localLog.debug(`EVENT.SIGNAL_PROVIDE`) // create WebRTC connection @@ -158,6 +158,9 @@ export class NekoMessages extends EventEmitter { // TODO: Return whole signal description (if answer / offer). this.emit('connection.webrtc.sdp', 'remote', sdp) + + this[EVENT.SIGNAL_VIDEO](video) + this[EVENT.SIGNAL_AUDIO](audio) } protected async [EVENT.SIGNAL_OFFER]({ sdp }: message.SignalDescription) { @@ -193,10 +196,16 @@ export class NekoMessages extends EventEmitter { this.emit('connection.webrtc.sdp.candidate', 'remote', candidate) } - protected [EVENT.SIGNAL_VIDEO]({ video, auto }: message.SignalVideo) { - this._localLog.debug(`EVENT.SIGNAL_VIDEO`, { video, auto }) - Vue.set(this._state.connection.webrtc, 'video', video) - Vue.set(this._state.connection.webrtc, 'auto', !!auto) + protected [EVENT.SIGNAL_VIDEO]({ disabled, id, auto }: message.SignalVideo) { + this._localLog.debug(`EVENT.SIGNAL_VIDEO`, { disabled, id, auto }) + Vue.set(this._state.connection.webrtc.video, 'disabled', disabled) + Vue.set(this._state.connection.webrtc.video, 'id', id) + Vue.set(this._state.connection.webrtc.video, 'auto', auto) + } + + protected [EVENT.SIGNAL_AUDIO]({ disabled }: message.SignalAudio) { + this._localLog.debug(`EVENT.SIGNAL_AUDIO`, { disabled }) + Vue.set(this._state.connection.webrtc.audio, 'disabled', disabled) } protected [EVENT.SIGNAL_CLOSE]() { diff --git a/src/component/internal/reconnector/webrtc.ts b/src/component/internal/reconnector/webrtc.ts index bbddd24f..25400188 100644 --- a/src/component/internal/reconnector/webrtc.ts +++ b/src/component/internal/reconnector/webrtc.ts @@ -37,9 +37,25 @@ export class WebrtcReconnector extends ReconnectorAbstract { } if (this._websocket.connected) { + // use requests from state to connect with selected values + + let selector = null + if (this._state.webrtc.video.id) { + selector = { + id: this._state.webrtc.video.id, + type: 'exact', + } + } + this._websocket.send(EVENT.SIGNAL_REQUEST, { - video: this._state.webrtc.video, - auto: this._state.webrtc.auto, + video: { + disabled: this._state.webrtc.video.disabled, + selector, + auto: this._state.webrtc.video.auto, + }, + audio: { + disabled: this._state.webrtc.audio.disabled, + }, }) } } diff --git a/src/component/main.vue b/src/component/main.vue index 457b7ea0..057cb224 100644 --- a/src/component/main.vue +++ b/src/component/main.vue @@ -74,7 +74,7 @@