Skip to content

Instantly share code, notes, and snippets.

@mganeko
Last active August 29, 2015 14:16
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 mganeko/4d0f84c383722d1fb963 to your computer and use it in GitHub Desktop.
Save mganeko/4d0f84c383722d1fb963 to your computer and use it in GitHub Desktop.
WebRTC 1to1 with "Simple Message Server" for WebSocket
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebRTC 1to1</title>
<!--- this is demo for http://www.slideshare.net/mganeko/chromebook-webrtc -->
<!-- please install simple message server from here: https://chrome.google.com/webstore/detail/simple-message-server/bihajhgkmpfnmbmdnobjcdhagncbkmmp -->
</head>
<body>
<button type="button" onclick="startVideo();">Start video</button>
<button type="button" onclick="stopVideo();">Stop video</button>
&nbsp;&nbsp;&nbsp;&nbsp;
<button type="button" onclick="connect();">Connect</button>
<button type="button" onclick="hangUp();">Hang Up</button>
&nbsp;&nbsp;&nbsp;&nbsp;
<button type="button" onclick="disconnect_ws();">Disconnect WS</button>
<br />
<div style="position: relative;">
<video id="local-video" autoplay style="position: absolute; top: 0px; width: 160px; height: 120px; border: 1px solid black;"></video>
<video id="remote-video" autoplay style="position: absolute; top: 0px; left: 165px; width: 800px; height: 600px; border: 1px solid black;"></video>
</div>
<script>
// create socket
var url = 'ws://localhost:3001/';
var ws = new WebSocket(url);
var socketId = null;
var localVideo = document.getElementById('local-video');
var remoteVideo = document.getElementById('remote-video');
var localStream = null;
var peerConn = null;
var peerStarted = false;
var channelReady = false;
var mediaConstraints = {'mandatory': {
'OfferToReceiveAudio':true,
'OfferToReceiveVideo':true }};
function disconnect_ws() {
if (ws) {
ws.close();
ws = null;
}
}
// --------------------- socket event ---------------
ws.onopen = onChannelOpened;
ws.onmessage = onMessage;
ws.onclose = onClose;
ws.onerror = onError;
function onChannelOpened(evt) {
console.log('Channel opened.');
console.log(evt);
channelReady = true;
var msg;
//msg = 'hi';
//ws.send(msg);
msg = JSON.stringify({type: "open", text: "hello"});
ws.send(msg);
msg = JSON.stringify({type: "open", text: "あいうえおす"});
ws.send(msg);
msg = "_system:getsocketid";
ws.send(msg);
}
// socket: accept connection request
function onMessage(raw_evt) {
console.log("onMessage() evt=", raw_evt);
var msg = raw_evt.data;
var evt = JSON.parse(msg);
if (evt.type === '_system') {
if (evt.system === 'socketid') {
socketId = evt.socketid;
console.log('_system: getsocketid = ', socketId);
var msg = '_system:sendto=' + socketId + ', ' + JSON.stringify({type: "direct", text: "only for you"});
ws.send(msg);
}
}
else if (evt.type === 'offer') {
console.log("Received offer...")
if (!peerStarted) {
sendAnswer(evt);
peerStarted = true;
}
}
else if (evt.type === 'answer' && peerStarted) {
console.log('Received answer...');
console.log('Setting remote session description...' );
peerConn.setRemoteDescription(new RTCSessionDescription(evt));
}
else if (evt.type === 'candidate' && peerStarted) {
console.log('Received ICE candidate...');
var candidate = new RTCIceCandidate({sdpMLineIndex:evt.sdpMLineIndex, sdpMid:evt.sdpMid, candidate:evt.candidate});
console.log(candidate);
peerConn.addIceCandidate(candidate);
}
else if (evt.type === 'bye' && peerStarted) {
console.log("Received bye");
stop();
}
}
function onClose(raw_evt) {
console.log("onClose() evt=", raw_evt);
channelReady = false;
}
function onError(raw_evt) {
console.log("onError() evt=", raw_evt);
}
// ---------------------- video handling -----------------------
// get the local video up
function startVideo() {
navigator.webkitGetUserMedia({video: true, audio: true}, successCallback, errorCallback);
function successCallback(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream);
localVideo.play();
}
function errorCallback(error) {
console.error('An error occurred: [CODE ' + error.code + ']');
return;
}
}
// stop local video
function stopVideo() {
localVideo.src = "";
localStream.stop();
}
// ---------------------- connection handling -----------------------
function prepareNewConnection() {
var pc_config = {"iceServers":[]};
var peer = null;
try {
peer = new webkitRTCPeerConnection(pc_config);
} catch (e) {
console.log("Failed to create PeerConnection, exception: " + e.message);
}
// send any ice candidates to the other peer
peer.onicecandidate = function (evt) {
if (evt.candidate) {
console.log(evt.candidate);
//socket.json.send({type: "candidate",
// sdpMLineIndex: evt.candidate.sdpMLineIndex,
// sdpMid: evt.candidate.sdpMid,
// candidate: evt.candidate.candidate});
var candidate = {type: "candidate",
sdpMLineIndex: evt.candidate.sdpMLineIndex,
sdpMid: evt.candidate.sdpMid,
candidate: evt.candidate.candidate
};
var msg = JSON.stringify(candidate);
ws.send(msg);
} else {
console.log("End of candidates. ------------------- phase=" + evt.eventPhase);
}
};
console.log('Adding local stream...');
peer.addStream(localStream);
peer.addEventListener("addstream", onRemoteStreamAdded, false);
peer.addEventListener("removestream", onRemoteStreamRemoved, false)
// when remote adds a stream, hand it on to the local video element
function onRemoteStreamAdded(event) {
console.log("Added remote stream");
remoteVideo.src = window.URL.createObjectURL(event.stream);
}
// when remote removes a stream, remove it from the local video element
function onRemoteStreamRemoved(event) {
console.log("Remove remote stream");
remoteVideo.src = "";
}
return peer;
}
function sendOffer() {
peerConn = prepareNewConnection();
peerConn.createOffer(function (sessionDescription) { // in case of success
peerConn.setLocalDescription(sessionDescription);
console.log("Sending: offer SDP");
console.log(sessionDescription);
//socket.json.send(sessionDescription);
var msg = JSON.stringify(sessionDescription);
ws.send(msg);
}, function () { // in case of error
console.log("Create Offer failed");
}, mediaConstraints);
}
function sendAnswer(evt) {
console.log('sending Answer. Creating remote session description...' );
peerConn = prepareNewConnection();
peerConn.setRemoteDescription(new RTCSessionDescription(evt));
peerConn.createAnswer(function (sessionDescription) { // in case of success
peerConn.setLocalDescription(sessionDescription);
console.log("Sending: answer SDP");
console.log(sessionDescription);
//socket.json.send(sessionDescription);
var msg = JSON.stringify(sessionDescription);
ws.send(msg);
}, function () { // in case of error
console.log("Create Answer failed");
}, mediaConstraints);
}
// ---------------- handling user UI event -----
// start the connection upon user request
function connect() {
if (!peerStarted && localStream && channelReady) {
sendOffer();
peerStarted = true;
} else {
alert("Local stream not running yet - try again.");
}
}
// stop the connection upon user request
function hangUp() {
console.log("Hang up.");
//socket.json.send({type: "bye"});
var msg = JSON.stringify({type: "bye"});
ws.send(msg);
stop();
}
function stop() {
if (peerConn) {
peerConn.close();
peerConn = null;
}
peerStarted = false;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment