Html程序  |  209行  |  5.51 KB

<!DOCTYPE html>
<html>
  <!--
  Copyright (c) 2013 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
  -->
<head>
<title>Video Effects Demo</title>
<style>
video {
  border:5px solid black;
  width:480px;
  height:360px;
}
button {
  font: 18px sans-serif;
  padding: 8px;
}
textarea {
  font-family: monospace;
  margin: 2px;
  width:480px;
  height:640px;
}
</style>
</head>
<body>
<table>
<tr>
<td><video id="vidlocal" autoplay></video></td>
<td><video id="vidprocessedlocal" autoplay></video></td>
<td><video id="vidremote" autoplay></video></td>
</tr>
<tr>
<td>Local Media Stream</td>
<td>Local Media Stream After Effect</td>
<td>Remote Media Stream</td>
</tr>
<tr>
</table>
<br>
<button id="startButton" onclick="start()">Start</button>
<button id="toggleEffectButton" onclick="toggleEffect()">Enable Effect</button>
<button id="callButton" onclick="call()">Call</button>
<button id="hangupButton" onclick="hangup()">Hang Up</button>
<br>
<embed id="plugin" type="application/x-ppapi-example-video-effects"
    width="320" height="240"/>

<script>
var RTCPeerConnection = webkitRTCPeerConnection;
var getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
var attachMediaStream = function(element, stream) {
  element.src = URL.createObjectURL(stream);
};
var startButton = document.getElementById('startButton');
var toggleEffectButton = document.getElementById('toggleEffectButton');
var callButton = document.getElementById('callButton');
var hangupButton = document.getElementById('hangupButton');

callButton.disabled = true;
hangupButton.disabled = true;
toggleEffectButton.disabled = true;
var pc1 = null;
var pc2 = null;
var localstream = null;
var processedLocalstream = null;
var effectsPlugin = null;
var effectsEnabled = false;

function trace(text) {
  // This function is used for logging.
  if (text[text.length - 1] == '\n') {
    text = text.substring(0, text.length - 1);
  }
  console.log((performance.now() / 1000).toFixed(3) + ": " + text);
}

function gotStream(stream){
  trace("Received local stream");
  // Call the polyfill wrapper to attach the media stream to this element.
  attachMediaStream(vidlocal, stream);
  localstream = stream;
  callButton.disabled = false;
  initEffect();
}

function start() {
  trace("Requesting local stream");
  startButton.disabled = true;
  // Call into getUserMedia via the polyfill (adapter.js).
  getUserMedia({audio:false, video:true},
                gotStream, function() {});
}  

function onRegisterStreamDone() {
  vidprocessedlocal.src = URL.createObjectURL(processedLocalstream);
  toggleEffectButton.disabled = false;
}

function HandleMessage(message_event) {
  if (message_event.data) {
    if (message_event.data == 'DoneRegistering') {
      onRegisterStreamDone();
    } else {
      trace(message_event.data);
    }
  }
}

function initEffect() {
  var url = URL.createObjectURL(localstream);
  processedLocalstream = new webkitMediaStream([]);
  var processedStreamUrl = URL.createObjectURL(processedLocalstream);
  effectsPlugin.postMessage(
      'registerStream' + ' ' + url + ' ' + processedStreamUrl);
}

function toggleEffect() {
  effectsEnabled = !effectsEnabled;
  if (effectsEnabled) {
    toggleEffectButton.innerHTML = 'Disable Effect';
    effectsPlugin.postMessage('effectOn');
  } else {
    toggleEffectButton.innerHTML = 'Enable Effect';
    effectsPlugin.postMessage('effectOff');
  }
}
    
function call() {
  callButton.disabled = true;
  hangupButton.disabled = false;
  trace("Starting call");
  var servers = null;
  pc1 = new RTCPeerConnection(servers);
  trace("Created local peer connection object pc1");
  pc1.onicecandidate = iceCallback1; 
  pc2 = new RTCPeerConnection(servers);
  trace("Created remote peer connection object pc2");
  pc2.onicecandidate = iceCallback2;
  pc2.onaddstream = gotRemoteStream; 

  pc1.addStream(processedLocalstream);
  trace("Adding Local Stream to peer connection");
  
  pc1.createOffer(gotDescription1);
}

function gotDescription1(desc){
  pc1.setLocalDescription(desc);
  trace("Offer from pc1 \n" + desc.sdp);
  pc2.setRemoteDescription(desc);
  // 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.
  var sdpConstraints = {'mandatory': {
                        'OfferToReceiveAudio':true, 
                        'OfferToReceiveVideo':true }};
  pc2.createAnswer(gotDescription2, null, sdpConstraints);
}

function gotDescription2(desc){
  pc2.setLocalDescription(desc);
  trace("Answer from pc2 \n" + desc.sdp);
  pc1.setRemoteDescription(desc);
}

function hangup() {
  trace("Ending call");
  pc1.close(); 
  pc2.close();
  pc1 = null;
  pc2 = null;
  hangupButton.disabled = true;
  callButton.disabled = false;
}

function gotRemoteStream(e){
  vidremote.src = URL.createObjectURL(e.stream);
  trace("Received remote stream");
}

function iceCallback1(event){
  if (event.candidate) {
    pc2.addIceCandidate(new RTCIceCandidate(event.candidate));
    trace("Local ICE candidate: \n" + event.candidate.candidate);
  }
}
      
function iceCallback2(event){
  if (event.candidate) {
    pc1.addIceCandidate(new RTCIceCandidate(event.candidate));
    trace("Remote ICE candidate: \n " + event.candidate.candidate);
  }
}

function InitializePlugin() {
  effectsPlugin = document.getElementById('plugin');
  effectsPlugin.addEventListener('message', HandleMessage, false);
}

document.addEventListener('DOMContentLoaded', InitializePlugin, false);
</script>
</body>
</html>