Skip to content

Instantly share code, notes, and snippets.

@n0bisuke
Created September 20, 2016 20:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n0bisuke/9a46a4f1455882d8263c9520f23c56b6 to your computer and use it in GitHub Desktop.
Save n0bisuke/9a46a4f1455882d8263c9520f23c56b6 to your computer and use it in GitHub Desktop.
Milkcocoaでシグナリング。 WSサーバーでシグナリングしてるコードを書き換え https://gist.github.com/n0bisuke/904997957304cd0a8edfa9c3edaeeced
'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