From 1fbb43ff83872ae16d7829990ba8c6dfe4007e47 Mon Sep 17 00:00:00 2001 From: Faiq Naufal <43695578+faiq-naufal@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:59:29 +0700 Subject: [PATCH] fix: remote stream data with empty client id and empty client name value (#107) Fix the issue of a remote stream data with empty client id and empty client name value --- packages/room/channel/channel.js | 54 +++++++++++++++++------- packages/room/peer/peer.js | 71 ++++++++++++++++++-------------- packages/room/stream/streams.js | 5 +-- 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/packages/room/channel/channel.js b/packages/room/channel/channel.js index d4252b41..676d31d0 100644 --- a/packages/room/channel/channel.js +++ b/packages/room/channel/channel.js @@ -1,4 +1,5 @@ import { RoomEvent } from '../index.js' +import { InternalPeerEvents } from '../peer/peer.js' export const REASONS = { PEER_CLOSED: 'peerClosed', @@ -268,29 +269,24 @@ export const createChannel = ({ api, event, peer, streams }) => { const data = JSON.parse(event.data) /** @type {import('./channel-types.js').RoomChannelType.SubscribingTrack[]} */ const subscribingTracks = [] + const streams = [] for (const id of Object.keys(data.tracks)) { const track = data.tracks[id] - const streamId = track.stream_id - const clientId = track.client_id - const clientName = track.client_name - const trackId = track.track_id - const source = track.source subscribingTracks.push({ - client_id: clientId, - stream_id: streamId, - track_id: trackId, + client_id: track.client_id, + stream_id: track.stream_id, + track_id: track.track_id, }) - if (!this._streams.getDraft(streamId)) { - this._streams.addDraft(streamId, { - clientId: clientId, - name: clientName, - origin: 'remote', - source: source, - }) - } + streams.push({ + streamId: track.stream_id, + clientId: track.client_id, + name: track.client_name, + origin: 'remote', + source: track.source, + }) } await this._api.subscribeTracks( @@ -298,6 +294,32 @@ export const createChannel = ({ api, event, peer, streams }) => { this._clientId, subscribingTracks ) + + for (const stream of streams) { + const draftStream = this._streams.getDraft(stream.streamId) + + if (draftStream) { + const newStream = { + ...draftStream, + clientId: stream.clientId, + name: stream.name, + source: stream.source, + origin: stream.origin, + } + + this._event.emit( + InternalPeerEvents.REMOTE_STREAM_READY_TO_ADD, + newStream + ) + } else { + this._streams.addDraft(stream.streamId, { + clientId: stream.clientId, + name: stream.name, + source: stream.source, + origin: stream.origin, + }) + } + } } /** diff --git a/packages/room/peer/peer.js b/packages/room/peer/peer.js index 07ef3272..c34c4eb1 100644 --- a/packages/room/peer/peer.js +++ b/packages/room/peer/peer.js @@ -8,6 +8,7 @@ import { RoomEvent } from '../index.js' export const InternalPeerEvents = { INTERNAL_DATACHANNEL_AVAILABLE: 'internalDataChannelAvailable', + REMOTE_STREAM_READY_TO_ADD: 'remoteStreamReadyToAdd', } /** @param {import('./peer-types.js').RoomPeerType.PeerDependencies} peerDependencies Dependencies for peer module */ @@ -125,7 +126,13 @@ export const createPeer = ({ api, createStream, event, streams, config }) => { */ addStream = (key, data) => { this._streams.validateKey(key) - this._streams.validateStream(data) + const isValidStream = this._streams.validateStream(data) + + if (!isValidStream) { + throw new Error( + 'Please provide valid stream data (clientId, name, origin, source, MediaStream)' + ) + } const stream = this._stream.createInstance({ id: key, @@ -314,6 +321,33 @@ export const createPeer = ({ api, createStream, event, streams, config }) => { } ) + this._event.on( + InternalPeerEvents.REMOTE_STREAM_READY_TO_ADD, + /** @param {import('../stream/stream-types.js').RoomStreamType.AddStreamParameters} stream */ + (stream) => { + const isValidStream = this._streams.validateStream(stream) + if (!isValidStream || this.hasStream(stream.mediaStream.id)) return + + stream.mediaStream.addEventListener('removetrack', (event) => { + const target = event.target + + if (!(target instanceof MediaStream)) return + + if (this.hasStream(target.id) && target.getTracks().length === 0) { + this.removeStream(target.id) + } + }) + + for (const track of stream.mediaStream.getTracks()) { + track.addEventListener('ended', () => { + this.removeStream(stream.mediaStream.id) + }) + } + + this.addStream(stream.mediaStream.id, stream) + } + ) + window.addEventListener('beforeunload', this._onBeforeUnload) } @@ -739,37 +773,14 @@ export const createPeer = ({ api, createStream, event, streams, config }) => { */ _onTrack = async (event) => { const mediaStream = event.streams.find((stream) => stream.active === true) + const draftStream = this._streams.getDraft(mediaStream.id) - if (!(mediaStream instanceof MediaStream)) return - if (this.hasStream(mediaStream.id)) return - - mediaStream.addEventListener('removetrack', (event) => { - const target = event.target - - if (!(target instanceof MediaStream)) return - - if (this.hasStream(target.id) && target.getTracks().length === 0) { - this.removeStream(target.id) - } - }) - - for (const track of mediaStream.getTracks()) { - track.addEventListener('ended', () => { - this.removeStream(mediaStream.id) - }) + if (draftStream) { + const stream = { ...draftStream, mediaStream } + this._event.emit(InternalPeerEvents.REMOTE_STREAM_READY_TO_ADD, stream) + } else { + this._streams.addDraft(mediaStream.id, { mediaStream }) } - - const draftStream = this._streams.getDraft(mediaStream.id) || {} - - this.addStream(mediaStream.id, { - clientId: draftStream.clientId || '', - name: draftStream.name || '', - origin: draftStream.origin || 'remote', - source: draftStream.source || 'media', - mediaStream: mediaStream, - }) - - this._streams.removeDraft(mediaStream.id) } /** diff --git a/packages/room/stream/streams.js b/packages/room/stream/streams.js index 9a53d966..97f61164 100644 --- a/packages/room/stream/streams.js +++ b/packages/room/stream/streams.js @@ -142,7 +142,6 @@ export const createStreams = () => { /** * Validate the streams data * @param {import('./stream-types.js').RoomStreamType.AddStreamParameters} data - * @throws {Error} * @returns {boolean} */ validateStream = (data) => { @@ -154,9 +153,7 @@ export const createStreams = () => { typeof data.clientId !== 'string' || typeof data.name !== 'string' ) { - throw new Error( - 'Please provide valid stream data (clientId, name, origin, source, MediaStream)' - ) + return false } return true