Change-Id: Iaf1aa61fb0d5f7e0fe6ef4c427911a50933a09b8changes/25/16525/5
parent
a5d6d1bfb8
commit
6ab38fcbb7
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,211 @@
|
|||||||
|
<template>
|
||||||
|
<div class="csc-call">
|
||||||
|
|
||||||
|
<q-card flat color="secondary">
|
||||||
|
<q-card-title>
|
||||||
|
<q-icon v-if="isCalling && getMediaType == 'audioOnly'" name="mic" color="primary" size="26px"/>
|
||||||
|
<q-icon v-else-if="isCalling && getMediaType == 'audioVideo'" name="videocam" color="primary" size="26px"/>
|
||||||
|
<q-icon v-else-if="isEnded" name="error" color="primary" size="26px"/>
|
||||||
|
<q-icon v-else name="call made" color="primary" size="26px"/>
|
||||||
|
|
||||||
|
<span v-if="isPreparing" class="text">{{ $t('call.startNew') }}</span>
|
||||||
|
<span v-else-if="isInitiating" class="text">{{ $t('call.initiating') }}</span>
|
||||||
|
<span v-else-if="isRinging" class="text">{{ $t('call.ringing') }}</span>
|
||||||
|
<span v-else-if="isEnded" class="text">{{ $t('call.ended') }}</span>
|
||||||
|
<span v-else class="text">{{ $t('call.call') }}</span>
|
||||||
|
|
||||||
|
<q-btn round small slot="right" class="no-shadow" @click="close()" icon="clear"/>
|
||||||
|
</q-card-title>
|
||||||
|
<q-card-main>
|
||||||
|
<div v-if="isTrying" class="csc-spinner"><q-spinner-rings color="primary" :size="60" /></div>
|
||||||
|
<div v-if="isCalling" class="phone-number">{{ getNumber }}</div>
|
||||||
|
<csc-media v-if="isCalling && localMediaStream != null" :stream="localMediaStream" />
|
||||||
|
<q-field v-if="isPreparing" :helper="$t('call.inputNumber')" :error="validationEnabled && phoneNumberError"
|
||||||
|
:error-label="$t('call.inputValidNumber')" :count="64" dark>
|
||||||
|
<q-input :float-label="$t('call.number')" v-model="formattedPhoneNumber" dark clearable max="64"
|
||||||
|
@blur="phoneNumberBlur()" @focus="phoneNumberFocus()"/>
|
||||||
|
</q-field>
|
||||||
|
<div v-if="isEnded" class="ended-reason">
|
||||||
|
{{ getEndedReason }}
|
||||||
|
</div>
|
||||||
|
</q-card-main>
|
||||||
|
<q-card-actions align="center">
|
||||||
|
<q-btn v-if="isPreparing" round small color="primary" @click="call('audioOnly')" icon="mic" />
|
||||||
|
<q-btn v-if="isPreparing" round small color="primary" @click="call('audioVideo')" icon="videocam" />
|
||||||
|
<q-btn v-if="isCalling" round small color="negative" @click="hangUp()" icon="call end" />
|
||||||
|
<q-btn v-if="isEnded" round small color="negative" @click="init()" icon="clear"/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { mapState, mapGetters } from 'vuex'
|
||||||
|
import CscMedia from './CscMedia'
|
||||||
|
import { QLayout, QCard, QCardTitle, QCardSeparator, QCardMain, QField, QInput,
|
||||||
|
QCardActions, QBtn, QIcon, Loading, Alert, QSpinnerRings } from 'quasar-framework'
|
||||||
|
import { PhoneNumberUtil, PhoneNumberFormat } from 'google-libphonenumber'
|
||||||
|
var phoneUtil = PhoneNumberUtil.getInstance();
|
||||||
|
export default {
|
||||||
|
name: 'csc-call',
|
||||||
|
props: ['region'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
phoneNumber: '',
|
||||||
|
parsedPhoneNumber: null,
|
||||||
|
phoneNumberError: false,
|
||||||
|
validationEnabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
QLayout,
|
||||||
|
QCard,
|
||||||
|
QCardTitle,
|
||||||
|
QCardSeparator,
|
||||||
|
QCardMain,
|
||||||
|
QField,
|
||||||
|
QInput,
|
||||||
|
QCardActions,
|
||||||
|
QBtn,
|
||||||
|
QIcon,
|
||||||
|
QSpinnerRings,
|
||||||
|
CscMedia
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.phoneNumber = '';
|
||||||
|
this.parsedPhoneNumber = null;
|
||||||
|
this.validationEnabled = false;
|
||||||
|
this.phoneNumberError = false;
|
||||||
|
this.$store.commit('call/inputNumber');
|
||||||
|
},
|
||||||
|
phoneNumberFocus() {
|
||||||
|
this.validationEnabled = true;
|
||||||
|
},
|
||||||
|
phoneNumberBlur() {
|
||||||
|
this.validationEnabled = false;
|
||||||
|
},
|
||||||
|
call(localMedia) {
|
||||||
|
this.validationEnabled = true;
|
||||||
|
if(this.parsedPhoneNumber !== null) {
|
||||||
|
this.phoneNumberError = false;
|
||||||
|
this.$store.dispatch('call/start', {
|
||||||
|
number: this.phoneNumber,
|
||||||
|
localMedia: localMedia
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.phoneNumberError = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hangUp() {
|
||||||
|
this.$store.dispatch('call/hangUp');
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.$store.commit('call/inputNumber');
|
||||||
|
this.$emit('close');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
formattedPhoneNumber: {
|
||||||
|
get() {
|
||||||
|
if(this.parsedPhoneNumber !== null) {
|
||||||
|
return _.trim(phoneUtil.format(this.parsedPhoneNumber, PhoneNumberFormat.INTERNATIONAL));
|
||||||
|
} else {
|
||||||
|
return _.trim(this.phoneNumber);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.validationEnabled = true;
|
||||||
|
this.phoneNumber = _.trim(value);
|
||||||
|
if(this.phoneNumber.match('^[1-9]')) {
|
||||||
|
this.phoneNumber = '+' + this.phoneNumber;
|
||||||
|
} else if(this.phoneNumber === '+') {
|
||||||
|
this.phoneNumber = '';
|
||||||
|
}
|
||||||
|
if(phoneUtil.isPossibleNumberString(this.phoneNumber, this.region)) {
|
||||||
|
try {
|
||||||
|
this.parsedPhoneNumber = phoneUtil.parse(this.phoneNumber, this.region);
|
||||||
|
this.phoneNumber = phoneUtil.format(this.parsedPhoneNumber, PhoneNumberFormat.E164);
|
||||||
|
this.phoneNumberError = false;
|
||||||
|
} catch(err) {
|
||||||
|
this.parsedPhoneNumber = null;
|
||||||
|
this.phoneNumberError = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.parsedPhoneNumber = null;
|
||||||
|
this.phoneNumberError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
localMediaStream() {
|
||||||
|
if(this.$store.state.call.localMediaStream != null) {
|
||||||
|
return this.$store.state.call.localMediaStream.getStream();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remoteMediaStream() {
|
||||||
|
console.log(this.$refs.remoteMedia);
|
||||||
|
},
|
||||||
|
...mapGetters('call', [
|
||||||
|
'isPreparing',
|
||||||
|
'isInitiating',
|
||||||
|
'isTrying',
|
||||||
|
'isRinging',
|
||||||
|
'isCalling',
|
||||||
|
'isEnded',
|
||||||
|
'getNumber',
|
||||||
|
'getMediaType',
|
||||||
|
'getLocalMediaType',
|
||||||
|
'getEndedReason'
|
||||||
|
]),
|
||||||
|
hasLocalVideo() {
|
||||||
|
return this.getLocalMediaType !== null && this.getLocalMediaType.match(/(v|V)ideo/) !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
.csc-call .q-card {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csc-call .q-card-main {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csc-call .q-field {
|
||||||
|
margin: 0px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csc-call .q-card-actions {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csc-spinner {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-card-title .text {
|
||||||
|
color: #adb3b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csc-call .phone-number {
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
color: #adb3b8;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csc-call .ended-reason {
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
color: #adb3b8;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<div class="csc-media">
|
||||||
|
<video ref="media"></video>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import _ from 'lodash';
|
||||||
|
export default {
|
||||||
|
name: 'csc-media',
|
||||||
|
props: ['stream'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
currentStream: this.stream
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if(_.isObject(this.currentStream) && _.isObject(this.$refs.media) &&
|
||||||
|
!_.isUndefined(this.$refs.media.srcObject)) {
|
||||||
|
this.$refs.media.srcObject = this.currentStream;
|
||||||
|
} else if(_.isObject(this.currentStream) && _.isObject(this.$refs.media) &&
|
||||||
|
!_.isUndefined(this.$refs.media.mozSrcObject)) {
|
||||||
|
this.$refs.media.mozSrcObject = this.currentStream;
|
||||||
|
} else if(_.isObject(this.currentStream) && _.isObject(this.$refs.media) &&
|
||||||
|
_.isObject(URL) && _.isFunction(URL.createObjectURL)) {
|
||||||
|
this.$refs.media.src = URL.createObjectURL(this.currentStream);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
methods: {},
|
||||||
|
computed: {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
.csc-media {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
.csc-media video {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,154 @@
|
|||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { loadCdkLib, connectDefaultCdkNetwork } from '../helpers/cdk-lib';
|
||||||
|
import { createSessionToken } from '../api/rtcsession';
|
||||||
|
|
||||||
|
export const LocalMedia = {
|
||||||
|
audioOnly: 'audioOnly',
|
||||||
|
audioVideo: 'audioVideo',
|
||||||
|
videoOnly: 'videoOnly',
|
||||||
|
audioScreen: 'audioScreen',
|
||||||
|
screenOnly: 'screenOnly'
|
||||||
|
};
|
||||||
|
|
||||||
|
export class NetworkNotConnected extends Error {
|
||||||
|
|
||||||
|
constructor(network) {
|
||||||
|
super();
|
||||||
|
this.name = this.constructor.name;
|
||||||
|
this.message = 'Network ' + network + ' is not connected';
|
||||||
|
this.network = network;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var rtcEngineCallInstance = null;
|
||||||
|
export class RtcEngineCall {
|
||||||
|
|
||||||
|
constructor(options) {
|
||||||
|
this.networkTag = 'sip';
|
||||||
|
this.client = null;
|
||||||
|
this.network = null;
|
||||||
|
this.currentCall = null;
|
||||||
|
this.loadedLibrary = null;
|
||||||
|
this.sessionToken = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
Promise.resolve().then(($loadedLibrary)=>{
|
||||||
|
this.loadedLibrary = $loadedLibrary;
|
||||||
|
return this.loadLibrary();
|
||||||
|
}).then(()=>{
|
||||||
|
return this.createSession();
|
||||||
|
}).then(($sessionToken)=>{
|
||||||
|
this.sessionToken = $sessionToken;
|
||||||
|
return this.connectNetwork($sessionToken);
|
||||||
|
}).then(($network)=>{
|
||||||
|
this.network = $network;
|
||||||
|
resolve();
|
||||||
|
}).catch((err)=>{
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isAvailable() {
|
||||||
|
return this.network !== null && this.network.isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasRunningCall() {
|
||||||
|
return this.currentCall !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadLibrary() {
|
||||||
|
return loadCdkLib();
|
||||||
|
}
|
||||||
|
|
||||||
|
createSession() {
|
||||||
|
return createSessionToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
connectNetwork(session) {
|
||||||
|
return connectDefaultCdkNetwork(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
createLocalMedia(localMedia) {
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
var localMediaStream = new cdk.LocalMediaStream();
|
||||||
|
var hasAudio = localMedia === LocalMedia.audioOnly ||
|
||||||
|
localMedia === LocalMedia.audioVideo ||
|
||||||
|
localMedia === LocalMedia.audioScreen;
|
||||||
|
var hasVideo = localMedia === LocalMedia.audioVideo ||
|
||||||
|
localMedia === LocalMedia.videoOnly;
|
||||||
|
var hasScreen = localMedia === LocalMedia.audioScreen ||
|
||||||
|
localMedia === LocalMedia.screenOnly;
|
||||||
|
|
||||||
|
localMediaStream.queryMediaSources((sources) => {
|
||||||
|
if (hasAudio && _.isObject(sources.defaultAudio)) {
|
||||||
|
localMediaStream.setAudio(sources.defaultAudio);
|
||||||
|
}
|
||||||
|
if (hasVideo && _.isObject(sources.defaultVideo)) {
|
||||||
|
localMediaStream.setVideo(sources.defaultVideo);
|
||||||
|
} else if (hasScreen && _.isObject(sources.desktopSharing)) {
|
||||||
|
localMediaStream.setVideo(sources.desktopSharing);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
localMediaStream.build((err)=>{
|
||||||
|
if(_.isObject(err)) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(localMediaStream);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
start(peer, localMediaStream) {
|
||||||
|
peer = peer.replace('+', '');
|
||||||
|
if(this.network !== null) {
|
||||||
|
this.currentCall = this.network.call(peer, { localMediaStream: localMediaStream });
|
||||||
|
return this.currentCall;
|
||||||
|
} else {
|
||||||
|
throw new NetworkNotConnected(this.networkTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onIncoming(listener) {
|
||||||
|
if(this.network !== null) {
|
||||||
|
this.network.onIncomingCall((call)=>{
|
||||||
|
if(this.currentCall === null) {
|
||||||
|
this.currentCall = call;
|
||||||
|
listener(call);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new NetworkNotConnected(this.networkTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accept(localMediaStream) {
|
||||||
|
if(this.currentCall !== null) {
|
||||||
|
this.currentCall.accept({
|
||||||
|
localMediaStream: localMediaStream
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hangUp() {
|
||||||
|
if(this.currentCall !== null) {
|
||||||
|
this.currentCall.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getInstance() {
|
||||||
|
if(rtcEngineCallInstance === null) {
|
||||||
|
rtcEngineCallInstance = new RtcEngineCall();
|
||||||
|
}
|
||||||
|
return rtcEngineCallInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static install(Vue, options) {
|
||||||
|
Vue.call = RtcEngineCall.getInstance();
|
||||||
|
}
|
||||||
|
}
|
@ -1,98 +1,213 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { loadCdkLib, connectDefaultCdkNetwork } from '../helpers/cdk-lib';
|
// import { loadCdkLib, connectDefaultCdkNetwork } from '../helpers/cdk-lib';
|
||||||
import { createSessionToken } from '../api/rtcsession';
|
// import { createSessionToken } from '../api/rtcsession';
|
||||||
|
|
||||||
var cdkNetwork = null;
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export var CallState = {
|
||||||
|
input: 'input',
|
||||||
|
initiating: 'initiating',
|
||||||
|
ringing: 'ringing',
|
||||||
|
incoming: 'incoming',
|
||||||
|
established: 'established',
|
||||||
|
ended: 'ended'
|
||||||
|
};
|
||||||
|
|
||||||
|
export var MediaType = {
|
||||||
|
audio: 'audio',
|
||||||
|
audioVideo: 'audioVideo',
|
||||||
|
audioScreen: 'audioScreen'
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: {
|
state: {
|
||||||
loaded: false,
|
initialized: false,
|
||||||
initFailure: false,
|
initError: null,
|
||||||
connected: false,
|
endedReason: null,
|
||||||
disconnectReason: '',
|
callState: CallState.input,
|
||||||
incoming: false,
|
number: null,
|
||||||
incomingNumber: '',
|
mediaType: null,
|
||||||
outgoing: false,
|
localMediaType: null,
|
||||||
outgoingNumber: ''
|
localMediaStream: null,
|
||||||
|
remoteMediaStream: null
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
|
getNumber(state, getters) {
|
||||||
|
return state.number;
|
||||||
|
},
|
||||||
|
getMediaType(state, getters) {
|
||||||
|
return state.mediaType;
|
||||||
|
},
|
||||||
|
getLocalMediaType(state, getters) {
|
||||||
|
return state.localMediaType
|
||||||
|
},
|
||||||
|
getEndedReason(state, getters) {
|
||||||
|
return state.endedReason;
|
||||||
|
},
|
||||||
|
isNetworkConnected(state, getters) {
|
||||||
|
return state.initialized;
|
||||||
|
},
|
||||||
isCallAvailable(state, getters) {
|
isCallAvailable(state, getters) {
|
||||||
return state.loaded && state.connected;
|
return getters.isNetworkConnected;
|
||||||
},
|
},
|
||||||
hasCallInitFailure(state, getters) {
|
hasCallInitFailure(state, getters) {
|
||||||
return state.initFailure;
|
return state.initError !== null;
|
||||||
|
},
|
||||||
|
isPreparing(state, getters) {
|
||||||
|
return state.callState === CallState.input;
|
||||||
|
},
|
||||||
|
isInitiating(state, getters) {
|
||||||
|
return state.callState === CallState.initiating;
|
||||||
|
},
|
||||||
|
isTrying(state, getters) {
|
||||||
|
return state.callState === CallState.initiating ||
|
||||||
|
state.callState === CallState.ringing;
|
||||||
|
},
|
||||||
|
isRinging(state, getters) {
|
||||||
|
return state.callState === CallState.ringing;
|
||||||
|
},
|
||||||
|
isCalling(state, getters) {
|
||||||
|
return state.callState === CallState.initiating ||
|
||||||
|
state.callState === CallState.ringing ||
|
||||||
|
state.callState === CallState.established;
|
||||||
|
},
|
||||||
|
isEnded(state, getters) {
|
||||||
|
return state.callState === CallState.ended;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
load(state) {
|
initSucceeded(state) {
|
||||||
state.loaded = true;
|
state.initialized = true;
|
||||||
|
state.initError = null;
|
||||||
},
|
},
|
||||||
initFailure(state) {
|
initFailed(state, err) {
|
||||||
state.initFailure = true;
|
state.initialized = false;
|
||||||
|
state.initError = err;
|
||||||
},
|
},
|
||||||
connect(state) {
|
inputNumber(state) {
|
||||||
state.connected = true;
|
state.callState = CallState.input;
|
||||||
},
|
},
|
||||||
disconnect(state, reason) {
|
startCalling(state, options) {
|
||||||
state.connected = false;
|
state.number = options.number;
|
||||||
state.disconnectReason = reason;
|
state.mediaType = options.mediaType;
|
||||||
|
state.localMediaType = state.mediaType;
|
||||||
|
state.localMediaStream = options.localMediaStream;
|
||||||
|
state.callState = CallState.initiating;
|
||||||
},
|
},
|
||||||
incoming(state) {
|
acceptIncoming(state, options) {
|
||||||
|
state.localMediaStream = options.localMediaStream;
|
||||||
},
|
},
|
||||||
outgoing(state) {
|
startRinging(state) {
|
||||||
|
state.callState = CallState.ringing;
|
||||||
|
},
|
||||||
|
establishCall(state, options) {
|
||||||
|
state.remoteMediaStream = options.remoteMediaStream;
|
||||||
|
state.callState = CallState.established;
|
||||||
|
},
|
||||||
|
incomingCall(state, options) {
|
||||||
|
state.callState = CallState.incoming;
|
||||||
|
},
|
||||||
|
hangUpCall(state) {
|
||||||
|
state.callState = CallState.input;
|
||||||
|
if(_.isObject(state.localMediaStream)) {
|
||||||
|
state.localMediaStream.stop();
|
||||||
|
state.localMediaStream = null;
|
||||||
|
}
|
||||||
|
if(_.isObject(state.remoteMediaStream)) {
|
||||||
|
state.remoteMediaStream.stop();
|
||||||
|
state.remoteMediaStream = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endCall(state, reason) {
|
||||||
|
state.callState = CallState.ended;
|
||||||
|
state.endedReason = reason;
|
||||||
|
if(_.isObject(state.localMediaStream)) {
|
||||||
|
state.localMediaStream.stop();
|
||||||
|
state.localMediaStream = null;
|
||||||
|
}
|
||||||
|
if(_.isObject(state.remoteMediaStream)) {
|
||||||
|
state.remoteMediaStream.stop();
|
||||||
|
state.remoteMediaStream = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
initialize(context) {
|
initialize(context) {
|
||||||
return new Promise((resolve, reject)=>{
|
return new Promise((resolve, reject)=>{
|
||||||
if(context.rootState.user.capabilities.rtcengine) {
|
Vue.call.initialize().then(()=>{
|
||||||
loadCdkLib().then((script)=>{
|
context.commit('initSucceeded');
|
||||||
context.commit('load');
|
Vue.call.onIncoming((call)=>{
|
||||||
return createSessionToken();
|
context.commit('incomingCall');
|
||||||
}).then((sessionToken)=>{
|
call.onRemoteMedia((remoteMediaStream)=>{
|
||||||
return connectDefaultCdkNetwork(sessionToken);
|
context.commit('establishCall', {
|
||||||
}).then(($cdkNetwork)=>{
|
remoteMediaStream: remoteMediaStream
|
||||||
cdkNetwork = $cdkNetwork;
|
});
|
||||||
cdkNetwork.getClient().onConnect(()=>{
|
}).onRemoteMediaEnded(()=>{
|
||||||
context.commit('connect');
|
context.commit("endRemoteMedia");
|
||||||
|
}).onEnded(()=>{
|
||||||
|
context.commit('endCall', call.endedReason);
|
||||||
});
|
});
|
||||||
cdkNetwork.getClient().onDisconnect(()=>{
|
|
||||||
context.commit('disconnect', cdkNetwork.disconnectReason);
|
|
||||||
});
|
|
||||||
context.commit('connect');
|
|
||||||
resolve();
|
|
||||||
}).catch((err)=>{
|
|
||||||
context.commit('initFailure');
|
|
||||||
resolve();
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}).catch((err)=>{
|
||||||
|
context.commit('initFailed', err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
call(context) {
|
/**
|
||||||
|
* @param context
|
||||||
},
|
* @param options
|
||||||
connect(context, sessionToken) {
|
* @param options.localMedia
|
||||||
},
|
* @param options.number
|
||||||
disconnect(context) {
|
*/
|
||||||
|
start(context, options) {
|
||||||
},
|
Vue.call.createLocalMedia(options.localMedia).then((localMediaStream)=>{
|
||||||
enableAudio(context) {
|
var call = Vue.call.start(options.number, localMediaStream);
|
||||||
|
call.onAccepted(()=>{
|
||||||
},
|
}).onEnded(()=>{
|
||||||
disableAudio(context) {
|
context.commit('endCall', call.endedReason);
|
||||||
|
|
||||||
|
}).onPending(()=>{
|
||||||
|
context.commit('startCalling', {
|
||||||
|
number: options.number,
|
||||||
|
mediaType: options.localMedia,
|
||||||
|
localMediaStream: localMediaStream
|
||||||
|
});
|
||||||
|
}).onRemoteMedia((remoteMediaStream)=>{
|
||||||
|
context.commit('establishCall', {
|
||||||
|
remoteMediaStream: remoteMediaStream
|
||||||
|
});
|
||||||
|
}).onRemoteMediaEnded(()=>{
|
||||||
|
context.commit("endRemoteMedia");
|
||||||
|
}).onRingingStart(()=>{
|
||||||
|
context.commit('startRinging');
|
||||||
|
}).onRingingStop(()=>{
|
||||||
|
context.commit('stopRinging');
|
||||||
|
});
|
||||||
|
}).catch((err)=>{
|
||||||
|
context.commit('endCall', err.name);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
enableVideo(context) {
|
accept(context, localMedia) {
|
||||||
|
Vue.call.createLocalMedia(localMedia).then((localMediaStream)=>{
|
||||||
|
Vue.call.accept(localMediaStream);
|
||||||
|
context.commit('acceptIncoming', {
|
||||||
|
localMediaStream: localMediaStream
|
||||||
|
});
|
||||||
|
}).catch((err)=>{
|
||||||
|
context.commit('endCall', 'localMediaError');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
disableVideo(context) {
|
hangUp(context) {
|
||||||
|
if(Vue.call.hasRunningCall()) {
|
||||||
|
Vue.call.hangUp();
|
||||||
|
context.commit('hangUpCall');
|
||||||
|
} else {
|
||||||
|
context.commit('endCall', 'noRunningCall');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in new issue