UNPKG

twilio-video

Version:

Twilio Video JavaScript Library

516 lines (455 loc) 16.1 kB
import * as Video from './index'; function customLogging() { const logger = Video.Logger.getLogger('twilio-video'); const originalFactory = logger.methodFactory; logger.methodFactory = function(methodName, logLevel, loggerName) { const method = originalFactory(methodName, logLevel, loggerName); return function(dateTime, logLevel, component, message, data) { method(dateTime, logLevel, component, message, data); }; }; logger.setLevel('debug'); } function getAudioTrack(track: Video.LocalAudioTrack) { let localAudioTrack: Video.LocalAudioTrack = track; localAudioTrack.attach('someEl'); localAudioTrack.detach('someEl'); localAudioTrack = localAudioTrack.disable().enable().stop(); return localAudioTrack; } function getDataTrack(track: Video.LocalDataTrack) { const localDataTrack = track; localDataTrack.send('hello world'); } function makeDataTrack() { const localTrackOptions: Video.LocalDataTrackOptions = { name: 'coolroom', logLevel: 'off' }; const localDataTrack: Video.LocalDataTrack = new Video.LocalDataTrack(localTrackOptions); localDataTrack.send('hello world'); } function getVideoTrack(track: Video.LocalVideoTrack) { const localVideoTrack = track; localVideoTrack.disable(); localVideoTrack.enable(); localVideoTrack.restart(); localVideoTrack.stop(); localVideoTrack.on('disabled', track => { track.detach(); }); localVideoTrack.on('enabled', track => { track.attach(); }); } function remoteVideoTrackPublication(publication: Video.RemoteVideoTrackPublication) { publication.on('subscriptionFailed', error => { throw error; }); publication.on('subscribed', track => { track.attach('someOtherEl'); }); publication.on('trackSwitchedOff', track => { track.detach('someOtherEl'); }); publication.on('unsubscribed', track => { track.detach('someOtherEl'); }); publication.on('s', () => { return 'this should build'; }); } function remoteAudioTrackPublication(publication: Video.RemoteAudioTrackPublication) { const track = publication.track; publication.on('subscriptionFailed', error => { throw error; }); publication.on('subscribed', track => { track.attach('someOtherEl'); track.setPriority('high'); }); publication.on('trackDisabled', () => { if (track) { track.detach('someOtherEl'); } }); publication.on('unsubscribed', track => { track.detach('someOtherEl'); }); publication.on('s', () => { return 'this should build'; }); } function remoteDataTrackPublication(publication: Video.RemoteDataTrackPublication) { const chatLog = document.getElementById('someElementChat'); publication.on('subscribed', track => { track.setPriority('high'); track.on('message', msg => { const textElement = document.createElement('p'); if (chatLog) { textElement.innerText = `${msg}`; chatLog.appendChild(textElement); } }); }); } function localAudioTrackPublication(publication: Video.LocalAudioTrackPublication) { const kind = publication.kind; const track = publication.track; const publicationInfo = { kind, track }; return publicationInfo; } function localVideoTrackPublication(publication: Video.LocalVideoTrackPublication) { const kind = publication.kind; const track = publication.track; const publicationInfo = { kind, track }; return publicationInfo; } function localDataTrackPublication(publication: Video.LocalDataTrackPublication) { const kind = publication.kind; const track = publication.track; const publicationInfo = { kind, track }; return publicationInfo; } function RemoteParticipant(remoteParticipant: Video.RemoteParticipant) { const chatLog = document.getElementById('someElementChat'); const RemoteData = remoteParticipant.dataTracks; const RemoteAudio = remoteParticipant.audioTracks; const sid = remoteParticipant.sid; const testDataTracks = remoteParticipant.dataTracks; remoteParticipant.on('disconnected', remoteParticipant => { return `${remoteParticipant} Has Disconnected`; }); remoteParticipant.on('trackMessage', msg => { const textElement = document.createElement('p'); if (chatLog) { textElement.innerText = `${msg}`; chatLog.appendChild(textElement); } }); remoteParticipant.on('trackDimensionsChanged', videoTrack => { return `${videoTrack} has new track dimensions`; }); remoteParticipant.on('trackDisabled', someTrack => { return `${someTrack} is now disabled`; }); remoteParticipant.on('trackEnabled', someOtherTrack => { return `${someOtherTrack} is now disabled`; }); remoteParticipant.on('trackPublished', publication => { const track = publication.track; return `${track} is now published`; }); remoteParticipant.on('trackPublishPriorityChanged', (trackPriority, remotePublication) => { const remotePublicationPriority = remotePublication.publishPriority; return `${remotePublicationPriority} priorty is now ${trackPriority}`; }); remoteParticipant.on('trackStarted', aTrack => { return `${aTrack} has started`; }); remoteParticipant.on('trackSubscribed', (anotherTrack, anotherPublication) => { const track = anotherTrack.kind; const publicationSid = anotherPublication.trackSid; return `${track} track with ${publicationSid} is subscribed`; }); remoteParticipant.on('trackSubscriptionFailed', (err, publication) => { throw err; }); remoteParticipant.on('trackSwitchedOff', (yetAnotherTrack, yetAnotherPublication) => { const trackName = yetAnotherTrack.name; const publication = yetAnotherPublication.trackName; return `${trackName} is now switched off`; }); remoteParticipant.on('trackSwitchedOn', (yetAnotherTrack, yetAnotherPublication) => { const trackName = yetAnotherTrack.name; const publication = yetAnotherPublication.trackName; return `${trackName} is now switched on`; }); remoteParticipant.on('trackUnpublished', somePublication => { const publicationTrackName = somePublication.trackName; return `${publicationTrackName} is unpublished`; }); remoteParticipant.on('trackUnsubscribed', (anotherTrack, anotherPublication) => { const publicationName = anotherPublication.trackName; return `${anotherTrack.name}, ${publicationName} has been unsubscribed`; }); } function LocalParticipant(localParticipant: Video.LocalParticipant) { const LocalAudioTrack = localParticipant.audioTracks; const LocalDataTracks = localParticipant.dataTracks; const LocalVideoTrack = localParticipant.videoTracks; const LocalTracks = localParticipant.tracks; const signalingRegion = localParticipant.signalingRegion; localParticipant.on('disconnected', participant => { return `${participant.sid} has disconnected from the room`; }); localParticipant.on('trackDimensionsChanged', videoTrack => { return `${videoTrack.name} dimensions have changed`; }); localParticipant.on('trackDisabled', localTrack => { return `Muting ${localTrack.name}`; }); localParticipant.on('trackEnabled', localTrack => { return `Unmute ${localTrack.name}`; }); localParticipant.on('trackPublicationFailed', (error, track) => { return `There was a problem publishing track ${track} with error ${error}`; }); localParticipant.on('trackPublished', publication => { return `Failed to publish ${publication.trackName}`; }); localParticipant.on('trackStarted', track => { return `${track.name} has started`; }); localParticipant.on('trackStopped', track => { return `${track.name} has stopped`; }); } function customWebRTCImplementations() { const customRTCPeerConnection = class extends RTCPeerConnection { constructor(configuration?: RTCConfiguration) { super(configuration); } }; const customRTCConfiguration: RTCConfiguration = { bundlePolicy: 'max-bundle', rtcpMuxPolicy: 'require', }; const getUserMedia = () => { return Promise.resolve(new MediaStream()); }; const enumerateDevices = () => { return Promise.resolve([]); }; const CustomMediaStream = class extends MediaStream { constructor() { super(); } }; function mapMediaElement(element: HTMLMediaElement) { return element; } function disposeMediaElement(element: HTMLMediaElement) { return element; } const localTracks = Video.createLocalTracks({ audio: true, video: true, getUserMedia, enumerateDevices, MediaStream: CustomMediaStream, mapMediaElement, disposeMediaElement }); const localAudioTrack = Video.createLocalAudioTrack({ getUserMedia, enumerateDevices, MediaStream: CustomMediaStream, mapMediaElement, disposeMediaElement }); const localVideoTrack = Video.createLocalVideoTrack({ getUserMedia, enumerateDevices, MediaStream: CustomMediaStream, mapMediaElement, disposeMediaElement }); const room = Video.connect('$TOKEN', { rtcConfiguration: customRTCConfiguration, RTCPeerConnection: customRTCPeerConnection, getUserMedia, enumerateDevices, MediaStream: CustomMediaStream, mapMediaElement, disposeMediaElement }); } let room: Video.Room | null = null; let localVideoTrack: Video.LocalVideoTrack | null = null; let localAudioTrack: Video.LocalAudioTrack | null = null; let localTracks: Video.LocalTrack[] | null = null; // Testing finally method const maybeRoom = Video.connect('$TOKEN', { name: 'room-name', video: false, audio: false }).then(room => { return room; }).catch(err => { throw new Error(err); }).finally(() => { return 'Finally happened!'; }); async function initRoom() { room = await Video.connect('$TOKEN', { name: 'room-name', video: false, audio: false, dominantSpeaker: true, networkQuality: true, region: 'au1', maxAudioBitrate: 500, maxVideoBitrate: 200, bandwidthProfile: { video: { clientTrackSwitchOffControl: 'auto', contentPreferencesMode: 'auto', dominantSpeakerPriority: 'high', renderDimensions: { low: { height: 500, width: null, }, }, trackSwitchOffMode: 'detected', }, }, preferredVideoCodecs: ['VP9', { codec: 'H264' }, { codec: 'VP8' }], }); await Video.connect('$TOKEN', { networkQuality: { local: 3, remote: 1, }, }); // with manual contentPreferencesMode mode. await Video.connect('$TOKEN', { bandwidthProfile: { video: { contentPreferencesMode: 'manual', clientTrackSwitchOffControl: 'manual', } }, }); localVideoTrack = await Video.createLocalVideoTrack({ name: 'camera' }); await localVideoTrack.restart({ facingMode: 'environment' }); localAudioTrack = await Video.createLocalAudioTrack({ name: 'microphone' }); await localAudioTrack.restart({ channelCount: 3 }); room.localParticipant.publishTrack(localAudioTrack); room.participants.forEach(participantConnected); localTracks = await Video.createLocalTracks({ audio: true, video: false }); await Video.createLocalTracks({ audio: true }); await Video.connect('$TOKEN', { name: 'my-cool-room', tracks: localTracks }); room.on('participantConnected', participantConnected); room.on('participantDisconnected', participantDisconnected); room.once('disconnected', (room: Video.Room, error: Video.TwilioError) => { room.participants.forEach(participantDisconnected); room.localParticipant.tracks.forEach((publication: Video.LocalTrackPublication) => { publication.unpublish(); if (publication.track.kind !== 'data') { trackUnsubscribed(publication.track); } }); }); room.on('transcription', (event: Video.TranscriptionEvent) => { // eslint-disable-next-line no-console console.log(`${event.participant}: ${event.transcription}`); }); } function unpublishTracks() { if (room && localVideoTrack) { room.localParticipant.unpublishTrack(localVideoTrack); } if (room && localAudioTrack) { room.localParticipant.unpublishTrack(localAudioTrack); } if (room && localVideoTrack && localAudioTrack) { room.localParticipant.unpublishTracks([localVideoTrack, localAudioTrack]); } } function participantConnected(participant: Video.Participant) { participant.on('trackSubscribed', trackSubscribed); participant.on('trackUnsubscribed', trackUnsubscribed); participant.tracks.forEach(publication => { const remotePublication = publication as Video.RemoteTrackPublication; if (remotePublication.isSubscribed) { trackSubscribed(remotePublication.track as Video.VideoTrack | Video.AudioTrack); } }); } function participantDisconnected(participant: Video.Participant) { participant.tracks.forEach(publication => { const remotePublication = publication as Video.RemoteTrackPublication; if (remotePublication.isSubscribed) { const { track } = remotePublication; if (track) { trackUnsubscribed(track as Video.AudioTrack | Video.VideoTrack); } } }); } function trackSubscribed(track: Video.VideoTrack | Video.AudioTrack) { const media = track.attach(); insertDomElement(media); } function trackUnsubscribed(track: Video.VideoTrack | Video.AudioTrack) { const element = document.createElement(track.kind); track.detach('#foo').remove(); track.detach(element).remove(); track.detach().forEach(element => element.remove()); } function insertDomElement(element: HTMLMediaElement) { document.createElement('div'); element.appendChild(element); } function useConnectionOptions() { const connectionOptions: Video.ConnectOptions = { dominantSpeaker: true, receiveTranscriptions: true, networkQuality: { local: 1, remote: 1 }, maxAudioBitrate: Number('13000'), preferredAudioCodecs: [{ codec: 'opus', dtx: false }], preferredVideoCodecs: [{ codec: 'VP8', simulcast: false }], }; return connectionOptions; } function useAdaptiveSimulcast() { const connectionOptions: Video.ConnectOptions = { preferredVideoCodecs: 'auto', }; } function runPreflight() { const preflight: Video.PreflightTest = Video.runPreflight('token', { region: 'us1' }); preflight.on('completed', (report: Video.PreflightTestReport) => { // eslint-disable-next-line no-console console.log('report ', report); }); preflight.on('failed', (error: Error) => { // eslint-disable-next-line no-console console.log('error ', error); }); preflight.on('progress', (progress: string) => { // eslint-disable-next-line no-console console.log('progress ', progress); }); preflight.stop(); } async function mediaWarnings() { let room = await Video.connect('$TOKEN', { notifyWarnings: [] }); room = await Video.connect('$TOKEN', { notifyWarnings: ['recording-media-lost'] }); room.localParticipant.tracks.forEach((publication: Video.LocalTrackPublication) => { publication.on('warning', (name: string) => { // eslint-disable-next-line no-console console.log(name); }); publication.on('warningsCleared', () => { // eslint-disable-next-line no-console console.log('warningsCleared'); }); }); room.localParticipant.on('trackWarning', (name: string, publication: Video.LocalTrackPublication) => { // eslint-disable-next-line no-console console.log(name, publication); }); room.localParticipant.on('trackWarningsCleared', (publication: Video.LocalTrackPublication) => { // eslint-disable-next-line no-console console.log('warningsCleared', publication); }); room.on('trackWarning', (name: string, publication: Video.LocalTrackPublication, participant: Video.LocalParticipant) => { // eslint-disable-next-line no-console console.log(name, publication, participant); }); room.on('trackWarningsCleared', (publication: Video.LocalTrackPublication, participant: Video.LocalParticipant) => { // eslint-disable-next-line no-console console.log('warningsCleared', publication, participant); }); } initRoom(); unpublishTracks(); runPreflight(); mediaWarnings();