Skip to content

Instantly share code, notes, and snippets.

@vigikaran
Created January 14, 2021 20:56
Show Gist options
  • Save vigikaran/c3446e634e36ccaba777e8da96d39d30 to your computer and use it in GitHub Desktop.
Save vigikaran/c3446e634e36ccaba777e8da96d39d30 to your computer and use it in GitHub Desktop.
<template>
<div id="wrapper">
<div v-if="registered" class="pad">
<div class="status">
<span>&#8226;</span><span class="txt">REGISTERED</span>
</div>
<DialPad v-model="destination" ref="dialpad" />
<Calling v-if="!incoming && (speaking||calling)" :counterpart-num="counterpartNum" :speaking="speaking" :onhold="onhold" @hold="hold" @unhold="unhold" />
<Receiving v-if="incoming && !speaking" :counterpart-num="counterpartNum" @accept="answer" @decline="decline" />
<button v-if="!incoming" class="call action-dig" @click.prevent="callOrHangup" :class="{ 'in-call': speaking||calling }" >
<div class="call-change" ></div>
<div class="call-icon" :class="{ 'in-call': speaking||calling }" ></div>
</button>
</div>
<div v-else class="login-pad">
<div class="logo"><img src="@/assets/icon.png"/></div>
<form>
<input type="text" class="field" placeholder="Name" v-model.trim="$v.form.name.$model" >
<input type="text" class="field" placeholder="Extn" v-model.trim="$v.form.exten.$model">
<input type="password" class="field" placeholder="Password" v-model.trim="$v.form.password.$model">
<div v-if="registering" class="loading"><img src="@/assets/loading.svg"/></div>
<input v-else type="submit" class="button" value="Login" :disabled="$v.$invalid" @click.prevent="login" >
</form>
</div>
</div>
</template>
<script>
import DialPad from './DailerPage/DialPad'
import Calling from './DailerPage/Calling'
import Receiving from './DailerPage/Receiving'
import Janus from 'janus-no-jquery'
import { validationMixin } from 'vuelidate'
import { required } from 'vuelidate/lib/validators'
// import config from './../config'
const ringing = new Audio(require('./../assets/ringing.wav'))
const calling = new Audio(require('./../assets/calling.wav'))
ringing.loop = true
calling.loop = true
export default {
name: 'dialer-page',
components: { Calling, DialPad, Receiving },
mixins: [validationMixin],
data () {
return {
form: {
exten: '1422',
name: '1422',
password: 'yH8yD62Q8Hkh'
},
destination: null,
onhold: false,
counterpartNum: null,
remoteStreamAudio: 'remote-stream-audio',
janus: null,
currentJsep: null,
incoming: false,
speaking: false,
sipcall: null,
started: false,
calling: false,
registering: false,
registered: false
}
},
validations: {
form: {
name: { required },
exten: { required },
password: { required }
}
},
created () {
window.addEventListener('keydown', this.doCommand)
},
destroyed () {
window.removeEventListener('keydown', this.doCommand)
},
methods: {
doCommand () {
if (!this.registered) {
return
}
const cmd = event.which || event.keyCode
const digits = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
if (digits.includes(cmd)) {
const key = String.fromCharCode(cmd)
if (key !== null) {
this.$refs.dialpad.digit(key)
}
} else if (cmd === 8) {
this.$refs.dialpad.del()
} else if (cmd === 13 && !this.calling && this.destination !== null) {
this.call()
}
},
open (link) {
this.$electron.shell.openExternal(link)
},
login () {
if (this.sipcall) {
this.registering = true
const register = {
username: 'sip:' + this.form.exten + '@154.51.184.51',
display_name: this.form.name,
secret: this.form.password,
proxy: 'sip:154.51.184.51:5060',
sips: false,
request: 'register'
}
this.sipcall.send({
'message': register
})
}
},
logout () {
if (this.sipcall) {
const unregister = {
request: 'unregister'
}
this.sipcall.send({
'message': unregister
})
}
},
callOrHangup () {
if (this.calling) {
this.hangup()
return
}
if (this.speaking) {
this.hangup()
return
}
if (this.calling === false) {
this.call()
}
},
call () {
this.calling = true
calling.play()
const sipUri = 'sip:' + this.destination + '@154.51.184.51'
Janus.log('This is a SIP call')
this.sipcall.createOffer({
media: {
audioSend: true,
audioRecv: true,
videoSend: false,
videoRecv: false
},
success: (jsep) => {
Janus.debug('Got SDP!')
Janus.debug(jsep)
const body = {
request: 'call',
uri: sipUri
}
this.sipcall.send({
'message': body,
'jsep': jsep
})
},
error: (error) => {
Janus.error('WebRTC error...', error)
}
})
},
handleRemote (jsep) {
this.sipcall.handleRemoteJsep({
jsep: jsep,
error: () => {
const hangup = {
'request': 'hangup'
}
this.sipcall.send({
'message': hangup
})
this.sipcall.hangup()
}
})
},
answer () {
this.incoming = false
this.sipcall.createAnswer({
jsep: this.currentJsep,
media: {
audio: true,
video: false
},
success: (jsep) => {
Janus.debug('Got SDP! audio=' + true + ', video=' + false)
Janus.debug(jsep)
const body = {
request: 'accept'
}
this.sipcall.send({
'message': body,
'jsep': jsep
})
},
error: (error) => {
Janus.error('WebRTC error:', error)
const body = {
'request': 'decline',
'code': 480
}
this.sipcall.send({
'message': body
})
}
})
},
hold () {
const hold = {
'request': 'hold'
}
this.sipcall.send({
'message': hold
})
this.onhold = true
},
unhold () {
const unhold = {
'request': 'unhold'
}
this.sipcall.send({
'message': unhold
})
this.onhold = false
},
hangup () {
if (this.incoming) {
this.decline()
return
}
const hangup = {
'request': 'hangup'
}
this.sipcall.send({
'message': hangup
})
this.sipcall.hangup()
},
decline () {
this.incoming = false
const body = {
'request': 'decline'
}
this.sipcall.send({
'message': body
})
},
init () {
Janus.init({
debug: 'all',
callback: () => {
if (this.started) {
return
}
this.janus = new Janus({
server: ['https://rtcgw.genpbx.com/janus'],
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' }
],
success: () => {
this.janus.attach({
plugin: 'janus.plugin.sip',
success: (pluginHandle) => {
this.sipcall = pluginHandle
Janus.log('Plugin attached! (' + this.sipcall.getPlugin() + ', id=' + this.sipcall.getId() + ')')
},
error: (error) => {
Janus.error(' -- Error attaching plugin...', error)
},
onmessage: (msg, jsep) => {
Janus.debug(' ::: Got a message :::')
Janus.debug(JSON.stringify(msg))
const error = msg['error']
if (error !== null && error !== undefined) {
if (!this.registered) {
Janus.log('User is not registered')
} else {
this.sipcall.hangup()
}
return
}
const result = msg['result']
if (result !== null && result !== undefined && result['event'] !== undefined && result['event'] !== null) {
// get event
const event = result['event']
// switch event
switch (event) {
case 'registration_failed':
this.registering = false
this.$toasted.show('Registration Faild!', {
theme: 'toasted-primary',
position: 'bottom-center',
duration: 2000
})
Janus.error('Registration failed: ' + result['code'] + ' ' + result['reason'])
break
case 'registered':
Janus.log('Successfully registered as ' + result['username'] + '!')
if (!this.registered) {
this.registered = true
this.registering = false
}
break
case 'unregistered':
Janus.log('Successfully unregistered as ' + result['username'] + '!')
if (this.registered) {
this.registered = false
this.registering = false
}
break
case 'calling':
this.counterpartNum = this.destination
Janus.log('Waiting for the peer to answer...')
if (!this.calling) {
this.calling = true
}
break
case 'incomingcall':
this.counterpartNum = msg.result.username.split('@')[0].split(':')[1]
this.incoming = true
ringing.play()
Janus.log('Incoming call from ' + result['username'] + '!')
this.currentJsep = jsep
break
case 'progress':
Janus.log("There's early media from " + result['username'] + ', wairing for the call!')
if (jsep !== null && jsep !== undefined) {
this.handleRemote(jsep)
}
break
case 'accepted':
calling.pause()
ringing.pause()
if (!this.speaking) {
this.speaking = true
}
Janus.log(result['username'] + ' accepted the call!')
if (jsep !== null && jsep !== undefined) {
this.handleRemote(jsep)
}
break
case 'hangup':
this.incoming = false
if (this.calling) {
this.calling = false
}
if (this.speaking) {
this.speaking = false
}
calling.pause()
ringing.pause()
this.counterpartNum = null
Janus.log('Call hung up (' + result['code'] + ' ' + result['reason'] + ')!')
this.sipcall.hangup()
break
default:
break
}
}
},
onlocalstream: function () {
},
onremotestream: function (stream) {
Janus.debug(' ::: Got a remote stream :::')
Janus.debug(JSON.stringify(stream))
// retrieve stream track
var audioTracks = stream.getAudioTracks()
// var videoTracks = stream.getVideoTracks();
const remoteStreamAudio = document.getElementById('remote-stream-audio')
Janus.attachMediaStream(remoteStreamAudio, new MediaStream(audioTracks))
// Janus.attachMediaStream(remoteStreamVideo, new MediaStream(videoTracks));
},
oncleanup: function () {
Janus.log(' ::: Got a cleanup notification :::')
}
})
},
error: function (error) {
this.started = false
this.registered = false
Janus.error(error)
console.error('Janus error: ' + error)
// reject()
},
destroyed: function () {
this.started = false
this.registered = false
// reject()
}
})
}
})
}
},
mounted () {
this.init()
}
}
</script>
<style lang="scss" >
@import "~@/assets/style.scss";
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment