UNPKG

janky

Version:

Janus Interface

240 lines (218 loc) 7.32 kB
import { JanusJS } from "janus-gateway"; import LocalRTC from "../repositories/LocalRTC"; import { ParticipantType, WhatToPublish } from "../types"; import eventEmitter from "../repositories/eventEmitter"; import { LOCAL_EVENTS } from "../events"; interface CaptureByID { deviceId: { exact: string} } interface OfferTrackType { type: 'audio' | 'video' | 'screen'; capture: boolean | 'screen' | CaptureByID; recv: false; simulcast?: boolean; svc?: null, } type MobileFacingMode = 'user' | 'environment'; interface MediaMobileVideo { facingMode: { exact: MobileFacingMode } } interface MediaConstraints { audio: boolean; video: boolean | MediaMobileVideo } class Publisher { public localStream: MediaStream | undefined; constructor( protected type: ParticipantType, private readonly handler: JanusJS.PluginHandle, private publishType: WhatToPublish ) {} public setMobileFacingMode (facingMode: MobileFacingMode): void { window.localStorage.setItem('mobile-camera-facing-mode', facingMode); } public getMobileFacingMode (): MobileFacingMode { return (window.localStorage.getItem('mobile-camera-facing-mode') || 'user') as MobileFacingMode; } public async doOffering(): Promise<void> { const jsep = await this.generateOffer(); this.sendJsep(jsep); } public unpublish(): Promise<void> { return new Promise<void>((resolves: () => void) => { this.handler.send({ message: { request: 'unpublish', }, success: () => { resolves(); } }); // clearing data (unset) eventEmitter.emit(LOCAL_EVENTS.NULL_STREAM); LocalRTC.setStream(null); LocalRTC.setIDs(undefined, undefined); // undefined to make it obvious we are cleaning the old data here }) } private generateOffer(): Promise<JanusJS.JSEP> { return new Promise<JanusJS.JSEP>((resolves: (jsep: JanusJS.JSEP) => void, rejects: (reason: string)=> void ) => { const tracks: OfferTrackType[] = this.mapTypeToTracks(); this.handler.createOffer({ tracks, iceRestart: true, trickle: true, success: async (jsep: JanusJS.JSEP) => { await this.sendPublishCommand(jsep); resolves(jsep); }, error: (error: string) => { console.log('Error On Creating Offer', error); rejects(error) } } as JanusJS.OfferParams); }); } private mapTypeToCommand(): MediaConstraints { switch(this.publishType) { case "audio": return {audio: true, video: false}; case "video": return {audio: true, video: true}; case "video_environment": return { audio: true, video: { facingMode: { exact: 'environment' } } }; case "video_user": return { audio: true, video: { facingMode: { exact: 'user' } } }; case 'screen': return { audio: true, video: true }; default: return {audio: false, video: false}; } } public switchByType(publishType: WhatToPublish): Promise<void> { return new Promise<void>((resolves: () => void, rejects: (reason: string) => void) => { this.publishType = publishType; const tracks = this.mapTypeToTracks(); this.handler.replaceTracks({ tracks: tracks as unknown as JanusJS.TrackOption[], success: () => resolves(), error: err => rejects(err) }); }); } public switchByDevice( audioDeviceId: string | undefined, videoDeviceId: string | undefined ) { const tracks: OfferTrackType[] = []; if(audioDeviceId) { tracks.push({ type: 'audio', capture: { deviceId: { exact: audioDeviceId } }, recv: false }); } if(videoDeviceId) { tracks.push({ type: 'video', capture: { deviceId: { exact: videoDeviceId } }, recv: false }); } } private mapTypeToTracks() { const tracks: OfferTrackType[] = []; const addAudio = ['video_environment', 'video_user', 'video', 'screen', 'audio']; const addVideo = ['video_environment', 'video_user', 'video']; if(addAudio.includes(this.publishType)) { tracks.push({ recv: false, type: 'audio', capture: true }); } if(addVideo.includes(this.publishType)) { tracks.push({ type: 'video', capture: true, simulcast: true, svc: null, recv: false, }); } if(this.publishType === 'screen') { tracks.push({ type: 'screen', capture: true, recv: false }); } return tracks; } private sendPublishCommand(jsep: JanusJS.JSEP): Promise<void> { return new Promise<void>((resolves,rejects) => { const mediaConstraints: MediaConstraints = this.mapTypeToCommand(); const message = { request: "publish", ...mediaConstraints }; this.handler.send({ message, jsep, success: data => { if(data && data.error) { console.log(data.error); rejects(data.error); return; } resolves(); }, error: err => { console.log(err); rejects(err); } }); }); } private sendJsep(jsep: JanusJS.JSEP): Promise<void> { return new Promise<void>((resolves, rejects) => { const message = { request: "configure", audio: true, video: true }; // TO BE CHANGED this.handler.send({ message, "jsep": jsep, success: (res) => { if(res && res.error) { rejects(res.error); return; } resolves(); } }); }); } // private mapTypeToConstraints () { // switch(this.type) { // case 'publisher_audio': // return { // }; // case 'publisher_back': // return { // }; // case 'publisher_front': // return { // } // } // } }; export default Publisher;