рдореИрдВ рдЕрдкрдиреЗ vue.js рд░реЗрдкреЛ рдореЗрдВ рд╕рд┐рдк.рдЬреЗрдПрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред
`
import sipModal from './sipModal.vue'
export default {
template: '#sipDialler',
name: 'sip-dialler',
data () {
return {
session: '',
ua: '',
hangupType: 'NOCALL',
inputNumber: '',
onCall: false,
callIncoming: false,
audioConstraints: {
audio: true,
video: false
},
mediaStream: ''
}
},
computed: {
media () {
const audio = document.getElementById('remoteAudio')
const audio2 = document.getElementById('localAudio')
return {
stream: this.audioConstraints,
render: {
remote: audio,
local: audio2
}
}
}
},
components: {
'sip-modal': sipModal
},
created () {
this.registerUserAgent()
},
methods: {
registerUserAgent () {
// eslint-disable-next-line
this.ua = new SIP.UA({
uri: '******.callwise.net',
wsServers: 'wss://sip.callwise.net:443',
traceSip: true,
authorizationUser: '******',
password: '********'
})
this.onRegistered()
this.onUnregistered()
this.onInvite()
},
onRegistered () {
this.ua.on('registered', function () {
// eslint-disable-next-line
SIP.WebRTC.isSupported()
// eslint-disable-next-line
SIP.WebRTC.getUserMedia(this.audioConstraints, function (stream) {
console.log(stream)
this.mediaStream = stream
}, function (e) {
console.error(e)
})
})
},
onUnregistered () {
this.ua.on('unregistered', function () {
console.log('unregistered')
})
},
onInvite () {
this.ua.on('invite', function (incoming) {
console.log('receiving call')
this.session = incoming
this.callIncoming = true
})
},
onFailed () {
this.session.on('failed', function (response, cause) {
this.callIncoming = false
})
},
makeCall () {
this.session = this.ua.invite('sip:' + this.inputNumber + '********.callwise.net', this.media)
},
answerCall () {
this.session.accept(this.media)
this.callIncoming = false
},
rejectCall () {
this.session.reject({statusCode: '486', reasonPhrase: 'Busy Here'})
},
deleteInput () {
this.inputNumber = this.inputNumber.slice(0, -1)
},
addHash () {
this.inputNumber += '#'
},
addAsterisk () {
this.inputNumber += '*'
}
}
}
`
When using that code I get ---> TypeError: Failed to execute 'getUserMedia' on 'Navigator': At least one of audio and video must be requested
at sip-0.7.5.js:10447
at Promise (
at Object.promisifiedMethod [as getUserMedia] (sip-0.7.5.js:10442)
at UA.eval (eval at 186 (0.9df3722тАж.hot-update.js:7),
at UA.EventEmitter.emit (sip-0.7.5.js:112)
at RegisterContext.EventEmitter.emit (sip-0.7.5.js:112)
at RegisterContext.receiveResponse (sip-0.7.5.js:3477)
at RequestSender.receiveResponse (sip-0.7.5.js:3758)
at NonInviteClientTransaction.receiveResponse (sip-0.7.5.js:7615)
at Transport.onMessage (sip-0.7.5.js:8526)
(anonymous) @ sipDialler.vue?36c1:114
If I remove the bit:
SIP.WebRTC.getUserMedia(this.audioConstraints, function (stream) {
console.log(stream)
this.mediaStream = stream
}, function (e) {
console.error(e)
})
})
I don't get any errors and I'm able to make calls, the person I'm calling to can hear me on the mobile-phone but I'm not ables to hear the person I'm calling on my speakers.
Any ideas why is that happening?
рдЖрдкрдХреЛ рд╕реНрд╡рдпрдВ getUserMedia
рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдореАрдбрд┐рдпрд╛ рд╣реИрдВрдбрд▓рд░ рдЖрдкрдХреЗ рд▓рд┐рдП рдпрд╣ рдХрд░реЗрдЧрд╛ред
рдЕрд░реЗ рдПрд░рд┐рдХ, рдЖрдкрдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкрд╣рд▓реЗ рдЕрдВрдХ рдкрд░ рдХрд╣рд╛ рдерд╛ рдЬрдм рдореИрдВ рдХреЛрдб рдХреА рд▓рд╛рдЗрди рд╣рдЯрд╛рддрд╛ рд╣реВрдВ:
SIP.WebRTC.getUserMedia(this.audioConstraints, function (stream) { console.log(stream) this.mediaStream = stream }, function (e) { console.error(e) }) })
рддреНрд░реБрдЯрд┐ рджрд┐рдЦрдирд╛ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдФрд░ рдореИрдВ рдЕрдкрдиреА рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реВрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ рдЬрд┐рд╕ рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ, рд╡рд╣ рдЕрдкрдиреЗ рдореЛрдмрд╛рдЗрд▓-рдлрд╝реЛрди рд╕реЗ рдореБрдЭреЗ рд╕реБрди рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрдкрдиреЗ рдХрдВрдкреНрдпреВрдЯрд░ рд╕реНрдкреАрдХрд░ рд╕реЗ рдЙрд╕ рд╡реНрдпрдХреНрддрд┐ рдХреА рдмрд╛рдд рдирд╣реАрдВ рд╕реБрди рдкрд╛ рд░рд╣рд╛ рд╣реВрдБ, рдЬрд┐рд╕реЗ рдореИрдВ рдХреЙрд▓ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐, рдРрдк рдореЗрд░реЗ рдорд╛рдЗрдХреНрд░реЛрдлрд╝реЛрди рддрдХ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдореЗрд░реЗ рд╕реНрдкреАрдХрд░ рддрдХ рдирд╣реАрдВред рдХреЛрдИ рд╡рд┐рдЪрд╛рд░ рдРрд╕рд╛ рдХреНрдпреЛрдВ рд╣реЛрддрд╛ рд╣реИ?
рдзрдиреНрдпрд╡рд╛рджред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдХреНрдпрд╛ рдЖрдк рдкреБрд╖реНрдЯрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд░рд┐рдореЛрдЯ рдСрдбрд┐рдпреЛ рдХреЛ рдбреАрдУрдПрдо рдкрд░ рдСрдбрд┐рдпреЛ рддрддреНрд╡ рд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ? рдпрд╣ рднреА рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдЦреЗрд▓рд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рд░реЛрдХрд╛ рдирд╣реАрдВ рдЧрдпрд╛ рд╣реИред
рдЕрдЧрд░ рдРрд╕рд╛ рд╣реИ, рддреЛ рдореИрдВ рдкрд╣рд▓реЗ SIP.js рдХреЛ vue.js рдХреЗ рдмрд╛рд╣рд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдкреНрдд рдХрд░реВрдВрдЧрд╛ред рдлрд┐рд░ рдЗрд╕реЗ Vue рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд░реЗрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ рдЬреЛ SIP.js afaik рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗред
рдзрдиреНрдпрд╡рд╛рдж рдПрд░рд┐рдХ, рдЖрдЦрд┐рд░рдХрд╛рд░ рдореИрдВрдиреЗ рдЗрд╕реЗ рдХрд╛рдо рдХрд░ рджрд┐рдпрд╛ рдореИрдВрдиреЗ рдЕрдкрдиреА рдЧрдгрдирд╛ рдХреА рд╡рд┐рдзрд┐ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛
рдкрд░рд┐рдХрд▓рд┐рдд: {
media () {
const audio = document.getElementById('remoteAudio')
const audio2 = document.getElementById('localAudio')
return {
stream: this.audioConstraints,
render: {
remote: audio,
local: audio2
}
}
}
},
рдкреНрд░рддрд┐:
options () {
const audio = document.getElementById('remoteAudio')
const audio2 = document.getElementById('localAudio')
return {
media: {
constraints: {
audio: true,
video: false
},
render: {
remote: audio,
local: audio2
}
}
}
},
рдФрд░ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп this.options рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ред рдореАрдбрд┐рдпрд╛ рдФрд░ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИред
рдорджрдж рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдмрдВрдж рдХрд░рддрд╛ рд╣реВрдВред
@Juli0GT
рдирдорд╕реНрддреЗ,
рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЕрдкрдиреЗ рдХрд╛рдордХрд╛рдЬреА рдХреЛрдб рдХрд╛ рд╢реЗрд╖ рдирдореВрдирд╛ рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рдореИрдВ рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рд╕рдВрдШрд░реНрд╖ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЖрдк рдореЗрд░реА рдмрд╣реБрдд рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╢реБрдХреНрд░рд┐рдпрд╛
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
@Juli0GT
рдирдорд╕реНрддреЗ,
рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЕрдкрдиреЗ рдХрд╛рдордХрд╛рдЬреА рдХреЛрдб рдХрд╛ рд╢реЗрд╖ рдирдореВрдирд╛ рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рдореИрдВ рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рд╕рдВрдШрд░реНрд╖ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЖрдк рдореЗрд░реА рдмрд╣реБрдд рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╢реБрдХреНрд░рд┐рдпрд╛