summaryrefslogtreecommitdiffstats
path: root/content/test/data/media/peerconnection-call.html
blob: cade13d0c0f00458e849995906a035dff24bd4a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<html>
<head>
  <script type="text/javascript">
  $ = function(id) {
    return document.getElementById(id);
  };

  var gFirstConnection = null;
  var gSecondConnection = null;

  function call(constraints) {
    navigator.webkitGetUserMedia(constraints, okCallback, failedCallback);
  }

  function failedCallback(error) {
    document.title = 'getUserMedia request failed with code ' + error.code;
  }

  function okCallback(localStream) {
    var localStreamUrl = webkitURL.createObjectURL(localStream);
    $('local-view').src = localStreamUrl;

    callUsingStream(localStream);
  }

  function callUsingStream(localStream) {
    gFirstConnection = new webkitRTCPeerConnection(null, null);
    gFirstConnection.onicecandidate = onIceCandidateToFirst;
    gFirstConnection.addStream(localStream);
    gFirstConnection.createOffer(onOfferCreated);
  }

  function onOfferCreated(offer) {
    gFirstConnection.setLocalDescription(offer);

    receiveCall(offer.sdp);
  }

  function receiveCall(offerSdp) {
    gSecondConnection = new webkitRTCPeerConnection(null, null);
    gSecondConnection.onicecandidate = onIceCandidateToSecond;
    gSecondConnection.onaddstream = onRemoteStream;

    var parsedOffer = new RTCSessionDescription({ type: 'offer',
                                                  sdp: offerSdp });
    gSecondConnection.setRemoteDescription(parsedOffer);

    gSecondConnection.createAnswer(onAnswerCreated);
  }

  function onAnswerCreated(answer) {
    gSecondConnection.setLocalDescription(answer);
    handleAnswer(answer.sdp);
  }

  function handleAnswer(answerSdp) {
    var parsedAnswer = new RTCSessionDescription({ type: 'answer',
                                                   sdp: answerSdp });
    gFirstConnection.setRemoteDescription(parsedAnswer);
  }

  function onIceCandidateToFirst(event) {
    if (event.candidate) {
      var candidate = new RTCIceCandidate(event.candidate);
      gSecondConnection.addIceCandidate(candidate);
    }
  }

  function onIceCandidateToSecond(event) {
    if (event.candidate) {
      var candidate = new RTCIceCandidate(event.candidate);
      gFirstConnection.addIceCandidate(candidate);
    }
  }

  function onRemoteStream(e) {
    var remoteStreamUrl = webkitURL.createObjectURL(e.stream);
    var remoteVideo = $('remote-view');
    remoteVideo.src = remoteStreamUrl;

    waitForVideo(remoteVideo, 320, 240);
  }

  // TODO(phoglund): perhaps use the video detector in chrome/test/data/webrtc/?
  function waitForVideo(videoElement, width, height) {
    document.title = 'Waiting for video...';
    var canvas = $('canvas');
    setInterval(function() {
      var context = canvas.getContext('2d');
      context.drawImage(videoElement, 0, 0, width, height);
      var pixels = context.getImageData(0, 0, width, height).data;

      if (isVideoPlaying(pixels, width, height))
        testSuccessful();
    }, 100);
  }

  // This very basic video verification algorithm will be satisfied if any
  // pixels are nonzero in a small sample area in the middle. It relies on the
  // assumption that a video element with null source just presents zeroes.
  function isVideoPlaying(pixels, width, height) {
    // Sample somewhere near the middle of the image.
    var middle = width * height / 2;
    for (var i = 0; i < 20; i++) {
      if (pixels[middle + i] > 0) {
        return true;
      }
    }
    return false;
  }

  function testSuccessful() {
    document.title = 'OK';
  }
  </script>
</head>
<body>
  <table border="0">
    <tr>
      <td>Local Preview</td>
      <td>Remote Stream</td>
      <td>Capturing Canvas</td>
    </tr>
    <tr>
      <td><video width="320" height="240" id="local-view"
          autoplay="autoplay"></video></td>
      <td><video width="320" height="240" id="remote-view"
          autoplay="autoplay"></video></td>
      <td><canvas width="320" height="240" id="canvas"></canvas></td>
    </tr>
    <tr>
      <td colspan="3">You should see the same animated feed in all three
          displays (the canvas will lag a bit).
      </td>
  </table>
</body>
</html>