我的目标是使用 Webrtc 和 Verto 实现语音通话。我已获得对 Freeswitch 服务器的访问权限。该网页提示输入来电显示,并具有拨打电话、挂断电话的按钮。现在仅支持 1002 和 1008 的来电显示。
var vertoHandle, vertoCallbacks, currentCall;
var myLoginNo, theirLoginNo;
function bootstrap(status) {
// user login to freeswitch via a secure websocket
myLoginNo = prompt('Login no:')
if (myLoginNo == '1002') theirLoginNo = '1008';
else if (myLoginNo == '1008') theirLoginNo = '1002';
vertoHandle = new jQuery.verto({
login: myLoginNo + '@www.hidden for stackoverflow.com',
passwd: 'hidden for stackoverflow',
socketUrl: 'wss://www.hidden for stackoverflow.com',
ringFile: 'sounds/bell_ring2.wav',
iceServers: [
{'urls': 'stun:stun.services.mozilla.com'},
{'urls': 'stun:stun.l.google.com:19302'},
{'urls': 'turn:numb.viagenie.ca','credential': 'webrtc','username': 'websitebeaver@mail.com'}
],
deviceParams: {
useMic: 'any',
useSpeak: 'any',
useCamera: 'any',
},
// tag: 'video-container',
}, vertoCallbacks);
document.getElementById('make-call').addEventListener('click', makeCall);
document.getElementById('hangup-call').addEventListener('click', hangupCall);
document.getElementById('answer-call').addEventListener('click', answerCall);
}
function onWSLogin(verto, success) {
console.log('onWSLogin', success);
if (success) { }
}
function onWSClose(verto, success) {
console.log('onWSClose', success);
if (success) { }
}
function makeCall() {
currentCall = vertoHandle.newCall({
destination_number: '3520',
caller_id_name: 'test guy',
caller_id_number: theirLoginNo,
outgoingBandwidth: 'default',
incomingBandwidth: 'default',
useStereo: true,
useVideo: true,
userVariables: {
email: 'test@test.com'
},
dedEnc: false,
})
}
function answerCall() {
currentCall.answer();
}
function hangupCall() {
currentCall.hangup();
}
// track progress of a call if desired
function onDialogState(dialog) {
console.log("THE CURRENT STATE IS", dialog.state.name, dialog);
switch(dialog.state.name){
case 'requesting': break;
case 'trying': break;
case 'answering': break;
case 'active': break;
case 'ringing': alert('Someone is calling, answer!'); break;
case 'hangup': log('call ended due to:' + dialog.cause); break;
case 'destroy': break;
}
if (!currentCall) {
currentCall = dialog;
}
}
// our main function
(function() {
$.verto.init({}, bootstrap);
vertoCallbacks = {
onWSLogin: onWSLogin,
onWSClose: onWSClose,
onDialogState: onDialogState,
}
})();
然后我用 Python 运行一个本地 http 服务器,并在两个不同的浏览器(Chromium 和 Vivaldi)上打开网页。
页面加载时:
media perm init complete
jquery.verto.js:2740 enumerating devices
jquery.verto.js:2751 InputDeviceInfo {deviceId: 'default', kind: 'audioinput', label: 'Default', groupId: '41f3383ed0bb3a5cf10a5299db11d033387a20ff3d3300e7cded598506c51633'}
jquery.verto.js:2752 audioinput: Default id = default
jquery.verto.js:2751 InputDeviceInfo {deviceId: '284f58b406f0ce7e777b6865cedea40cdd3ec418bc7be95a76d1e52e8bd11c3f', kind: 'audioinput', label: 'Built-in Audio Analog Stereo', groupId: 'a32c6c7ea4d8e89f3457dab734c27acf8da999f7e65436e503bf50e823b23681'}
jquery.verto.js:2752 audioinput: Built-in Audio Analog Stereo id = 284f58b406f0ce7e777b6865cedea40cdd3ec418bc7be95a76d1e52e8bd11c3f
jquery.verto.js:2751 MediaDeviceInfo {deviceId: 'default', kind: 'audiooutput', label: 'Default', groupId: 'default'}
jquery.verto.js:2752 audiooutput: Default id = default
jquery.verto.js:2751 MediaDeviceInfo {deviceId: '9ec2152c25810eac90eb2eab4d2dffcf60f99c898ca5d2fe294acf6ae69938e8', kind: 'audiooutput', label: 'Built-in Audio Analog Stereo', groupId: 'a32c6c7ea4d8e89f3457dab734c27acf8da999f7e65436e503bf50e823b23681'}
jquery.verto.js:2752 audiooutput: Built-in Audio Analog Stereo id = 9ec2152c25810eac90eb2eab4d2dffcf60f99c898ca5d2fe294acf6ae69938e8
jquery.verto.js:2773 Audio IN Devices (2) [{…}, {…}]
jquery.verto.js:2774 Audio Out Devices (2) [{…}, {…}]
jquery.verto.js:2775 Video Devices []
输入来电显示时:
jquery.FSRTC.js:1059 CACHED RES FOR CAM any {validRes: Array(0), bestResSupported: Array(2)}
按下呼叫按钮时:
jquery.FSRTC.js:570 Camera Disabled
jquery.FSRTC.js:635 Audio constraints {}
jquery.FSRTC.js:636 Video constraints false
jquery.FSRTC.js:188 Stream Success
jquery.verto.js:2060 stream started
jquery.FSRTC.js:266 Offer SDP
jquery.verto.js:2050 offer RTCIceCandidate {candidate: 'candidate:4278134664 1 udp 2122260223 192.168.1.8 …eration 0 ufrag JerH network-id 1 network-cost 10', sdpMid: '0', sdpMLineIndex: 0, foundation: '4278134664', component: 'rtp', …}
jquery.verto.js:2050 offer RTCIceCandidate {candidate: 'candidate:2960972664 1 tcp 1518280447 192.168.1.8 …eration 0 ufrag JerH network-id 1 network-cost 10', sdpMid: '0', sdpMLineIndex: 0, foundation: '2960972664', component: 'rtp', …}
jquery.verto.js:2050 offer RTCIceCandidate {candidate: 'candidate:1470146653 1 udp 1686052607 117.254.33.2…eration 0 ufrag JerH network-id 1 network-cost 10', sdpMid: '0', sdpMLineIndex: 0, foundation: '1470146653', component: 'rtp', …}
jquery.FSRTC.js:206 ICE Complete
jquery.FSRTC.js:217 ICE SDP
jquery.verto.js:2018 RECV offer SDP v=0
o=- 925384632778700947 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS WnoZdnnOk9EtfBmGfvUMKoUR8yEq1ho0cEHL
m=audio 10915 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 117.254.33.254
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:4278134664 1 udp 2122260223 192.168.1.8 55515 typ host generation 0 network-id 1 network-cost 10
a=candidate:2960972664 1 tcp 1518280447 192.168.1.8 9 typ host tcptype active generation 0 network-id 1 network-cost 10
a=candidate:1470146653 1 udp 1686052607 117.254.33.254 10915 typ srflx raddr 192.168.1.8 rport 55515 generation 0 network-id 1 network-cost 10
a=ice-ufrag:JerH
a=ice-pwd:va+iMs0gI2pZVm+xnT1kzP8W
a=ice-options:trickle
a=fingerprint:sha-256 08:2C:7E:4E:29:63:D8:D2:35:91:45:5B:FC:B0:89:0A:3F:43:F8:40:1D:B4:9E:2B:D0:0A:00:2B:DE:DD:9F:AC
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:WnoZdnnOk9EtfBmGfvUMKoUR8yEq1ho0cEHL ce839971-f2ed-479b-b84a-1fe481df6988
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1; stereo=1; sprop-stereo=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:4217896380 cname:dNyxztJfwP0rlpac
a=ssrc:4217896380 msid:WnoZdnnOk9EtfBmGfvUMKoUR8yEq1ho0cEHL ce839971-f2ed-479b-b84a-1fe481df6988
a=ssrc:4217896380 mslabel:WnoZdnnOk9EtfBmGfvUMKoUR8yEq1ho0cEHL
a=ssrc:4217896380 label:ce839971-f2ed-479b-b84a-1fe481df6988
jquery.verto.js:2204 Dialog b40a8b30-12cd-39cd-5522-b6255231499e: state change from new to requesting
main.js:75 THE CURRENT STATE IS requesting