使用WebRTC建立一个网络摄像头通讯 App

10 月 24 日- 25 日,一票难求的 RTC 2019 实时互联网大会将在北京举行,次日将举行「WebRTC 工做坊」,大会邀请了 Janus 开源项目做者,以及资深音视频工程师,分享 WebRTC 应用的开发实践与各个环节的迈坑经验,并与听众小范围深刻交流,名额有限,如今便可报名前端

WebRTC是一个协议,容许人们使用JavaScript在两点之间建立实时通信。ajax

咱们能够用这个结构使两个或更多浏览器之间实现直接交流,而不须要中心服务器。npm

服务器只须要在链接的时候被使用,所以每一个客户端知道如何链接彼此。后端

咱们可使用这个特性建立什么类型的App呢?例如,直接网络摄像头链接。点对点通话,文件共享,还有更多。浏览器

本教程我会介绍一个当你第一次使用的时候,会发出惊呼的App:一个网络摄像头通讯App.bash

咱们不会使用原始WebRTC API,然而,咱们须要注意不少细节。这就是library的做用,它们作出了很好的抽象,人们能够集中精力建立App而不是将精力花费的底层API上。服务器

其中一个library是PeerJS,它使得实时通讯变得很是简单。简单来讲就是WebRTC,它的抽象使得结果获取更快,以后你能够学习内部是如何运做的。网络

建议:当你创建一个App时候使用Bit分享到一个可重复利用的集合中,而且在你全部的项目中同步它们!不妨试一下,能够加快你的工做速度。并发

后端 首先咱们须要建立后端。尽管咱们会实现直接点对点通讯,起初的握手和合做须要中心服务器。异步

一旦握手完成,点点之间会直接交流,而再也不须要依靠后端。

PeerJS为咱们提供了这样一个服务器,安装过程很简单,容易运行。

在一个文件夹下,初始化一个npm项目使用npm init命令,使用npm install peer指令安装PeerJS,接着你可使用npx运行它:

Npx peerjs –port 9000

使用npx peerjs –help查看更多选择。

这就是你的后端。

如今咱们能够建立一个最简单的App,咱们设置一个接收端和一个发送端。

前端 首先建立一个接收端,链接PeerJS服务器,等待接收信息。第一个参数new Peer()为咱们的端点名称,咱们叫作receiver,使得表意更清晰。: 导入PeerJS客户端:

<script src="https://cdnjs.cloudflare.com/ajax/libs/peerjs/0.3.16/peer.min.js"></script>
复制代码

接着初始化Peer对象。当另外一个端点链接咱们的时候,Connection事件被调用。当接收到一些信息以后,data事件被调用:

const peer = new Peer('receiver', { host: 'localhost', port: 9000, path: '/' })
peer.on('connection', (conn) => {
  conn.on('data', (data) => {
    console.log(data);
  })
})

复制代码

让咱们建立通讯的另外一端。咱们称做sender,由于它会链接并发送信息到接收端。

初始化Peer对象,接着请求端点链接receiver端,接收端咱们以前已经建立好。一旦链接创建,open事件启动,接着调用send()方法来向接收端发送信息:

const peer = new Peer('sender', { host: 'localhost', port: 9000, path: '/' })
const conn = peer.connect('receiver')
conn.on('open', () => {
  conn.send('hi!')
})
复制代码

这就是最简单的例子。

首先打开接收端,接着打开发送端。接受者从发送者直接获取信息,不须要中心服务器。服务器只须要交换信息,确保两端链接。以后,就不会干预两端之间的交流。

这是一个很是基础的信息链接。

下一步,咱们不会发送信息,而是让两端彼此共享网络摄像头流。

在客户端,咱们没有使用peer.connect()链接,而是使用了peer.call():

const call = peer.call('receiver', localStream)
})
复制代码

在接收端,当接收到一个通话事件反馈以后,必须对此做出应答:

peer.on('call', call => {
  call.answer(localStream)
})
复制代码

就像电话交流同样,咱们不能自动回复每一个来电,必须明确的做出应答。

每一个通话中的LocalStream是什么?它是网络摄像头产生的流,咱们必须经过调用navigator.mediaDevices.getUserMedia()获得它,这是一个浏览器API。

这是一个异步通信,所以咱们使用async/await来等待执行,咱们须要将通话包裹在一个异步函数中,首先:

const startChat = async () => {
  const localStream = await navigator.mediaDevices.getUserMedia({
    video: true
  })
}
startChat()
复制代码

一旦咱们获得了localStream对象,能够将它分配给HTML网页中的一个video元素。咱们能够建立本地和远程视频元素:

333

将流分配给video#local元素:

document.querySelector('video#local').srcObject = localStream
复制代码

调用receiver端,传递localStream对象:

const call = peer.call('receiver', localStream)
复制代码

接收端的代码以下:

peer.on('call', call => {
  call.answer(localStream)
})
复制代码

咱们也须要获得媒体流。代码很是简单,和发送端相似,只是咱们把全部代码包裹在call事件反馈中:

peer.on('call', call => {
  const startChat = async () => {
    const localStream = await navigator.mediaDevices.getUserMedia({
      video: true
    })
    document.querySelector('video#local').srcObject = localStream
    call.answer(localStream)
  }
  startChat()
})
复制代码

展现远程流 咱们还须要添加最后一部分到发送端和接收端中。一旦从call对象的stream事件中获得远程流,咱们须要将它附加在video#remote元素上。

call.on('stream', remoteStream => {
  document.querySelector('video#remote').srcObject = remoteStream
})
复制代码

接收端代码以下:

peer.on('call', call => {
  const startChat = async () => {
    const localStream = await navigator.mediaDevices.getUserMedia({
      video: true
    })
    document.querySelector('video#local').srcObject = localStream
    call.answer(localStream)
    call.on('stream', remoteStream => {
      document.querySelector('video#remote').srcObject = remoteStream
    })
  }
  startChat()
})

复制代码

发送端代码以下:

const startChat = async () => {
  const localStream = await navigator.mediaDevices.getUserMedia({
    video: true
  })
  document.querySelector('video#local').srcObject = localStream
  const call = peer.call('receiver', localStream)
  call.on('stream', remoteStream => {
    document.querySelector('video#remote').srcObject = remoteStream
  })
}
startChat()
复制代码

当其中一端经过导向新网页或关闭浏览器标签关闭了链接以后,另外一端中止接收流,远程视频流中止。

总结 咱们使用WebRTC建立了一个很是简单的网络摄像头通讯App。建立了两个文件来处理两端通讯,可是不必这样作。你能够创建一个用户接口,容许用户本身决定是否须要调用,更重要的是,他们想与谁通话。能够容许用户输入用户名或者从列表中选择来实现这个功能。

相关文章
相关标签/搜索