From d0510f8fc5c01dc6a92ef1163eb874cd8981ec29 Mon Sep 17 00:00:00 2001 From: tymccart Date: Mon, 23 Aug 2021 13:27:06 -0500 Subject: [PATCH] Feat/use track method (#22) * feat: setUnderlyingTrack method * feat: useTrack method * feat: track emits event to be handled by peer connection for new track * fix: change method name to 'replaceUnderlyingTrack' * fix: changed 'trackId' to 'oldTrackId' * style: alphabetize local-track methods --- src/local-track.ts | 13 +++++++++++++ src/peer-connection.ts | 16 ++++++++++++++++ src/track.ts | 9 +++++++++ 3 files changed, 38 insertions(+) diff --git a/src/local-track.ts b/src/local-track.ts index e63b514..838e8e4 100644 --- a/src/local-track.ts +++ b/src/local-track.ts @@ -4,6 +4,19 @@ import { Track } from './track'; * A wrapper around MediaStreamTrack. */ export class LocalTrack extends Track { + /** + * Exchange the underlying track with a new track. Emit the `track-update` event to alert + * listeners to an update on a new track. + * + * @param track - New underlying track. + * @fires LocalTrack#track-update + */ + replaceUnderlyingTrack(track: MediaStreamTrack): void { + this.emit('track-update', this.getUnderlyingTrack().id, track); + this.getUnderlyingTrack().stop(); + this.setUnderlyingTrack(track); + } + /** * Sets the track to be enabled or disabled. * diff --git a/src/peer-connection.ts b/src/peer-connection.ts index 7f0a937..9f8452d 100644 --- a/src/peer-connection.ts +++ b/src/peer-connection.ts @@ -14,6 +14,9 @@ class PeerConnection { log('PeerConnection init'); this.pc = new RTCPeerConnection(); + + // Bind event handlers. + this.handleTrackUpdate = this.handleTrackUpdate.bind(this); } /** @@ -23,8 +26,10 @@ class PeerConnection { * @param streams - (Optional) One or more local MediaStream objects to which the track should be * added. * @returns The RTCRtpSender object which will be used to transmit the media data. + * @listens LocalTrack#track-update */ addTrack(track: LocalTrack, ...streams: MediaStream[]): RTCRtpSender { + track.on('track-update', this.handleTrackUpdate); return this.pc.addTrack(track.getUnderlyingTrack(), ...streams); } @@ -91,6 +96,17 @@ class PeerConnection { close(): void { this.pc.close(); } + + /** + * Handles `track-update` event and replaces track on sender. + * + * @param oldTrackId - Id of the existing track. + * @param newTrack - New LocalTrack. + */ + handleTrackUpdate(oldTrackId: string, newTrack: MediaStreamTrack): void { + const sender = this.pc.getSenders().find((s: RTCRtpSender) => s.track?.id === oldTrackId); + sender?.replaceTrack(newTrack); + } } export { PeerConnection }; diff --git a/src/track.ts b/src/track.ts index 74bdbcc..1c14154 100644 --- a/src/track.ts +++ b/src/track.ts @@ -28,4 +28,13 @@ export abstract class Track extends EventEmitter { getUnderlyingTrack(): MediaStreamTrack { return this.track; } + + /** + * Sets the underlying track. + * + * @param track - The new underlying track. + */ + setUnderlyingTrack(track: MediaStreamTrack): void { + this.track = track; + } }