在本节课程中, 我们将学习以下内容:
本节的完整版代码位于 step-06
文件夹中。
前面的小节中, 我们使用 RTCDataChannel
来传递文本消息。
本节课程, 将学习如何发送文件: 下面的示例发送的是通过 getUserMedia()
捕获的照片文件, 原理都是一样的。
核心内容包括:
getUserMedia()
获取摄像头拍到的视频。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);
});
}
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);
}
function sendPhoto() {
// 将数据分块的字节数长度;
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));
}
}
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文件的内容为:
Realtime communication with WebRTC
Realtime communication with WebRTC
Room URL: ...
Incoming photos
如果没有执行上一节的操作, 需要在 step-06目录, 或者工作目录下, 安装相应的依赖, 命令如下:
cnpm install
安装完成后, 需要启动 Node.js 服务器, 在work目录下执行命令:
node index.js
请确认 index.js 文件的内容中包含了 Socket.IO 相关的内容, 参考前一小节。更多关于Node和Socket.IO的内容, 请参考 7_Set_up_signaling_service.md。
如果弹出对话框, 请点击Allow(允许)按钮, 授权使用本地摄像头。
本应用会创建一个随机的房间ID, 并将此ID加入URL中。
然后在一个新的标签或窗口打开同样的URL。
点击 Snap
和 Send
按钮, 然后查看另一个标签页中, 是否显示了传过去的照片。
这个应用主要是实现了在不同标签页/不同窗口之间传输照片。
界面看起来类似这样:
本节的完整版代码位于 step-06
文件夹中。
原文链接: https://codelabs.developers.google.com/codelabs/webrtc-web/#8
翻译人员: 铁锚 - https://blog.csdn.net/renfufei
翻译日期: 2018年08月27日
WebRTC基础实践 系列文章目录如下: