Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added captureStream to peer connection demo
- Loading branch information
Showing
22 changed files
with
2,489 additions
and
22 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. | ||
*/ | ||
|
||
canvas { | ||
background-color: #ccc; | ||
height: 231px; | ||
margin: 0 20px 0 0; | ||
vertical-align: top; | ||
width: calc(50% - 12px); | ||
} | ||
|
||
video { | ||
height: 231px; | ||
margin: 0 0 20px 0; | ||
object-fit: cover; | ||
width: calc(50% - 12px); | ||
} | ||
|
||
@media screen and (max-width: 400px) { | ||
canvas { | ||
margin: 0 10px 0 0; | ||
width: calc(50% - 7px); | ||
} | ||
video { | ||
margin: 0 0 20px 0; | ||
width: calc(50% - 7px); | ||
} | ||
} | ||
|
||
@media screen and (max-width: 700px) { | ||
canvas { | ||
border: 1px solid #ccc; | ||
width: calc(50% - 14px); | ||
} | ||
video { | ||
object-fit: inherit; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<!DOCTYPE html> | ||
<!-- | ||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. | ||
--> | ||
<html> | ||
<head> | ||
|
||
<meta charset="utf-8"> | ||
<meta name="description" content="WebRTC code samples"> | ||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1"> | ||
<meta itemprop="description" content="Client-side WebRTC code samples"> | ||
<meta itemprop="image" content="../../../images/webrtc-icon-192x192.png"> | ||
<meta itemprop="name" content="WebRTC code samples"> | ||
<meta name="mobile-web-app-capable" content="yes"> | ||
<meta id="theme-color" name="theme-color" content="#ffffff"> | ||
|
||
<base target="_blank"> | ||
|
||
<title>Canvas to peer connection</title> | ||
|
||
<link rel="icon" sizes="192x192" href="../../../images/webrtc-icon-192x192.png"> | ||
<link href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet" type="text/css"> | ||
<link rel="stylesheet" href="../../../css/main.css" /> | ||
<link rel="stylesheet" href="css/main.css" /> | ||
|
||
</head> | ||
|
||
<body> | ||
|
||
<div id="container"> | ||
|
||
<h1><a href="//webrtc.github.io/samples/" title="WebRTC samples homepage">WebRTC samples</a> <span>Stream from canvas to peer connection</span></h1> | ||
|
||
<canvas></canvas> | ||
<video autoplay></video> | ||
|
||
<p>Click and drag on the canvas element (on the left) to move the teapot.</p> | ||
|
||
<p>This demo requires Firefox 43 or above, Chrome 51 or above, or Chrome 50 with <strong>Experimental Web Platform features</strong> enabled.</p> | ||
|
||
<p>The teapot is drawn on the canvas element using WebGL. A stream is captured from the canvas using its <code>captureStream()</code> method and streamed via a peer connection to the video element on the right.</p> | ||
|
||
<p>View the browser console to see logging.</p> | ||
|
||
<p>Several variables are in global scope, so you can inspect them from the console: <code>canvas</code>, <code>video</code>, <code>localPeerConnection</code>, <code>remotePeerConnection</code> and <code>stream</code>.</p> | ||
|
||
<p>For more information about RTCPeerConnection, see <a href="http://www.html5rocks.com/en/tutorials/webrtc/basics/" title="HTML5 Rocks article about WebRTC by Sam Dutton">Getting Started With WebRTC</a>.</p> | ||
|
||
<a href="https://github.com/webrtc/samples/tree/gh-pages/src/content/capture/canvas-stream" title="View source for this page on GitHub" id="viewSource">View source on GitHub</a> | ||
|
||
</div> | ||
|
||
<!-- Teapot code --> | ||
<script src="js/third_party/webgl-utils.js"></script> | ||
<script src="js/third_party/webgl-debug.js"></script> | ||
<script src="js/third_party/matrix4x4.js"></script> | ||
<script src="js/third_party/cameracontroller.js"></script> | ||
<script src="js/third_party/teapot-streams.js"></script> | ||
<script src="js/third_party/demo.js"></script> | ||
|
||
<script src="../../../js/adapter.js"></script> | ||
<script src="../../../js/common.js"></script> | ||
<script src="js/main.js"></script> | ||
|
||
<script src="../../../js/lib/ga.js"></script> | ||
</body> | ||
</html> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. | ||
*/ | ||
|
||
/* global main */ | ||
|
||
'use strict'; | ||
|
||
var canvas = document.querySelector('canvas'); | ||
var video = document.querySelector('video'); | ||
|
||
var pc1; | ||
var pc2; | ||
var offerOptions = { | ||
offerToReceiveAudio: 1, | ||
offerToReceiveVideo: 1 | ||
}; | ||
|
||
var startTime; | ||
|
||
video.addEventListener('loadedmetadata', function() { | ||
trace('Remote video videoWidth: ' + this.videoWidth + | ||
'px, videoHeight: ' + this.videoHeight + 'px'); | ||
}); | ||
|
||
video.onresize = function() { | ||
trace('Remote video size changed to ' + | ||
video.videoWidth + 'x' + video.videoHeight); | ||
// We'll use the first onsize callback as an indication that video has started | ||
// playing out. | ||
if (startTime) { | ||
var elapsedTime = window.performance.now() - startTime; | ||
trace('Setup time: ' + elapsedTime.toFixed(3) + 'ms'); | ||
startTime = null; | ||
} | ||
}; | ||
|
||
// Call main() in demo.js | ||
main(); | ||
|
||
var stream = canvas.captureStream(); | ||
trace('Got stream from canvas'); | ||
|
||
call(); | ||
|
||
function call() { | ||
trace('Starting call'); | ||
startTime = window.performance.now(); | ||
var videoTracks = stream.getVideoTracks(); | ||
var audioTracks = stream.getAudioTracks(); | ||
if (videoTracks.length > 0) { | ||
trace('Using video device: ' + videoTracks[0].label); | ||
} | ||
if (audioTracks.length > 0) { | ||
trace('Using audio device: ' + audioTracks[0].label); | ||
} | ||
var servers = null; | ||
pc1 = new RTCPeerConnection(servers); | ||
trace('Created local peer connection object pc1'); | ||
pc1.onicecandidate = function(e) { | ||
onIceCandidate(pc1, e); | ||
}; | ||
pc2 = new RTCPeerConnection(servers); | ||
trace('Created remote peer connection object pc2'); | ||
pc2.onicecandidate = function(e) { | ||
onIceCandidate(pc2, e); | ||
}; | ||
pc1.oniceconnectionstatechange = function(e) { | ||
onIceStateChange(pc1, e); | ||
}; | ||
pc2.oniceconnectionstatechange = function(e) { | ||
onIceStateChange(pc2, e); | ||
}; | ||
pc2.onaddstream = gotRemoteStream; | ||
|
||
pc1.addStream(stream); | ||
trace('Added local stream to pc1'); | ||
|
||
trace('pc1 createOffer start'); | ||
pc1.createOffer(onCreateOfferSuccess, onCreateSessionDescriptionError, | ||
offerOptions); | ||
} | ||
|
||
function onCreateSessionDescriptionError(error) { | ||
trace('Failed to create session description: ' + error.toString()); | ||
} | ||
|
||
function onCreateOfferSuccess(desc) { | ||
trace('Offer from pc1\n' + desc.sdp); | ||
trace('pc1 setLocalDescription start'); | ||
pc1.setLocalDescription(desc, function() { | ||
onSetLocalSuccess(pc1); | ||
}, onSetSessionDescriptionError); | ||
trace('pc2 setRemoteDescription start'); | ||
pc2.setRemoteDescription(desc, function() { | ||
onSetRemoteSuccess(pc2); | ||
}, onSetSessionDescriptionError); | ||
trace('pc2 createAnswer start'); | ||
// Since the 'remote' side has no media stream we need | ||
// to pass in the right constraints in order for it to | ||
// accept the incoming offer of audio and video. | ||
pc2.createAnswer(onCreateAnswerSuccess, onCreateSessionDescriptionError); | ||
} | ||
|
||
function onSetLocalSuccess(pc) { | ||
trace(getName(pc) + ' setLocalDescription complete'); | ||
} | ||
|
||
function onSetRemoteSuccess(pc) { | ||
trace(getName(pc) + ' setRemoteDescription complete'); | ||
} | ||
|
||
function onSetSessionDescriptionError(error) { | ||
trace('Failed to set session description: ' + error.toString()); | ||
} | ||
|
||
function gotRemoteStream(e) { | ||
video.srcObject = e.stream; | ||
trace('pc2 received remote stream'); | ||
} | ||
|
||
function onCreateAnswerSuccess(desc) { | ||
trace('Answer from pc2:\n' + desc.sdp); | ||
trace('pc2 setLocalDescription start'); | ||
pc2.setLocalDescription(desc, function() { | ||
onSetLocalSuccess(pc2); | ||
}, onSetSessionDescriptionError); | ||
trace('pc1 setRemoteDescription start'); | ||
pc1.setRemoteDescription(desc, function() { | ||
onSetRemoteSuccess(pc1); | ||
}, onSetSessionDescriptionError); | ||
} | ||
|
||
function onIceCandidate(pc, event) { | ||
if (event.candidate) { | ||
getOtherPc(pc).addIceCandidate(new RTCIceCandidate(event.candidate), | ||
function() { | ||
onAddIceCandidateSuccess(pc); | ||
}, | ||
function(err) { | ||
onAddIceCandidateError(pc, err); | ||
} | ||
); | ||
trace(getName(pc) + ' ICE candidate: \n' + event.candidate.candidate); | ||
} | ||
} | ||
|
||
function onAddIceCandidateSuccess(pc) { | ||
trace(getName(pc) + ' addIceCandidate success'); | ||
} | ||
|
||
function onAddIceCandidateError(pc, error) { | ||
trace(getName(pc) + ' failed to add ICE Candidate: ' + error.toString()); | ||
} | ||
|
||
function onIceStateChange(pc, event) { | ||
if (pc) { | ||
trace(getName(pc) + ' ICE state: ' + pc.iceConnectionState); | ||
console.log('ICE state change event: ', event); | ||
} | ||
} | ||
|
||
function getName(pc) { | ||
return (pc === pc1) ? 'pc1' : 'pc2'; | ||
} | ||
|
||
function getOtherPc(pc) { | ||
return (pc === pc1) ? pc2 : pc1; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by a BSD-style license | ||
* that can be found in the LICENSE file in the root of the source | ||
* tree. | ||
*/ | ||
/* eslint-env node */ | ||
|
||
'use strict'; | ||
// This is a basic test file for use with testling. | ||
// The test script language comes from tape. | ||
var test = require('tape'); | ||
|
||
var webdriver = require('selenium-webdriver'); | ||
var seleniumHelpers = require('webrtc-utilities').seleniumLib; | ||
|
||
test('PeerConnection pc1 sample', function(t) { | ||
var driver = seleniumHelpers.buildDriver(); | ||
|
||
driver.get('file://' + process.cwd() + | ||
'/src/content/peerconnection/pc1/index.html') | ||
.then(function() { | ||
t.pass('page loaded'); | ||
return driver.findElement(webdriver.By.id('startButton')).click(); | ||
}) | ||
.then(function() { | ||
t.pass('got media'); | ||
return driver.findElement(webdriver.By.id('callButton')).click(); | ||
}) | ||
.then(function() { | ||
return driver.wait(function() { | ||
return driver.executeScript( | ||
'return pc2 && pc2.iceConnectionState === \'connected\';'); | ||
}, 30 * 1000); | ||
}) | ||
.then(function() { | ||
t.pass('pc2 ICE connected'); | ||
return driver.findElement(webdriver.By.id('hangupButton')).click(); | ||
}) | ||
.then(function() { | ||
return driver.wait(function() { | ||
return driver.executeScript('return pc1 === null'); | ||
}, 30 * 1000); | ||
}) | ||
.then(function() { | ||
t.pass('hangup'); | ||
t.end(); | ||
}) | ||
.then(null, function(err) { | ||
t.fail(err); | ||
t.end(); | ||
}); | ||
}); |
Oops, something went wrong.