import AgoraRTC, { ILocalAudioTrack, ILocalVideoTrack } from "agora-rtc-sdk-ng"; import { ShareScreenAction } from "../action/ShareScreenAction"; import { ActionParams } from "../action/type/ActionParams"; import { RegionChangeActionParams } from "../action/type/RegionChangeActionParams"; import { ShareScreenActionParams } from "../action/type/ShareScreenActionParams"; import { Context } from "../context/Context"; import { DeviceT } from "../context/type/DeviceT"; import { CustomError } from "../exception/CustomError"; import { ErrorType } from "../exception/enum/ErrorType"; import { setAction } from "../store/slices/action"; import { BaseOperation } from "./base/BaseOperation"; import { EOperationStatus } from "./enum/EOperationStatus"; import { EOperationType } from "./enum/EOperationType"; import { IOperation } from "./interface/IOperation"; export class PublishTracksOperation extends BaseOperation implements IOperation { constructor(context: Context){ super(context); this.type=EOperationType.PUBLISH_TRACKS; } /*@overwrite*/ public async handler(params ? : ActionParams) : Promise{ return new Promise( async (resolve, reject)=>{ try { this.context.getDeterminants().setUpdating(true); let tracks : Array = []; let regionChangeActionParams : RegionChangeActionParams = Object.assign(params ? params : {}); if(regionChangeActionParams.keepTracks==false){ this.context.getDeterminants().setHasCamera(false); this.context.getDeterminants().setHasScreen(false); } if(this.context.getDeterminants().getHasAudio()){ let audioTrack : ILocalAudioTrack = await this.context.getResources().getAudioTrack(); if(audioTrack == undefined || audioTrack == null){ let microphones = await this.context.getResources().getMicrophones(); let microphone : DeviceT = Object.assign(this.context.getDeterminants().getMicrophoneSelected() ? this.context.getDeterminants().getMicrophoneSelected() : microphones && microphones.length > 0 ? microphones[0] : {}); this.context.getDeterminants().setMicrophoneSelected(microphone); let speakers = await this.context.getResources().getSpeakers(); let speaker : DeviceT = Object.assign(this.context.getDeterminants().getPlayBackSelected() ? this.context.getDeterminants().getPlayBackSelected() : speakers && speakers.length > 0 ? speakers[0] : {}); this.context.getDeterminants().setPlayBackSelected(speaker); audioTrack = await this.context.getResources().createAudioTrack(microphone); } await audioTrack.setEnabled(true); tracks.push(audioTrack); } if(this.context.getDeterminants().getHasCamera()){ let cameraTrack : ILocalVideoTrack = await this.context.getResources().getVideoTrack(); if(cameraTrack == undefined || cameraTrack == null){ let cameras = await this.context.getResources().getCameras(); let camera : DeviceT = Object.assign(this.context.getDeterminants().getCameraSelected() ? this.context.getDeterminants().getCameraSelected() : cameras && cameras.length > 0 ? cameras[0] : {}); this.context.getDeterminants().setCameraSelected(camera); cameraTrack = await this.context.getResources().createVideoTrack(camera); } await cameraTrack.setEnabled(true); tracks.push(cameraTrack); } if(this.context.getDeterminants().getHasScreen()){ let screenTrack : ILocalVideoTrack = await this.context.getResources().createScreenTrack(); screenTrack.on("track-ended", async () => { await client.unpublish(this.context.getResources().getScreeanTrack()); await this.context.getDeterminants().setHasScreen(false); if(this.context.getDeterminants().getActionDispatch()){ let params : ShareScreenActionParams = {active: false}; let action = new ShareScreenAction(params); this.context.getDeterminants().getActionDispatch()(setAction({action: action})); } }); tracks.push(screenTrack); } let client = this.context.getResources().getClient(); if(tracks.length > 0){ await client.publish(tracks); this.status = EOperationStatus.PERFORMED; }else{ this.addError(new CustomError(ErrorType.BUSINESS, "Cannot publish track", "Cannot publish track, because no stream tracks were found")); this.status = EOperationStatus.FAILED; } } catch (error) { this.addError(error); this.status = EOperationStatus.FAILED; } resolve(this.status); }); } }