WebRTC实时通信系列教程9 数据通道图片传输

10 篇文章 0 订阅
10 篇文章 0 订阅

转载地址:https://blog.csdn.net/leytton/article/details/76838194

1、你将学到

  • 拍照并通过canvas标签获取图片数据.
  • 与远程用户交换图片数据.

 

完整示例代码在 step-06 目录下.

2、工作原理

前面你学习了如何使用 RTCDataChannel 交换文本消息.

这一节将讲解如何传输整个文件: 案例中通过 getUserMedia() 获取图片.

核心步骤如下:

  1. 建立数据通道. 此节中你不需要添加媒体流到P2P连接之中.
  2. 使用 getUserMedia() 获取取用户摄像头视频流:
 
  1. var video = document.getElementById('video');

  2.  
  3. function grabWebCamVideo() {

  4. console.log('Getting user media (video) ...');

  5. navigator.mediaDevices.getUserMedia({

  6. audio: false,

  7. video: true

  8. })

  9. .then(gotStream)

  10. .catch(function(e) {

  11. alert('getUserMedia() error: ' + e.name);

  12. });

  13. }

  1. 当用户点击 Snap(拍照) 按钮, 从视频流获取一张快照 (一个视频帧)并在canvas 标签显示:
 
  1. var photo = document.getElementById('photo');

  2. var photoContext = photo.getContext('2d');

  3.  
  4. function snapPhoto() {

  5. photoContext.drawImage(video, 0, 0, photo.width, photo.height);

  6. show(photo, sendBtn);

  7. }

  1. 当用户点击 Send(发送) 按钮, 将图片转换成字节并通过数据通道发送:
 
  1. function sendPhoto() {

  2. // Split data channel message in chunks of this byte length.

  3. var CHUNK_LEN = 64000;

  4. var img = photoContext.getImageData(0, 0, photoContextW, photoContextH),

  5. len = img.data.byteLength,

  6. n = len / CHUNK_LEN | 0;

  7.  
  8. console.log('Sending a total of ' + len + ' byte(s)');

  9. dataChannel.send(len);

  10.  
  11. // split the photo and send in chunks of about 64KB

  12. for (var i = 0; i < n; i++) {

  13. var start = i * CHUNK_LEN,

  14. end = (i + 1) * CHUNK_LEN;

  15. console.log(start + ' - ' + (end - 1));

  16. dataChannel.send(img.data.subarray(start, end));

  17. }

  18.  
  19. // send the reminder, if any

  20. if (len % CHUNK_LEN) {

  21. console.log('last ' + len % CHUNK_LEN + ' byte(s)');

  22. dataChannel.send(img.data.subarray(n * CHUNK_LEN));

  23. }

  24. }

  1. 接收端将接收到的信息字节转换成图片并展示:
 
  1. function receiveDataChromeFactory() {

  2. var buf, count;

  3.  
  4. return function onmessage(event) {

  5. if (typeof event.data === 'string') {

  6. buf = window.buf = new Uint8ClampedArray(parseInt(event.data));

  7. count = 0;

  8. console.log('Expecting a total of ' + buf.byteLength + ' bytes');

  9. return;

  10. }

  11.  
  12. var data = new Uint8ClampedArray(event.data);

  13. buf.set(data, count);

  14.  
  15. count += data.byteLength;

  16. console.log('count: ' + count);

  17.  
  18. if (count === buf.byteLength) {

  19. // we're done: all data chunks have been received

  20. console.log('Done. Rendering photo.');

  21. renderPhoto(buf);

  22. }

  23. };

  24. }

  25.  
  26. function renderPhoto(data) {

  27. var canvas = document.createElement('canvas');

  28. canvas.width = photoContextW;

  29. canvas.height = photoContextH;

  30. canvas.classList.add('incomingPhoto');

  31. // trail is the element holding the incoming images

  32. trail.insertBefore(canvas, trail.firstChild);

  33.  
  34. var context = canvas.getContext('2d');

  35. var img = context.createImageData(photoContextW, photoContextH);

  36. img.data.set(data);

  37. context.putImageData(img, 0, 0);

  38. }

3、获取代码

将step-06 中的index.html 文件替换掉 work 目录里的:

 
  1. <!DOCTYPE html>

  2. <html>

  3.  
  4. <head>

  5.  
  6. <title>Realtime communication with WebRTC</title>

  7.  
  8. <link rel="stylesheet" href="/css/main.css" />

  9.  
  10. </head>

  11.  
  12. <body>

  13.  
  14. <h1>Realtime communication with WebRTC</h1>

  15.  
  16. <h2>

  17. <span>Room URL: </span><span id="url">...</span>

  18. </h2>

  19.  
  20. <div id="videoCanvas">

  21. <video id="camera" autoplay></video>

  22. <canvas id="photo"></canvas>

  23. </div>

  24.  
  25. <div id="buttons">

  26. <button id="snap">Snap</button><span> then </span><button id="send">Send</button>

  27. <span> or </span>

  28. <button id="snapAndSend">Snap &amp; Send</button>

  29. </div>

  30.  
  31. <div id="incoming">

  32. <h2>Incoming photos</h2>

  33. <div id="trail"></div>

  34. </div>

  35.  
  36. <script src="/socket.io/socket.io.js"></script>

  37. <script src="js/lib/adapter.js"></script>

  38. <script src="js/main.js"></script>

  39.  
  40. </body>

  41.  
  42. </html>

在 work 目录下使用以下命令行运行Node服务器:

node index.js

(确保你使用的的 index.js 文件中是上一节中实现了Socket.IO的代码.)

如果需要浏览器允许网页调用摄像头.

应用将会创建一个随机房间ID并将其添加到URL. 在新标签中打开这个URL.

点击 Snap & Send 按钮,查看另一个标签中页面下方的接收区域.

你将会看到如下所示:

4、拓展

  1. 如何修改代码让其支持传输任何类型的文件?

5、更多资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值