美文网首页FFmpeg音视频直播技术iOS音视频开发
通过WebRTC进行实时通信-拍照片并通过数据通道传输

通过WebRTC进行实时通信-拍照片并通过数据通道传输

作者: 音视频直播技术专家 | 来源:发表于2018-10-22 13:31 被阅读11次

    你将学到什么

    在本步骤中,你将学习如何:

    • 拍照片并从 canvas无素中获得数据
    • 与远端用户交换图像数据

    本步骤的完整版本在 step-06目录下。

    它是如何工作的

    将面已经学习了如何使用RTCDataChannel 交换广本数据。 这步将用它来共享整个文件。在这个例子中通过 getUserMedia()捕获照片。

    这步的核心部分如下:

      1. 建立数据通道。 在这一步你不需要添加任何媒体流到 peer connection.
      1. 通过 getUserMedia()捕获用户的 webcam 视频流。
    var video = document.getElementById('video');
    
    function grabWebCamVideo() {
      console.log('Getting user media (video) ...');
      navigator.mediaDevices.getUserMedia({
        video: true
      })
      .then(gotStream)
      .catch(function(e) {
        alert('getUserMedia() error: ' + e.name);
      });
    }
    
      1. 当用户点击 Snap 按钮时,从视频流得到一个快照(一个视频帧)并在 canvas元素里显示它。
    var photo = document.getElementById('photo');
    var photoContext = photo.getContext('2d');
    
    function snapPhoto() {
      photoContext.drawImage(video, 0, 0, photo.width, photo.height);
      show(photo, sendBtn);
    }
    
      1. 当用户点击 Send按钮时,将图片转成字节并通过数据通道发送出去:
    function sendPhoto() {
      // Split data channel message in chunks of this byte length.
      var CHUNK_LEN = 64000;
      var img = photoContext.getImageData(0, 0, photoContextW, photoContextH),
        len = img.data.byteLength,
        n = len / CHUNK_LEN | 0;
    
      console.log('Sending a total of ' + len + ' byte(s)');
      dataChannel.send(len);
    
      // split the photo and send in chunks of about 64KB
      for (var i = 0; i < n; i++) {
        var start = i * CHUNK_LEN,
          end = (i + 1) * CHUNK_LEN;
        console.log(start + ' - ' + (end - 1));
        dataChannel.send(img.data.subarray(start, end));
      }
    
      // send the reminder, if any
      if (len % CHUNK_LEN) {
        console.log('last ' + len % CHUNK_LEN + ' byte(s)');
        dataChannel.send(img.data.subarray(n * CHUNK_LEN));
      }
    }
    
      1. 接收端将数据通道中的字节转换回图片再显示给用户:
    function receiveDataChromeFactory() {
      var buf, count;
    
      return function onmessage(event) {
        if (typeof event.data === 'string') {
          buf = window.buf = new Uint8ClampedArray(parseInt(event.data));
          count = 0;
          console.log('Expecting a total of ' + buf.byteLength + ' bytes');
          return;
        }
    
        var data = new Uint8ClampedArray(event.data);
        buf.set(data, count);
    
        count += data.byteLength;
        console.log('count: ' + count);
    
        if (count === buf.byteLength) {
          // we're done: all data chunks have been received
          console.log('Done. Rendering photo.');
          renderPhoto(buf);
        }
      };
    }
    
    function renderPhoto(data) {
      var canvas = document.createElement('canvas');
      canvas.width = photoContextW;
      canvas.height = photoContextH;
      canvas.classList.add('incomingPhoto');
      // trail is the element holding the incoming images
      trail.insertBefore(canvas, trail.firstChild);
    
      var context = canvas.getContext('2d');
      var img = context.createImageData(photoContextW, photoContextH);
      img.data.set(data);
      context.putImageData(img, 0, 0);
    }
    

    获得代码

    用 step-06目录中的内容替换你工作目录中的内容。在work目录中的 index.html现在看起来像这样:

    <!DOCTYPE html>
    <html>
    
    <head>
    
      <title>Realtime communication with WebRTC</title>
    
      <link rel="stylesheet" href="/css/main.css" />
    
    </head>
    
    <body>
    
      <h1>Realtime communication with WebRTC</h1>
    
      <h2>
        <span>Room URL: </span><span id="url">...</span>
      </h2>
    
      <div id="videoCanvas">
        <video id="camera" autoplay></video>
        <canvas id="photo"></canvas>
      </div>
    
      <div id="buttons">
        <button id="snap">Snap</button><span> then </span><button id="send">Send</button>
        <span> or </span>
        <button id="snapAndSend">Snap &amp; Send</button>
      </div>
    
      <div id="incoming">
        <h2>Incoming photos</h2>
        <div id="trail"></div>
      </div>
    
      <script src="/socket.io/socket.io.js"></script>
      <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
      <script src="js/main.js"></script>
    
    </body>
    
    </html>
    

    如果在你的work目录下没有一直跟着codelab, 你可能需要安装step-06目录或你的当前目录的依赖。可以在你的目录下简单的运行下面的命令即可:

    npm install
    

    一旦安装后,如果Node.js没有运行的话,在你的工作目录下调用下面的命令来启动它:

    node index.js
    

    要确保你正在使用的index.js版本实现了 Sokcet.IO, 如果做了改变记得重启 Node.js。关于 Node和 Socket IO更多的信息查看 "为交换消息建立信令服务"一节。

    如果需要,点击"Allow"按钮允许应用使用你的webcam。 应该将创建一个随机的 room ID并将它添加到 URL里。 从浏览器的新的 tab或窗口地址栏中打开些 URL。

    点击 Snap & Send按钮,然后观察一下网页底部的另一个选项卡中输入区域。些应用在两个选项卡之间传输照片。

    你应该看到像下面这个样子:


    点滴

      1. 你如何改代码才能使尽可能的共享任意类型的文件呢?

    更多信息

    你学到了什么

    • 如何拍照并通过 canvas 无素获得数据。
    • 如何与远端用户交换数据。

    这步完整的版本在step-06目录下。

    相关文章

      网友评论

        本文标题:通过WebRTC进行实时通信-拍照片并通过数据通道传输

        本文链接:https://www.haomeiwen.com/subject/bigwzftx.html