Permalink
1f6e036 Jan 7, 2016
executable file 461 lines (391 sloc) 12.6 KB
<title>AppRTC look for RTCMultiConnection Demo ® Muaz Khan</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<script>
if(!location.hash.replace('#', '').length) {
location.href = location.href.split('#')[0] + '#' + (Math.random() * 100).toString().replace('.', '');
location.reload();
}
</script>
<meta name="description" content="AppRTC like RTCMultiConnection demo where styles and layout is taken from AppRTC demo." />
<meta name="keywords" content="AppRTC,RTCMultiConnection,AppRTC-Look,WebRTC" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<script src="//cdn.webrtc-experiment.com/RTCMultiConnection.js"></script>
<script src="//cdn.webrtc-experiment.com/firebase.js"></script>
<style>
body,
html {
background: black;
text-align: center;
color: white;
overflow: hidden;
}
.local-media,
.remote-media {
max-width: 100%;
max-height: 70%;
}
.local-media-small,
.remote-media-small {
width: 20%;
position: fixed;
bottom: 0;
left: 0;
}
button {
display: inline-block;
outline: 0;
color: white;
background: #4472b9;
white-space: nowrap;
border: 5px solid #4472b9 !important;
font-family: 'Gotham Rounded A', 'Gotham Rounded B', sans-serif;
font-weight: 500;
font-style: normal;
padding: 9px 16px !important;
line-height: 1.4;
position: relative;
border-radius: 10px;
-webkit-box-shadow: 5px 5px 0 0 rgba(0, 0, 0, 0.15);
box-shadow: 5px 5px 0 0 rgba(0, 0, 0, 0.15);
-webkit-transition: 0.1s;
transition: 0.1s;
}
button:hover,
button:active,
button:focus {
background: #04C;
}
button[disabled] {
background: transparent;
border-color: rgb(83, 81, 81);
color: rgb(139, 133, 133);
}
#container {
-webkit-perspective: 1000;
background-color: #000000;
height: 100%;
margin: 0px auto;
position: absolute;
width: 100%;
}
#card {
-webkit-transform-style: preserve-3d;
-webkit-transition-duration: 2s;
-webkit-transition-property: rotation;
}
#local {
-webkit-backface-visibility: hidden;
-webkit-transform: scale(-1, 1);
position: absolute;
width: 100%;
}
#remote {
-webkit-backface-visibility: hidden;
-webkit-transform: rotateY(180deg);
position: absolute;
width: 100%;
}
#mini {
/* -webkit-transform: scale(-1, 1); */
bottom: 0;
height: 30%;
opacity: 1.0;
position: absolute;
right: 4px;
width: 30%;
}
#localVideo {
-webkit-transition-duration: 2s;
-webkit-transition-property: opacity;
height: 100%;
opacity: 0;
width: 100%;
}
#remoteVideo {
-webkit-transition-duration: 2s;
-webkit-transition-property: opacity;
height: 100%;
opacity: 0;
width: 100%;
}
#miniVideo,
.other-videos {
-webkit-transition-duration: 2s;
-webkit-transition-property: opacity;
height: 100%;
opacity: 0;
width: 100%;
}
#footer {
background-color: #3F3F3F;
bottom: 0;
color: rgb(255, 255, 255);
font-size: 13px;
font-weight: bold;
height: 28px;
line-height: 28px;
position: absolute;
text-align: center;
width: 100%;
}
#hangup {
background-color: #808080;
border-color: #FFFFFF;
border-style: solid;
color: #FFFFFF;
font-size: 13px;
font-weight: bold;
height: 24px;
margin: 2px;
width: 128px;
}
</style>
<button id="open-room" style="position: fixed; left: 45%; right: 45%; z-index: 100000;">Open Room</button>
<div id="container" ondblclick="enterFullScreen()">
<div id="card">
<div id="local">
<video id="localVideo" autoplay="autoplay" muted="true" />
</div>
<div id="remote">
<video id="remoteVideo" autoplay="autoplay"></video>
<div id="mini">
<video id="miniVideo" autoplay="autoplay" muted="true" />
</div>
</div>
</div>
</div>
<script>
// initializing the constructor
var connection = new RTCMultiConnection();
// some booleans to override defaults
connection.preventSSLAutoAllowed = false;
connection.autoReDialOnFailure = true;
connection.setDefaultEventsForMediaElement = false;
// setting type of media connection
connection.session = {
audio: true,
video: true
};
// DOM objects
var localVideo = document.getElementById('localVideo');
var miniVideo = document.getElementById('miniVideo');
var remoteVideo = document.getElementById('remoteVideo');
var card = document.getElementById('card');
var containerDiv;
var main = document.querySelector('#main');
var smaller = document.querySelector('#smaller');
var RTCPeerConnection = null;
var getUserMedia = null;
var attachMediaStream = null;
var reattachMediaStream = null;
var webrtcDetectedBrowser = null;
var webrtcDetectedVersion = null;
if (navigator.mozGetUserMedia) {
console.log("This appears to be Firefox");
webrtcDetectedBrowser = "firefox";
webrtcDetectedVersion =
parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1]);
// The RTCPeerConnection object.
RTCPeerConnection = mozRTCPeerConnection;
// The RTCSessionDescription object.
RTCSessionDescription = mozRTCSessionDescription;
// The RTCIceCandidate object.
RTCIceCandidate = mozRTCIceCandidate;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.mozGetUserMedia.bind(navigator);
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
console.log("Attaching media stream");
element.mozSrcObject = stream;
element.play();
};
reattachMediaStream = function(to, from) {
console.log("Reattaching media stream");
to.mozSrcObject = from.mozSrcObject;
to.play();
};
// Fake get{Video,Audio}Tracks
MediaStream.prototype.getVideoTracks = function() {
return [];
};
MediaStream.prototype.getAudioTracks = function() {
return [];
};
} else if (navigator.webkitGetUserMedia) {
console.log("This appears to be Chrome");
webrtcDetectedBrowser = "chrome";
webrtcDetectedVersion =
parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]);
// The RTCPeerConnection object.
RTCPeerConnection = webkitRTCPeerConnection;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
if (typeof element.srcObject !== 'undefined') {
element.srcObject = stream;
} else if (typeof element.mozSrcObject !== 'undefined') {
element.mozSrcObject = stream;
} else if (typeof element.src !== 'undefined') {
element.src = URL.createObjectURL(stream);
} else {
console.log('Error attaching stream to element.');
}
};
reattachMediaStream = function(to, from) {
to.src = from.src;
};
// The representation of tracks in a stream is changed in M26.
// Unify them for earlier Chrome versions in the coexisting period.
if (!webkitMediaStream.prototype.getVideoTracks) {
webkitMediaStream.prototype.getVideoTracks = function() {
return this.videoTracks;
};
webkitMediaStream.prototype.getAudioTracks = function() {
return this.audioTracks;
};
}
// New syntax of getXXXStreams method in M26.
if (!webkitRTCPeerConnection.prototype.getLocalStreams) {
webkitRTCPeerConnection.prototype.getLocalStreams = function() {
return this.localStreams;
};
webkitRTCPeerConnection.prototype.getRemoteStreams = function() {
return this.remoteStreams;
};
}
} else {
console.log("Browser does not appear to be WebRTC-capable");
}
// onstream event; fired both for local and remote videos
var numberOfRemoteVideos = 0;
connection.onstream = function(e) {
if (e.type == 'local') {
localStream = e.stream;
attachMediaStream(localVideo, e.stream);
localVideo.muted = true;
localVideo.style.opacity = 1;
}
if (e.type == 'remote') numberOfRemoteVideos++;
if (e.type == 'remote' && numberOfRemoteVideos == 1) {
remoteStream = e.stream;
reattachMediaStream(miniVideo, localVideo);
miniVideo.muted = true;
attachMediaStream(remoteVideo, e.stream);
waitForRemoteVideo();
remoteVideo.setAttribute('data-id', e.userid);
miniVideo.setAttribute('data-id', connection.userid);
}
if (e.type == 'remote' && numberOfRemoteVideos == 2) {
appendVideo(e, 'opacity: 1;position: fixed;bottom: 0;z-index: 1;width: 32%;');
}
if (e.type == 'remote' && numberOfRemoteVideos == 3) {
appendVideo(e, 'opacity: 1;position: fixed;top: 0;z-index: 1;width: 32%;');
}
if (e.type == 'remote' && numberOfRemoteVideos == 4) {
appendVideo(e, 'opacity: 1;position: fixed;top: 0;z-index: 1;width: 32%;right:0;');
}
if (e.type == 'local') {
document.getElementById('open-room').style.display = 'none';
}
};
function appendVideo(e, style) {
createVideoContainer(e, style, function(div) {
var video = document.createElement('video');
video.className = 'other-videos';
video.setAttribute('style', 'height:auto;opacity:1;');
video.id = e.userid;
video.src = URL.createObjectURL(e.stream);
var remote = document.getElementById('remote');
div.appendChild(video);
video.play();
});
}
function createVideoContainer(e, style, callback) {
var div = document.createElement('div');
div.setAttribute('style', style || 'float:left;opacity: 1;width: 32%;');
remote.insertBefore(div, remote.firstChild);
if (callback) callback(div);
}
// if user left
connection.onleave = function(e) {
var video = document.getElementById(e.userid);
if (numberOfRemoteVideos == 1) {
transitionToWaiting();
} else if (video && video.parentNode && video.parentNode.parentNode) {
numberOfRemoteVideos--;
video.parentNode.parentNode.removeChild(video.parentNode);
}
};
function waitForRemoteVideo() {
// Call the getVideoTracks method via adapter.js.
var videoTracks = remoteStream.getVideoTracks();
if (videoTracks.length === 0 || remoteVideo.currentTime > 0) {
transitionToActive();
} else {
setTimeout(waitForRemoteVideo, 100);
}
}
function transitionToActive() {
remoteVideo.style.opacity = 1;
card.style.webkitTransform = 'rotateY(180deg)';
setTimeout(function() {
localVideo.src = '';
}, 500);
setTimeout(function() {
miniVideo.style.opacity = 1;
}, 1000);
// Reset window display according to the aspectRatio of remote video.
window.onresize();
}
function transitionToWaiting() {
card.style.webkitTransform = 'rotateY(0deg)';
setTimeout(function() {
localVideo.src = miniVideo.src;
localVideo.muted = true;
miniVideo.src = '';
remoteVideo.src = '';
localVideo.style.opacity = 1;
}, 500);
miniVideo.style.opacity = 0;
remoteVideo.style.opacity = 0;
}
// Set the video displaying in the center of window.
window.onresize = function() {
var aspectRatio;
if (remoteVideo.style.opacity === '1') {
aspectRatio = remoteVideo.videoWidth / remoteVideo.videoHeight;
} else if (localVideo.style.opacity === '1') {
aspectRatio = localVideo.videoWidth / localVideo.videoHeight;
} else {
return;
}
var innerHeight = this.innerHeight;
var innerWidth = this.innerWidth;
var videoWidth = innerWidth < aspectRatio * window.innerHeight ?
innerWidth : aspectRatio * window.innerHeight;
var videoHeight = innerHeight < window.innerWidth / aspectRatio ?
innerHeight : window.innerWidth / aspectRatio;
containerDiv = document.getElementById('container');
containerDiv.style.width = videoWidth + 'px';
containerDiv.style.height = videoHeight + 'px';
containerDiv.style.left = (innerWidth - videoWidth) / 2 + 'px';
containerDiv.style.top = (innerHeight - videoHeight) / 2 + 'px';
};
function enterFullScreen() {
container.webkitRequestFullScreen();
}
// connecting to signaling medium
connection.connect();
document.getElementById('open-room').onclick = function() {
this.disabled = true;
// starting a new room
connection.open();
};
</script>