Skip to content

Commit

Permalink
feat(calls): cleanup & comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Drew Ewing committed May 5, 2022
1 parent bc34c02 commit 693adf3
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 47 deletions.
195 changes: 189 additions & 6 deletions libraries/WebRTC/Call.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Duplex } from 'stream'
import Peer, { SignalData } from 'simple-peer'
import PeerId from 'peer-id'
import Emitter from './Emitter'
Expand Down Expand Up @@ -78,10 +77,21 @@ export class Call extends Emitter<CallEventListeners> {
this._bindBusListeners()
}

/**
* @method isDirectCall
* @description Returns true if the call is direct, false otherwise
* @returns {boolean}
* @example
* const isDirectCall = call.isDirectCall()
*/
isDirectCall() {
return this.peerIds.length <= 1
}

/**
* @method requestPeerCalls
* @description Send a libp2p message requesting for the given peerIds to initiate a call
*/
async requestPeerCalls() {
await Promise.all(
this.peerIds.map(async (peerId) => {
Expand Down Expand Up @@ -137,6 +147,15 @@ export class Call extends Emitter<CallEventListeners> {
await this.start()
}

/**
* @method initiateCall
* @description locally initiates a call to the given peer
* @param peerId
* @param asCaller boolean indicating if the local peer is the caller or not
* @returns {Promise<void>}
* @example
* await call.initiateCall(peerId, true)
*/
async initiateCall(peerId: string, asCaller: boolean = false) {
if (!this.peers[peerId]) {
const peer = new CallPeer(
Expand Down Expand Up @@ -170,6 +189,14 @@ export class Call extends Emitter<CallEventListeners> {
}
}

/**
* @method sendPeerCallRequest
* @description Send a call request to the given peer
* @param peerId
* @returns {Promise<void>}
* @example
* await call.sendPeerCallRequest(peerId)
*/
async sendPeerCallRequest(peerId: string) {
if (this.peerConnected[peerId] || this.peerDialingDisabled[peerId]) return
await this.p2p.sendMessage(
Expand All @@ -188,16 +215,24 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method setCallId
* @description Sets the callId of the current call
* @param callId
* @returns {void}
* @example
* call.setCallId(callId)
*/
setCallId(callId: string) {
this.callId = callId
}

/**
* @method createLocalTracks
* @description Generate local tracks for audio/video
* @param kinds Array of track kind you want to create
* @description Generate local streams for audio/video/screen
* @param kinds Array of track kinds you want to create
* @param constraints Media stream constraints to apply
* @returns The created local tracks
* @returns The created streams
* @example
*/
async createLocalTracks(
Expand All @@ -224,6 +259,14 @@ export class Call extends Emitter<CallEventListeners> {
return this.streams
}

/**
* @method createAudioStream
* @description Create local audio stream and send it to remote peers
* @param constraints Media stream constraints to apply
* @returns {Promise<void>}
* @example
* await call.createAudioStream()
*/
async createAudioStream(
constraints: MediaTrackConstraints | boolean | undefined,
) {
Expand Down Expand Up @@ -258,6 +301,14 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method createVideoStream
* @description Create local video stream and send it to remote peers
* @param constraints Media stream constraints to apply
* @returns {Promise<void>}
* @example
* await call.createVideoStream()
*/
async createVideoStream(
constraints: MediaTrackConstraints | boolean | undefined,
) {
Expand Down Expand Up @@ -292,6 +343,13 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method createDisplayStream
* @description Create local screen stream and send it to remote peers
* @returns {Promise<void>}
* @example
* await call.createDisplayStream()
*/
async createDisplayStream() {
const screenStream = await navigator.mediaDevices.getDisplayMedia()
if (!this.streams[this.localId]) {
Expand Down Expand Up @@ -390,6 +448,12 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method getTrack
* @description Get the given track from the local or remote stream
* @param trackId
* @returns {MediaStreamTrack} the track
*/
getTrack(trackId: string) {
Object.values(this.tracks).forEach((tracks) => {
tracks.forEach((track) => {
Expand All @@ -401,42 +465,110 @@ export class Call extends Emitter<CallEventListeners> {
return null
}

/**
* @method allRemoteStreams
* @description get all remote streams
* @returns {{ [peerId: string]: { [kind: string]: MediaStream } }}
* @example
* const remoteStreams = call.allRemoteStreams()
*/
allRemoteStreams() {
return Object.keys(this.streams)
.filter((peerId) => peerId !== this.localId)
.map((peerId) => this.streams[peerId])
}

/**
* @method getRemoteStreams
* @description get remote streams of a given type
* @param kind
* @returns {{ [peerId: string]: MediaStream }}
* @example
* const remoteStreams = call.getRemoteStreams('video')
*/
getRemoteStreams(kind: string) {
return Object.keys(this.streams)
.filter((peerId) => peerId !== this.localId)
.map((peerId) => this.streams[peerId]?.[kind])
}

/**
* @method getLocalStreams
* @description get all local streams
* @returns {{ [kind: string]: MediaStream }}
* @example
* const localStreams = call.getLocalStreams()
*/
getLocalStreams() {
return this.streams[this.localId]
}

/**
* @method getLocalStream
* @description get local stream of a given type
* @param kind
* @returns {MediaStream}
* @example
* const localStream = call.getLocalStream('video')
*/
getLocalStream(kind: string) {
return this.streams[this.localId]?.[kind]
}

/**
* @method getPeerStreams
* @description get all streams of a given peer
* @param peerId
* @returns {{ [kind: string]: MediaStream }}
* @example
* const peerStreams = call.getPeerStreams(peerId)
*/
getPeerStreams(peerId: string) {
return this.streams[peerId]
}

/**
* @method getPeerStream
* @description get stream of a given peer and type
* @param peerId
* @param kind
* @returns {MediaStream}
* @example
* const peerStream = call.getPeerStream(peerId, 'video')
*/
getPeerStream(peerId: string, kind: string) {
return this.streams[peerId]?.[kind]
}

/**
* @method hasLocalStream
* @description check if any local stream is available
* @returns {boolean}
* @example
* const hasLocalStream = call.hasLocalStream()
*/
hasLocalStream() {
return Object.entries(this.streams[this.localId] || {}).length > 0
}

/**
* @method hasRemoteStream
* @description check if any remote stream is available
* @returns {boolean}
* @example
* const hasRemoteStream = call.hasRemoteStream()
*/
hasRemoteStream() {
return this.allRemoteStreams().length > 0
}

/**
* @method hasRemoteTracks
* @description check if any remote track is available
* @returns {boolean}
* @example
* const hasRemoteTracks = call.hasRemoteTracks()
*/
hasRemoteTracks() {
return this.getRemoteTracks().length > 0
}
Expand Down Expand Up @@ -665,6 +797,12 @@ export class Call extends Emitter<CallEventListeners> {
this.p2p?.on('peer:destroy', this._onBusDestroy.bind(this))
}

/**
* @method _unbindBusListeners
* @description Internal function to unbind listeners to the communiciationBus events
* @example
* this._unbindBusListeners();
*/
protected _unbindBusListeners() {
this.p2p?.off('peer:signal', this._onBusSignal.bind(this))
this.p2p?.off('peer:refuse', this._onBusRefuse.bind(this))
Expand All @@ -690,6 +828,12 @@ export class Call extends Emitter<CallEventListeners> {
peer.on('close', this._onClose.bind(this, peer))
}

/**
* @method _unbindPeerListeners
* @description Internal function to unbind listeners to the main peer events
* @example
* this._unbindPeerListeners()
*/
protected _unbindPeerListeners(peer: CallPeer) {
peer.removeAllListeners()
}
Expand Down Expand Up @@ -726,12 +870,25 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method send
* @description send some data to connected peers
* @param type
* @param data
* @returns {void}
* @example
* await call.send('foo', 'test')
*/
async send(type: string, data: any) {
Object.values(this.peers).forEach((peer) => {
peer.send({ peerId: this.localId, type, ...data })
Object.values(this.peers).map(async (peer) => {
await peer.send({ peerId: this.localId, type, ...data })
})
}

/**
* @method _onConnect
* @description Callback for the Simple Peer connect event
*/
protected _onConnect(peer: CallPeer) {
this.emit('CONNECTED', {
callId: this.callId,
Expand Down Expand Up @@ -842,6 +999,14 @@ export class Call extends Emitter<CallEventListeners> {
}
}

/**
* @method destroyPeer
* @description Destroy a peer
* @param peerId
* @returns {void}
* @example
* call.destroyPeer('peerId')
*/
destroyPeer(peerId: string) {
if (this.streams[peerId]) {
Object.values(this.streams[peerId]).forEach((stream) => {
Expand Down Expand Up @@ -886,6 +1051,12 @@ export class Call extends Emitter<CallEventListeners> {
this.destroyPeer(peerId.toB58String())
}

/**
* @method _onBusScreenshare
* @description Callback for the on screenshare event
* @param peerId
* @param payload
*/
protected _onBusScreenshare({
peerId,
payload: { streamId },
Expand All @@ -904,6 +1075,10 @@ export class Call extends Emitter<CallEventListeners> {
}
}

/**
* @method _onBusMute
* @description Callback for the on mute event
*/
protected _onBusMute({
peerId,
payload: { kind, trackId },
Expand All @@ -926,6 +1101,10 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method _onBusMute
* @description Callback for the on unmute event
*/
protected _onBusUnmute({
peerId,
payload: { kind, trackId },
Expand All @@ -948,6 +1127,10 @@ export class Call extends Emitter<CallEventListeners> {
)
}

/**
* @method _onBusMute
* @description Callback for the on destroy event
*/
protected _onBusDestroy({ peerId }: { peerId: PeerId }) {
this.destroyPeer(peerId.toB58String())
}
Expand Down
Loading

0 comments on commit 693adf3

Please sign in to comment.