-
-
Save n0bisuke/9a46a4f1455882d8263c9520f23c56b6 to your computer and use it in GitHub Desktop.
Milkcocoaでシグナリング。 WSサーバーでシグナリングしてるコードを書き換え https://gist.github.com/n0bisuke/904997957304cd0a8edfa9c3edaeeced
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const milkcocoa = new MilkCocoa('your-app-id.mlkcca.com'); | |
const ds = milkcocoa.dataStore('webrtc-signaling'); | |
const UUID = uuid(); | |
console.log(UUID); | |
ds.send({uuid:UUID}); | |
/** | |
* step2 | |
*/ | |
'use strict'; | |
let localVideo = document.querySelector('#local_video'); | |
let remoteVideo = document.querySelector('#remote_video'); | |
let localStream = null; | |
let peerConnection = null; | |
let textForSendSdp = document.querySelector('#text_for_send_sdp'); | |
let textToReceiveSdp = document.querySelector('#text_for_receive_sdp'); | |
//イベント紐付け | |
let startBtn = document.querySelector('#start_btn'); | |
startBtn.addEventListener('click', startVideo, false); | |
let stopBtn = document.querySelector('#stop_btn'); | |
stopBtn.addEventListener('click', stopVideo, false); | |
let connectBtn = document.querySelector('#connect_btn'); | |
connectBtn.addEventListener('click', connect, false); | |
// getUserMediaでカメラ、マイクにアクセス | |
function startVideo() { | |
navigator.mediaDevices.getUserMedia({video: true, audio: true}) | |
.then((stream) => { // success | |
console.log(stream); | |
playVideo(localVideo, stream); | |
localStream = stream; | |
}).catch((error) => { // error | |
console.error('mediaDevice.getUserMedia() error:', error); | |
return; | |
} | |
); | |
} | |
// Videoの再生を開始する | |
function playVideo(element, stream) { | |
if ('srcObject' in element) { | |
element.srcObject = stream; | |
} | |
else { | |
element.src = window.URL.createObjectURL(stream); | |
} | |
element.play(); | |
} | |
function stopVideo(){ | |
console.log('stop'); | |
} | |
// Connectボタンが押されたら処理を開始 | |
function connect() { | |
if (! peerConnection) { | |
console.log('make Offer'); | |
makeOffer(); | |
} | |
else { | |
console.warn('peer already exist.'); | |
} | |
} | |
// WebRTCを利用する準備をする | |
function prepareNewConnection() { | |
let RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection; | |
// RTCPeerConnectionを初期化する | |
let pc_config = {"iceServers":[ {"url":"stun:stun.skyway.io:3478"} ]}; | |
let peer = new RTCPeerConnection(pc_config); | |
// リモートのストリームを受信した場合のイベントをセット | |
if ('ontrack' in peer) { | |
peer.ontrack = function(event) { | |
console.log('-- peer.ontrack()'); | |
let stream = event.streams[0]; | |
playVideo(remoteVideo, stream); | |
}; | |
} | |
else { | |
peer.onaddstream = function(event) { | |
console.log('-- peer.onaddstream()'); | |
let stream = event.stream; | |
playVideo(remoteVideo, stream); | |
}; | |
} | |
// ICE Candidateを収集したときのイベント | |
// peer.onicecandidate = function (evt) { | |
// if (evt.candidate) { | |
// console.log(evt.candidate); | |
// } else { | |
// console.log('empty ice event'); | |
// sendSdp(peer.localDescription); | |
// } | |
// }; | |
// | |
//↓修正 | |
peer.onicecandidate = function (evt) { | |
if (evt.candidate) { | |
console.log(evt.candidate); | |
sendIceCandidate(evt.candidate); | |
} else { | |
console.log('empty ice event'); | |
// sendSdp(peer.localDescription); | |
} | |
}; | |
// ICEのステータスが変更になったときの処理 | |
peer.oniceconnectionstatechange = function() { | |
console.log('ICE connection Status has changed to ' + peer.iceConnectionState); | |
switch (peer.iceConnectionState) { | |
case 'closed': | |
case 'failed': | |
// ICEのステートが切断状態または異常状態になったら切断処理を実行する | |
if (peerConnection) { | |
hangUp(); | |
} | |
break; | |
case 'dissconnected': | |
break; | |
} | |
}; | |
// ローカルのストリームを利用できるように準備する | |
if (localStream) { | |
console.log('Adding local stream...'); | |
peer.addStream(localStream); | |
} | |
else { | |
console.warn('no local stream, but continue.'); | |
} | |
return peer; | |
} | |
// 手動シグナリングのための処理を追加する | |
// function sendSdp(sessionDescription) { | |
// console.log('---sending sdp ---'); | |
// textForSendSdp.value = sessionDescription.sdp; | |
// textForSendSdp.focus(); | |
// textForSendSdp.select(); | |
// } | |
// | |
// ↓シグナリングサーバー経由での処理に変更 | |
function sendSdp(sessionDescription) { | |
console.log('---sending sdp ---'); | |
textForSendSdp.value = sessionDescription.sdp; | |
let message = JSON.stringify(sessionDescription); | |
console.log('sending SDP=' + message); | |
// ws.send(message); | |
ds.send({text:message,uuid:UUID}); | |
} | |
// Offer SDPを生成する | |
// function makeOffer() { | |
// peerConnection = prepareNewConnection(); | |
// peerConnection.onnegotiationneeded = function(){ | |
// peerConnection.createOffer() | |
// .then(function (sessionDescription) { | |
// console.log('createOffer() succsess in promise'); | |
// return peerConnection.setLocalDescription(sessionDescription); | |
// }).then(function() { | |
// console.log('setLocalDescription() succsess in promise'); | |
// }).catch(function(err) { | |
// console.error(err); | |
// }); | |
// } | |
// } | |
//↓ | |
// Offer SDPを生成する | |
function makeOffer() { | |
peerConnection = prepareNewConnection(); | |
peerConnection.onnegotiationneeded = function(){ | |
peerConnection.createOffer() | |
.then(function (sessionDescription) { | |
console.log('createOffer() succsess in promise'); | |
return peerConnection.setLocalDescription(sessionDescription); | |
}).then(function() { | |
console.log('setLocalDescription() succsess in promise'); | |
sendSdp(peerConnection.localDescription); | |
}).catch(function(err) { | |
console.error(err); | |
}); | |
} | |
} | |
/** | |
* | |
*/ | |
// Answer SDPを生成する | |
// function makeAnswer() { | |
// console.log('sending Answer. Creating remote session description...' ); | |
// if (! peerConnection) { | |
// console.error('peerConnection NOT exist!'); | |
// return; | |
// } | |
// peerConnection.createAnswer() | |
// .then(function (sessionDescription) { | |
// console.log('createAnswer() succsess in promise'); | |
// return peerConnection.setLocalDescription(sessionDescription); | |
// }).then(function() { | |
// console.log('setLocalDescription() succsess in promise'); | |
// }).catch(function(err) { | |
// console.error(err); | |
// }); | |
// } | |
//↓ | |
// Answer SDPを生成する | |
function makeAnswer() { | |
console.log('sending Answer. Creating remote session description...' ); | |
if (! peerConnection) { | |
console.error('peerConnection NOT exist!'); | |
return; | |
} | |
peerConnection.createAnswer() | |
.then(function (sessionDescription) { | |
console.log('createAnswer() succsess in promise'); | |
return peerConnection.setLocalDescription(sessionDescription); | |
}).then(function() { | |
console.log('setLocalDescription() succsess in promise'); | |
sendSdp(peerConnection.localDescription); | |
}).catch(function(err) { | |
console.error(err); | |
}); | |
} | |
/** | |
* | |
*/ | |
// SDPのタイプを判別しセットする | |
function onSdpText() { | |
let text = textToReceiveSdp.value; | |
if (peerConnection) { | |
// Offerした側が相手からのAnserをセットする場合 | |
console.log('Received answer text...'); | |
let answer = new RTCSessionDescription({ | |
type : 'answer', | |
sdp : text, | |
}); | |
setAnswer(answer); | |
} | |
else { | |
// Offerを受けた側が相手からのOfferをセットする場合 | |
console.log('Received offer text...'); | |
let offer = new RTCSessionDescription({ | |
type : 'offer', | |
sdp : text, | |
}); | |
setOffer(offer); | |
} | |
textToReceiveSdp.value =''; | |
} | |
// Offer側のSDPをセットした場合の処理 | |
function setOffer(sessionDescription) { | |
if (peerConnection) { | |
console.error('peerConnection alreay exist!'); | |
} | |
peerConnection = prepareNewConnection(); | |
peerConnection.onnegotiationneeded = function () { | |
peerConnection.setRemoteDescription(sessionDescription) | |
.then(function() { | |
console.log('setRemoteDescription(offer) succsess in promise'); | |
makeAnswer(); | |
}).catch(function(err) { | |
console.error('setRemoteDescription(offer) ERROR: ', err); | |
}); | |
} | |
} | |
// Answer側のSDPをセットした場合の処理 | |
function setAnswer(sessionDescription) { | |
if (! peerConnection) { | |
console.error('peerConnection NOT exist!'); | |
return; | |
} | |
peerConnection.setRemoteDescription(sessionDescription) | |
.then(function() { | |
console.log('setRemoteDescription(answer) succsess in promise'); | |
}).catch(function(err) { | |
console.error('setRemoteDescription(answer) ERROR: ', err); | |
}); | |
} | |
/** | |
* 切断処理追加 | |
*/ | |
// WebRTCを利用する準備をする | |
// function prepareNewConnection() { | |
// // ICEのステータスが変更になったときの処理 | |
// peer.oniceconnectionstatechange = function() { | |
// console.log('ICE connection Status has changed to ' + peer.iceConnectionState); | |
// switch (peer.iceConnectionState) { | |
// case 'closed': | |
// case 'failed': | |
// // ICEのステートが切断状態または異常状態になったら切断処理を実行する | |
// if (peerConnection) { | |
// hangUp(); | |
// } | |
// break; | |
// case 'dissconnected': | |
// break; | |
// } | |
// }; | |
// } | |
// P2P通信を切断する | |
// function hangUp(){ | |
// if (peerConnection) { | |
// if(peerConnection.iceConnectionState !== 'closed'){ | |
// peerConnection.close(); | |
// peerConnection = null; | |
// cleanupVideoElemet(remoteVideo); | |
// textForSendSdp.value = ''; | |
// textToReceiveSdp.value = ''; | |
// return; | |
// } | |
// } | |
// console.log('peerConnection is closed.'); | |
// } | |
// P2P通信を切断する | |
function hangUp(){ | |
if (peerConnection) { | |
if(peerConnection.iceConnectionState !== 'closed'){ | |
peerConnection.close(); | |
peerConnection = null; | |
let obj = { type: 'close' }; | |
let message = JSON.stringify(obj); | |
console.log('sending close message'); | |
// ws.send(message); | |
ds.send({text:message,uuid:UUID}); | |
cleanupVideoElemet(remoteVideo); | |
textForSendSdp.value = ''; | |
textToReceiveSdp.value = ''; | |
return; | |
} | |
} | |
console.log('peerConnection is closed.'); | |
} | |
// ビデオエレメントを初期化する | |
function cleanupVideoElemet(element) { | |
element.pause(); | |
if ('srcObject' in element) { | |
element.srcObject = null; | |
} | |
else { | |
if (element.src && (element.src !== '') ) { | |
window.URL.revokeObjectURL(element.src); | |
} | |
element.src = ''; | |
} | |
} | |
// シグナリングサーバへ接続する | |
// let wsUrl = 'ws://localhost:3001/'; | |
// let ws = new WebSocket(wsUrl); | |
// ws.onopen = function(evt) { | |
// console.log('ws open()'); | |
// }; | |
// ws.onerror = function(err) { | |
// console.error('ws onerror() ERR:', err); | |
// }; | |
// | |
ds.on('send', function(sended){ | |
if(!sended.value.text) return; | |
if(sended.value.uuid === UUID) return; | |
let message = JSON.parse(sended.value.text); | |
// console.log('mlk--',sended.value); | |
// console.log('mlk--',message,typeof(message)); | |
if (message.type === 'offer') { | |
// offer 受信時 | |
console.log('Received offer ...'); | |
textToReceiveSdp.value = message.sdp; | |
let offer = new RTCSessionDescription(message); | |
setOffer(offer); | |
} | |
else if (message.type === 'answer') { | |
// answer 受信時 | |
console.log('Received answer ...'); | |
textToReceiveSdp.value = message.sdp; | |
let answer = new RTCSessionDescription(message); | |
setAnswer(answer); | |
} | |
else if (message.type === 'candidate') { | |
// ICE candidate 受信時 | |
console.log('Received ICE candidate ...'); | |
let candidate = new RTCIceCandidate(message.ice); | |
console.log(candidate); | |
addIceCandidate(candidate); | |
} | |
}); | |
// ws.onmessage = function(evt) { | |
// console.log('ws onmessage() data:', evt.data); | |
// let message = JSON.parse(evt.data); | |
// if (message.type === 'offer') { | |
// // offer 受信時 | |
// console.log('Received offer ...'); | |
// textToReceiveSdp.value = message.sdp; | |
// let offer = new RTCSessionDescription(message); | |
// setOffer(offer); | |
// } | |
// else if (message.type === 'answer') { | |
// // answer 受信時 | |
// console.log('Received answer ...'); | |
// textToReceiveSdp.value = message.sdp; | |
// let answer = new RTCSessionDescription(message); | |
// setAnswer(answer); | |
// } | |
// else if (message.type === 'candidate') { | |
// // ICE candidate 受信時 | |
// console.log('Received ICE candidate ...'); | |
// let candidate = new RTCIceCandidate(message.ice); | |
// console.log(candidate); | |
// addIceCandidate(candidate); | |
// } | |
// }; | |
// ICE candaidate受信時にセットする | |
function addIceCandidate(candidate) { | |
if (peerConnection) { | |
peerConnection.addIceCandidate(candidate); | |
} | |
else { | |
console.error('PeerConnection not exist!'); | |
return; | |
} | |
} | |
// ICE candidate生成時に送信する | |
function sendIceCandidate(candidate) { | |
console.log('---sending ICE candidate ---'); | |
let obj = { type: 'candidate', ice: candidate }; | |
let message = JSON.stringify(obj); | |
console.log('sending candidate=' + message); | |
// ws.send(message); | |
ds.send({text:message,uuid:UUID}); | |
} | |
function uuid() { | |
var uuid = "", i, random; | |
for (i = 0; i < 32; i++) { | |
random = Math.random() * 16 | 0; | |
if (i == 8 || i == 12 || i == 16 || i == 20) { | |
uuid += "-" | |
} | |
uuid += (i == 12 ? 4 : (i == 16 ? (random & 3 | 8) : random)).toString(16); | |
} | |
return uuid; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment