Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
343 lines (285 sloc) 10.3 KB
<title>Switch Streams / WebRTC Experiment / Muaz Khan</title>
<link rel="author" type="text/html" href="https://plus.google.com/100325991024054712503">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<blockquote style="background: #f3b7b7;border: 5px solid black;border-radius: 5px;padding: 5px 10px; margin: 10px 20px;">
This demo is <span style="border: 1px dotted red; background: yellow; padding: 2px 5px;">out-dated (published on 2013)</span>. Please check this instead: <a href="https://github.com/webrtc/samples">https://github.com/webrtc/samples</a>
</blockquote>
<div style="text-align: center;">
<button id="switch-stream">
Switch Stream to Audio+Video</button>
<hr />
<div class="videos-container">
<video id="peer2-to-peer1" autoplay controls></video>
<h2>
Offerer-to-Answerer</h2>
</div>
<div class="videos-container">
<video id="peer1-to-peer2" autoplay controls></video>
<h2>
Answerer-to-Offerer</h2>
</div>
<hr />
<h2>Switch Streams / <a href="https://www.webrtc-experiment.com/">WebRTC Experiment</a></h2>
<p>Switching streams from screen-sharing to audio+video at runtime. (Renegotiation) / Read <a href="https://www.webrtc-experiment.com/docs/how-to-switch-streams.html" target="_blank">how to switch streams?</a></p>
</div>
<script src="https://cdn.WebRTC-Experiment.com/getScreenId.js"></script>
<script>
var mediaConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
/*jshint -W079 */
var URL = window.URL;
if (typeof URL === 'undefined' && typeof webkitURL !== 'undefined') {
/*global URL:true */
URL = webkitURL;
}
var MediaStream = window.MediaStream;
if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') {
MediaStream = webkitMediaStream;
}
/*global MediaStream:true */
if (typeof MediaStream !== 'undefined') {
if (!('getVideoTracks' in MediaStream.prototype)) {
MediaStream.prototype.getVideoTracks = function() {
if (!this.getTracks) {
return [];
}
var tracks = [];
this.getTracks.forEach(function(track) {
if (track.kind.toString().indexOf('video') !== -1) {
tracks.push(track);
}
});
return tracks;
};
MediaStream.prototype.getAudioTracks = function() {
if (!this.getTracks) {
return [];
}
var tracks = [];
this.getTracks.forEach(function(track) {
if (track.kind.toString().indexOf('audio') !== -1) {
tracks.push(track);
}
});
return tracks;
};
}
if (!('stop' in MediaStream.prototype)) {
MediaStream.prototype.stop = function() {
this.getAudioTracks().forEach(function(track) {
if (!!track.stop) {
track.stop();
}
});
this.getVideoTracks().forEach(function(track) {
if (!!track.stop) {
track.stop();
}
});
};
}
}
</script>
<script>
var offerer, answerer;
var offererToAnswerer = document.getElementById('peer1-to-peer2');
var answererToOfferer = document.getElementById('peer2-to-peer1');
window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.URL = window.webkitURL || window.URL;
window.iceServers = {
iceServers: [{
urls: 'stun:stun.l.google.com:19302'
}, {
urls: 'stun:webrtcweb.com:4455',
username: 'muazkh',
credential: 'muazkh'
}]
};
</script>
<script>
/* offerer */
function offererPeer(e) {
if (!e.switching) offerer = new RTCPeerConnection(window.iceServers);
if (old_stream) offerer.removeStream(old_stream);
offerer.addStream(e.stream);
offerer.onaddstream = function(event) {
offererToAnswerer.src = URL.createObjectURL(event.stream);
offererToAnswerer.play();
};
offerer.onicecandidate = function(event) {
if (e.switching) return;
if (!event || !event.candidate) return;
answerer.addIceCandidate(event.candidate);
console.log('\r\n----ice gathered by offerer-----\r\n');
console.log(event.candidate.candidate);
};
offerer.createOffer(function(offer) {
offerer.setLocalDescription(offer);
answererPeer(offer, e.stream, e.switching);
console.log('\r\n----offer-----\r\n');
console.log(offer.sdp);
}, function() {}, mediaConstraints);
}
</script>
<script>
/* answerer */
function answererPeer(offer, stream, switching) {
if (!switching) answerer = new RTCPeerConnection(window.iceServers);
if (old_stream) answerer.removeStream(old_stream);
answerer.addStream(stream);
answerer.onaddstream = function(event) {
answererToOfferer.src = URL.createObjectURL(event.stream);
answererToOfferer.play();
};
answerer.onicecandidate = function(event) {
if (switching) return;
if (!event || !event.candidate) return;
offerer.addIceCandidate(event.candidate);
console.log('\r\n----ice gathered by answerer-----\r\n');
console.log(event.candidate.candidate);
};
answerer.setRemoteDescription(offer);
answerer.createAnswer(function(answer) {
answerer.setLocalDescription(answer);
offerer.setRemoteDescription(answer);
console.log('\r\n----answer-----\r\n');
console.log(answer.sdp);
}, function() {}, mediaConstraints);
}
</script>
<script>
var video_constraints = {
mandatory: { },
optional: []
};
function getUserMedia(callback, constraints) {
console.info('getUserMedia', constraints);
var n = navigator;
n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia;
n.getMedia(constraints || {
audio: true,
video: video_constraints
}, callback, onerror);
function onerror(e) {
console.error(e);
if (location.protocol === 'http:') {
throw '<https> is mandatory to capture screen.';
} else {
throw 'Screen capturing process is denied. Are you enabled flag: "Enable screen capture support in getUserMedia"?';
}
}
}
</script>
<!-- screen capturing stream -->
<script>
var old_stream;
function captureScreen() {
getScreenId(function (error, sourceId, screen_constraints) {
console.info('getScreenId', error, sourceId, screen_constraints);
getUserMedia(function(stream) {
old_stream = stream;
console.log(JSON.stringify(screen_constraints, null, '\t'), stream);
offererPeer({
stream: stream
});
}, screen_constraints);
});
}
var maxTries = 0;
function showChromeExtensionStatus() {
if (typeof window.getChromeExtensionStatus !== 'function') return captureScreen();
var gotResponse;
window.getChromeExtensionStatus(function(status) {
gotResponse = true;
console.info('getChromeExtensionStatus', status);
captureScreen();
});
maxTries++;
if (maxTries > 15) return;
setTimeout(function() {
if (!gotResponse) showChromeExtensionStatus();
}, 1000);
}
showChromeExtensionStatus();
</script>
<!-- switch streams to audio+video -->
<script>
document.getElementById('switch-stream').onclick = function() {
this.disabled = true;
if(old_stream) old_stream.stop();
getUserMedia(function(stream) {
console.log('audio+video stream', stream);
offererPeer({
stream: stream,
switching: true
});
});
};
</script>
<!-- CSS -->
<style>
html { background: #eee; }
button, input[type=button] {
-moz-border-radius: 3px;
-moz-transition: none;
-webkit-transition: none;
background: #0370ea;
background: -moz-linear-gradient(top, #008dfd 0, #0370ea 100%);
background: -webkit-linear-gradient(top, #008dfd 0, #0370ea 100%);
border: 1px solid #076bd2;
border-radius: 3px;
color: #fff;
display: inline-block;
font-family: inherit;
font-size: .8em;
font-size: 1.5em;
line-height: 1.3;
padding: 5px 12px;
text-align: center;
text-shadow: 1px 1px 1px #076bd2;
}
button:hover, input[type=button]:hover { background: rgb(9, 147, 240); }
button:active, input[type=button]:active { background: rgb(10, 118, 190); }
button[disabled], input[type=button][disabled] {
background: none;
border: 1px solid rgb(187, 181, 181);
color: gray;
text-shadow: none;
}
.videos-container {
background: white;
border: 2px solid black;
border-radius: 0.2em;
display: inline-block;
margin: 2em .2em;
padding: .1em;
vertical-align: top;
}
.videos-container h2 {
border: 0;
border-top: 1px solid black;
display: block;
margin: 0;
text-align: center;
}
video {
background: black;
height: 15em;
width: 20em;
}
</style>
<section class="experiment">
<h2 class="header" id="feedback">Feedback</h2>
<div><textarea id="message" style="height: 8em; margin: .2em; width: 98%; border: 1px solid rgb(189, 189, 189); outline: none; resize: vertical;" placeholder="Have any message? Suggestions or something went wrong?"></textarea></div>
<button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left:1em;">Enter your email too; if you want "direct" reply!</small>
</section>
<script src="https://cdn.webrtc-experiment.com/commits.js" async></script>