Add an exponential backoff to rechecking the app list doodle.
[chromium-blink-merge.git] / ppapi / examples / video_effects / video_effects.html
blobf7dd0ce0abdf91b31b20d4322611448c59433f41
1 <!DOCTYPE html>
2 <html>
3 <!--
4 Copyright (c) 2013 The Chromium Authors. All rights reserved.
5 Use of this source code is governed by a BSD-style license that can be
6 found in the LICENSE file.
7 -->
8 <head>
9 <title>Video Effects Demo</title>
10 <style>
11 video {
12 border:5px solid black;
13 width:480px;
14 height:360px;
16 button {
17 font: 18px sans-serif;
18 padding: 8px;
20 textarea {
21 font-family: monospace;
22 margin: 2px;
23 width:480px;
24 height:640px;
26 </style>
27 </head>
28 <body>
29 <table>
30 <tr>
31 <td><video id="vidlocal" autoplay></video></td>
32 <td><video id="vidprocessedlocal" autoplay></video></td>
33 <td><video id="vidremote" autoplay></video></td>
34 </tr>
35 <tr>
36 <td>Local Media Stream</td>
37 <td>Local Media Stream After Effect</td>
38 <td>Remote Media Stream</td>
39 </tr>
40 <tr>
41 </table>
42 <br>
43 <button id="startButton" onclick="start()">Start</button>
44 <button id="toggleEffectButton" onclick="toggleEffect()">Enable Effect</button>
45 <button id="callButton" onclick="call()">Call</button>
46 <button id="hangupButton" onclick="hangup()">Hang Up</button>
47 <br>
48 <embed id="plugin" type="application/x-ppapi-example-video-effects"
49 width="320" height="240"/>
51 <script>
52 var RTCPeerConnection = webkitRTCPeerConnection;
53 var getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
54 var attachMediaStream = function(element, stream) {
55 element.src = URL.createObjectURL(stream);
57 var startButton = document.getElementById('startButton');
58 var toggleEffectButton = document.getElementById('toggleEffectButton');
59 var callButton = document.getElementById('callButton');
60 var hangupButton = document.getElementById('hangupButton');
62 callButton.disabled = true;
63 hangupButton.disabled = true;
64 toggleEffectButton.disabled = true;
65 var pc1 = null;
66 var pc2 = null;
67 var localstream = null;
68 var processedLocalstream = null;
69 var effectsPlugin = null;
70 var effectsEnabled = false;
72 function trace(text) {
73 // This function is used for logging.
74 if (text[text.length - 1] == '\n') {
75 text = text.substring(0, text.length - 1);
77 console.log((performance.now() / 1000).toFixed(3) + ": " + text);
80 function gotStream(stream){
81 trace("Received local stream");
82 // Call the polyfill wrapper to attach the media stream to this element.
83 attachMediaStream(vidlocal, stream);
84 localstream = stream;
85 callButton.disabled = false;
86 initEffect();
89 function start() {
90 trace("Requesting local stream");
91 startButton.disabled = true;
92 // Call into getUserMedia via the polyfill (adapter.js).
93 getUserMedia({audio:false, video:true},
94 gotStream, function() {});
97 function onRegisterStreamDone() {
98 vidprocessedlocal.src = URL.createObjectURL(processedLocalstream);
99 toggleEffectButton.disabled = false;
102 function HandleMessage(message_event) {
103 if (message_event.data) {
104 if (message_event.data == 'DoneRegistering') {
105 onRegisterStreamDone();
106 } else {
107 trace(message_event.data);
112 function initEffect() {
113 var url = URL.createObjectURL(localstream);
114 processedLocalstream = new webkitMediaStream([]);
115 var processedStreamUrl = URL.createObjectURL(processedLocalstream);
116 effectsPlugin.postMessage(
117 'registerStream' + ' ' + url + ' ' + processedStreamUrl);
120 function toggleEffect() {
121 effectsEnabled = !effectsEnabled;
122 if (effectsEnabled) {
123 toggleEffectButton.innerHTML = 'Disable Effect';
124 effectsPlugin.postMessage('effectOn');
125 } else {
126 toggleEffectButton.innerHTML = 'Enable Effect';
127 effectsPlugin.postMessage('effectOff');
131 function call() {
132 callButton.disabled = true;
133 hangupButton.disabled = false;
134 trace("Starting call");
135 var servers = null;
136 pc1 = new RTCPeerConnection(servers);
137 trace("Created local peer connection object pc1");
138 pc1.onicecandidate = iceCallback1;
139 pc2 = new RTCPeerConnection(servers);
140 trace("Created remote peer connection object pc2");
141 pc2.onicecandidate = iceCallback2;
142 pc2.onaddstream = gotRemoteStream;
144 pc1.addStream(processedLocalstream);
145 trace("Adding Local Stream to peer connection");
147 pc1.createOffer(gotDescription1);
150 function gotDescription1(desc){
151 pc1.setLocalDescription(desc);
152 trace("Offer from pc1 \n" + desc.sdp);
153 pc2.setRemoteDescription(desc);
154 // Since the "remote" side has no media stream we need
155 // to pass in the right constraints in order for it to
156 // accept the incoming offer of audio and video.
157 var sdpConstraints = {'mandatory': {
158 'OfferToReceiveAudio':true,
159 'OfferToReceiveVideo':true }};
160 pc2.createAnswer(gotDescription2, null, sdpConstraints);
163 function gotDescription2(desc){
164 pc2.setLocalDescription(desc);
165 trace("Answer from pc2 \n" + desc.sdp);
166 pc1.setRemoteDescription(desc);
169 function hangup() {
170 trace("Ending call");
171 pc1.close();
172 pc2.close();
173 pc1 = null;
174 pc2 = null;
175 hangupButton.disabled = true;
176 callButton.disabled = false;
179 function gotRemoteStream(e){
180 vidremote.src = URL.createObjectURL(e.stream);
181 trace("Received remote stream");
184 function iceCallback1(event){
185 if (event.candidate) {
186 pc2.addIceCandidate(new RTCIceCandidate(event.candidate));
187 trace("Local ICE candidate: \n" + event.candidate.candidate);
191 function iceCallback2(event){
192 if (event.candidate) {
193 pc1.addIceCandidate(new RTCIceCandidate(event.candidate));
194 trace("Remote ICE candidate: \n " + event.candidate.candidate);
198 function InitializePlugin() {
199 effectsPlugin = document.getElementById('plugin');
200 effectsPlugin.addEventListener('message', HandleMessage, false);
203 document.addEventListener('DOMContentLoaded', InitializePlugin, false);
204 </script>
205 </body>
206 </html>