import { AzureCommunicationTokenCredential, createIdentifierFromRawId } from '@azure/communication-common'; import { CallClient, LocalVideoStream, VideoStreamRenderer } from '@azure/communication-calling'; class VideoCall { constructor() { //this.isLocalVideoStartedChangedCallback = null; //this.localVideoStreamsUpdatedCallback = null; //this.onCreateLocalVideoStreamCallback = null; this.onGetServerCallIDCallback = null; //this.remoteParticipantStateChangedCallback = null; //this.remoteParticipantsUpdatedCallback = null; //this.remoteVideoIsAvailableChangedCallback = null; this.stateChangedCallback = null; this.callEndedCallback = null; this.participantsJoinedCallback = null; this.callsUpdatedCallback = null; this.callAdapter = null; this.videoContainer = null; this.displayName = null; this.roomID = null; this.token = null; this.userID = null; this.onFetchParticipantMenuItemsCallback = null; this.onFetchCustomButtonPropsCallbacks = []; this.onAddParticipantCallback = null; } async init(options) { let self = this; this.stateChangedCallback = options.stateChangedCallback; /*this.remoteParticipantsUpdatedCallback = options.remoteParticipantsUpdated;*/ /*this.isLocalVideoStartedChangedCallback = options.isLocalVideoStartedChanged;*/ /*this.localVideoStreamsUpdatedCallback = options.localVideoStreamsUpdated;*/ this.idChangedCallback = options.idChanged; //this.onCreateLocalVideoStreamCallback = options.onCreateLocalVideoStream; //this.remoteParticipantStateChangedCallback = options.remoteParticipantStateChanged; //this.remoteVideoIsAvailableChangedCallback = options.remoteVideoIsAvailableChanged; this.onGetServerCallIDCallback = options.onGetServerCallIDCallback; this.callEndedCallback = options.callEndedCallback; this.participantsJoinedCallback = options.participantsJoinedCallback; this.onFetchParticipantMenuItemsCallback = options.onFetchParticipantMenuItemsCallback; this.onFetchCustomButtonPropsCallbacks = options.onFetchCustomButtonPropsCallbacks || []; this.onAddParticipantCallback = options.onAddParticipantCallback; this.callAdapter = options.callAdapter; this.videoContainer = options.videoContainer; this.displayName = options.displayName; this.roomID = options.roomID; this.token = options.token; this.userID = options.userID; this.serverCallId; const callControls = { // Hide all default buttons cameraButton: true, endCallButton: false, microphoneButton: false, participantsButton: true, screenShareButton: false, devicesButton: false, moreButton: false, raiseHandButton: false, reactionButton: false, dtmfDialerButton: false, holdButton: false, peopleButton: false, exitSpotlightButton: false, captionsButton: false, galleryControlsButton: false, teamsMeetingPhoneCallButton: false, displayType: 'compact', // Hide the entire control bar if needed onFetchCustomButtonProps: this.onFetchCustomButtonPropsCallbacks }; const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); const callCompositeProps = { callControls: callControls, formFactor: isMobile ? 'mobile' : 'desktop', onFetchParticipantMenuItems: this.onFetchParticipantMenuItemsCallback, options: { callControls: callControls } }; const adapterArgs = { userId: createIdentifierFromRawId(this.userID), //credential: new AzureCommunicationTokenCredential(this.token), token: this.token, displayName: this.displayName, locator: { roomId: this.roomID }, callAdapterOptions: {}, callCompositeOptions: callCompositeProps }; this.callAdapter = await callComposite.loadCallComposite( adapterArgs, this.videoContainer, // container element, callCompositeProps ); //this.callAdapter.callAgent.on("callsUpdated", function (e) { // e.added.forEach((addedCall) => { // addedCall.on('stateChanged', (state) => this.stateChanged(addedCall)); // }); //}); this.callAdapter.on("callIdChanged", function (e) { }); this.callAdapter.onStateChange(state => { if (state.call?.info && !this.serverCallId) { state.call.info.getServerCallId().then(result => { this.serverCallId = result; this.onGetServerCallIDCallback?.(result); }).catch(err => { console.log(err); }); } }); this.callAdapter.on("callEnded", function (e) { self.callEndedCallback?.(e); }); this.callAdapter.on("participantsJoined", function (e, f) { self.participantsJoinedCallback?.(e, f); }); this.callAdapter.on("onAddParticipant", function (e, f) { self.onAddParticipantCallback?.(e, f); }); //CallEnded return this.callAdapter; } //stopLocalVideo() { // if (this.call) { // this.call.stopVideo(this.localVideoStream); // } //} async joinRoom() { await this.callAdapter?.joinCall({ microphoneOn: true, cameraOn: true }); } async stopCall(forEveryone = false) { await this.callAdapter?.leaveCall(forEveryone); } //async subscribeToCall(call) { // try { // call.on('idChanged', () => { // this.idChanged?.(call.id); // }); // call.on('stateChanged', async () => { // this.stateChangedCallback?.(call.state); // }); // call.on('isLocalVideoStartedChanged', () => { // this.isLocalVideoStartedChanged?.(call.isLocalVideoStarted); // }); // call.on('localVideoStreamsUpdated', e => { // this.localVideoStreamsUpdated?.(e); // }); // // Subscribe to the call's 'remoteParticipantsUpdated' event to be // // notified when new participants are added to the call or removed from the call. // call.on('remoteParticipantsUpdated', e => { // this.remoteParticipantsUpdated?.(e); // e.added.forEach(remoteParticipant => { // this.subscribeToRemoteParticipant(remoteParticipant) // }); // // Unsubscribe from participants that are removed from the call // e.removed.forEach(remoteParticipant => { // console.log('Remote participant removed from the call.'); // }); // }); // call.localVideoStreams.forEach(async (lvs) => { // this.localVideoStream = lvs; // await this.displayLocalVideoStream(lvs); // }); // // Inspect the call's current remote participants and subscribe to them. // call.remoteParticipants.forEach(remoteParticipant => { // this.subscribeToRemoteParticipant(remoteParticipant); // }); // } catch (error) { // console.error(error); // } //} //subscribeToRemoteParticipant(remoteParticipant) { // try { // // Inspect the initial remoteParticipant.state value. // console.log(`Remote participant state: ${remoteParticipant.state}`); // // Subscribe to remoteParticipant's 'stateChanged' event for value changes. // remoteParticipant.on('stateChanged', () => { // console.log(`Remote participant state changed: ${remoteParticipant.state}`, JSON.stringify(remoteParticipant)); // this.remoteParticipantStateChanged?.(remoteParticipant.state); // }); // // Inspect the remoteParticipants's current videoStreams and subscribe to them. // remoteParticipant.videoStreams.forEach(remoteVideoStream => { // this.subscribeToRemoteVideoStream(remoteVideoStream); // }); // // Subscribe to the remoteParticipant's 'videoStreamsUpdated' event to be // // notified when the remoteParticipant adds new videoStreams and removes video streams. // remoteParticipant.on('videoStreamsUpdated', e => { // // Subscribe to new remote participant's video streams that were added. // e.added.forEach(remoteVideoStream => { // this.subscribeToRemoteVideoStream(remoteVideoStream); // }); // // Unsubscribe from remote participant's video streams that were removed. // e.removed.forEach(remoteVideoStream => { // console.log('Remote participant video stream was removed.'); // }) // }); // } catch (error) { // console.error(error); // } //} //async subscribeToRemoteVideoStream(remoteVideoStream) { // let renderer = new VideoStreamRenderer(remoteVideoStream); // let view; // const createView = async () => { // // Create a renderer view for the remote video stream. // view = await renderer.createView(); // this.remoteVideoIsAvailableChanged?.({ // isAvailable: remoteVideoStream.isAvailable, // participantId: remoteVideoStream.tsParticipantId, // el: view.target // }); // } // // Remote participant has switched video on/off // remoteVideoStream.on('isAvailableChanged', async () => { // try { // if (remoteVideoStream.isAvailable) { // await createView(); // } else { // view?.dispose(); // } // } catch (e) { // console.error(e); // } // }); // // Remote participant has video on initially. // if (remoteVideoStream.isAvailable) { // try { // await createView(); // } catch (e) { // console.error(e); // } // } //} //async createLocalVideoStream() { // const camera = (await this.deviceManager.getCameras())[0]; // if (camera) { // return new LocalVideoStream(camera); // } else { // console.error(`No camera device found on the system`); // } //} leaveRoom() { if (this.call) { this.call.hangUp(); } } //createIdentifierFromRawId(rawId) { // return createIdentifierFromRawId(rawId); //} //async displayLocalVideoStream(lvs) { // try { // let localVideoStreamRenderer = new VideoStreamRenderer(lvs); // const view = await localVideoStreamRenderer.createView(); // this.onCreateLocalVideoStream?.(view.target); // } catch (error) { // console.error(error); // } //} } export default VideoCall;