WebRTC 的黎明
The Dawn of WebRTC 机翻
原文:The Dawn of WebRTC - SitePoint
Web 实时通信 (WebRTC) 旨在为开发人员提供使用简单 JavaScript API 创建高清视频和音频呼叫的能力。这些 API 直接嵌入在浏览器中,无需插件、下载或任何类型的安装即可启动和运行。
谷歌花了大约 2 亿美元将这项技术开源给开发社区。WebRTC 使用多种视频和音频编解码器,使任何人都能够创建下一代通信应用程序,而无需支付许可或版税。
有哪些可能性?
我们才刚刚开始了解 WebRTC 将如何改变通信行业。我们正在看到使用 WebRTC 创建的所有类型的应用程序。最具标志性的例子之一是亚马逊的 Mayday Button。它展示了大大小小的公司如何利用 WebRTC 的真正力量。
WebRTC 为您带来了许多功能来增强您的应用程序,例如:
- 视频通信:在浏览器之间创建安全和高清的音频和视频流
- 文件共享和消息传递:在浏览器之间安全地连接和共享数据,无需将文件上传到云或网络服务器。数据直接在连接的对等点之间发送
- 电话到浏览器: WebRTC 允许公共交换电话网络 (PSTN) 和浏览器之间的连接。您可以使用 HTML5 中的新 API、SIP 网关和 WebRTC 从一个位置拨打和接听电话
- 移动到移动: WebRTC 不仅适用于 Web,还有适用于 iOS 和 Android 的原生库利用 WebRTC 的功能
- 机器对机器: WebRTC 可嵌入到需要机器对机器通信的系统中,例如物联网。Google Chromecast 是在正常用例之外使用 WebRTC 的完美示例
了解 WebRTC API
WebRTC 依赖于三个直接嵌入到 Web 浏览器中的 JavaScript API,无需客户端或浏览器插件即可与另一个启用 WebRTC 的浏览器直接通信。这些 API 是:
- MediaStream(又名 getUserMedia)允许您访问用户使用的设备的摄像头、麦克风或屏幕。作为附加的安全层,在您被允许流式传输他们的媒体之前,用户将拥有访问权限。如果用户从安全连接 (HTTPS) 连接,则用户只需为应用程序授予一次访问权限,但如果您从非安全连接 (HTTP) 连接,则每次应用程序需要访问权限时都会提示用户
- RTCPeerConnection(又名 PeerConnection)允许两个用户直接通信,点对点。它对发送到本地计算机和从本地计算机发送到接收媒体的远程对等体的媒体进行编码和解码。
- RTCDataChannel (aka DataChannel) 代表两个对等点之间的双向数据通道。它搭载在 RTCPeerConnection 之上,允许您直接在两个连接的对等方之间安全地发送数据。
WebRTC 入门
我们将从一个简单的照相亭应用程序开始,它允许您使用网络摄像头捕获图像并将一些 CSS 过滤器应用于捕获的图像。它将教您使用 MediaStream API 开始使用 WebRTC 的基础知识。它是Google 团队创建的示例应用程序的轻微修改版本
HTML
在下面的 HTML 代码中,您将看到创建您的第一个 WebRTC Web 应用程序所需的基础知识。WebRTC 利用 HTML5 `video` 元素来呈现本地和远程视频流。此外,我们将使用 `canvas` 元素制作本地视频流的快照以应用过滤器:
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-markup"><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>div</span> <span style="color:#ffcb6b">class</span><span style="color:#ff5572"><span style="color:#c792ea">=</span><span style="color:#c792ea">"</span>m-content<span style="color:#c792ea">"</span></span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>h1</span><span style="color:#c792ea">></span></span>getUserMedia + CSS filters demo<span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>h1</span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>div</span> <span style="color:#ffcb6b">class</span><span style="color:#ff5572"><span style="color:#c792ea">=</span><span style="color:#c792ea">"</span>photo-booth<span style="color:#c792ea">"</span></span><span style="color:#c792ea">></span></span><span style="color:#697098"><!-- local video stream will be rendered to the video tag --></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>video</span> <span style="color:#ffcb6b">autoplay</span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>video</span><span style="color:#c792ea">></span></span><span style="color:#697098"><!-- a copy of the stream will be made and css filters applied --></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>canvas</span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>canvas</span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>div</span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>div</span> <span style="color:#ffcb6b">class</span><span style="color:#ff5572"><span style="color:#c792ea">=</span><span style="color:#c792ea">"</span>buttons<span style="color:#c792ea">"</span></span><span style="color:#c792ea">></span></span><span style="color:#697098"><!-- call getUserMedia() to access webcam and give permission --></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>button</span> <span style="color:#ffcb6b">id</span><span style="color:#ff5572"><span style="color:#c792ea">=</span><span style="color:#c792ea">"</span>start<span style="color:#c792ea">"</span></span><span style="color:#c792ea">></span></span>Access Webcam<span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>button</span><span style="color:#c792ea">></span></span><span style="color:#697098"><!-- take a snapshot from your webcam and render it to the canvas tag --></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>button</span> <span style="color:#ffcb6b">id</span><span style="color:#ff5572"><span style="color:#c792ea">=</span><span style="color:#c792ea">"</span>snapshot<span style="color:#c792ea">"</span></span><span style="color:#c792ea">></span></span>Take a Snapshot<span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>button</span><span style="color:#c792ea">></span></span><span style="color:#697098"><!-- sort through the available css filters --></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"><</span>button</span> <span style="color:#ffcb6b">id</span><span style="color:#ff5572"><span style="color:#c792ea">=</span><span style="color:#c792ea">"</span>filter<span style="color:#c792ea">"</span></span><span style="color:#c792ea">></span></span>Change Filter<span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>button</span><span style="color:#c792ea">></span></span><span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>div</span><span style="color:#c792ea">></span></span>
<span style="color:#ff5572"><span style="color:#ff5572"><span style="color:#c792ea"></</span>div</span><span style="color:#c792ea">></span></span></code></span></span>
JavaScript
该navigator.getUserMedia()
方法是 getUserMedia API 提供的方法,它允许您从用户那里检索流。在撰写本文时,需要为不同的供应商前缀定义它,以使该应用程序在所有 WebRTC 兼容浏览器上工作:Chrome、Firefox、Opera。我们可以通过以下代码实现这个目标:
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript"><span style="color:#bfc7d5">navigator</span><span style="color:#c792ea">.</span>getUserMedia <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">navigator</span><span style="color:#c792ea">.</span>getUserMedia <span style="color:#89ddff">||</span><span style="color:#bfc7d5">navigator</span><span style="color:#c792ea">.</span>webkitGetUserMedia <span style="color:#89ddff">||</span><span style="color:#bfc7d5">navigator</span><span style="color:#c792ea">.</span>mozGetUserMedia<span style="color:#c792ea">;</span></code></span></span>
我们需要定义我们请求的约束,这些约束navigator.getUserMedia()
将决定我们请求的媒体类型。在此示例中,我们仅通过设置请求访问用户的网络摄像头video: true
。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">var constraints <span style="color:#89ddff">=</span> <span style="color:#c792ea">{</span> audio<span style="color:#89ddff">:</span> <span style="color:#ff5874">false</span><span style="color:#c792ea">,</span> video<span style="color:#89ddff">:</span> <span style="color:#ff5874">true</span> <span style="color:#c792ea">}</span><span style="color:#c792ea">;</span></code></span></span>
下面我们在变量中定义和存储演示应用程序的 HTML 元素。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">var start <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">document</span><span style="color:#c792ea">.</span><span style="color:#82aaff">querySelector</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'#start'</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
var snapshot <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">document</span><span style="color:#c792ea">.</span><span style="color:#82aaff">querySelector</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'#snapshot'</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
var filter <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">document</span><span style="color:#c792ea">.</span><span style="color:#82aaff">querySelector</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'#filter'</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
var video <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">document</span><span style="color:#c792ea">.</span><span style="color:#82aaff">querySelector</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'video'</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
var canvas <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">document</span><span style="color:#c792ea">.</span><span style="color:#82aaff">querySelector</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'canvas'</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span></code></span></span>
接下来,我们需要为我们将应用于快照的过滤器创建一个数组。我们将在我们的 CSS 代码中定义过滤器,在下一节中描述,使用相同的名称:
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">var filters <span style="color:#89ddff">=</span> <span style="color:#c792ea">[</span><span style="color:#c3e88d">'blur'</span><span style="color:#c792ea">,</span> <span style="color:#c3e88d">'brightness'</span><span style="color:#c792ea">,</span> <span style="color:#c3e88d">'contrast'</span><span style="color:#c792ea">,</span> <span style="color:#c3e88d">'grayscale'</span><span style="color:#c792ea">,</span><span style="color:#c3e88d">'hue'</span><span style="color:#c792ea">,</span> <span style="color:#c3e88d">'invert'</span><span style="color:#c792ea">,</span> <span style="color:#c3e88d">'saturate'</span><span style="color:#c792ea">,</span> <span style="color:#c3e88d">'sepia'</span><span style="color:#c792ea">]</span><span style="color:#c792ea">;</span></code></span></span>
是时候享受真正的乐趣了!我们向我们的开始按钮添加一个click
事件来初始化 navigator.getUserMedia(constraints, success, error);
以访问我们的网络摄像头。必须获得许可才能访问我们的网络摄像头。每个浏览器供应商处理显示提示以允许以不同方式访问用户的网络摄像头和麦克风。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">start<span style="color:#c792ea">.</span><span style="color:#82aaff">addEventListener</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'click'</span><span style="color:#c792ea">,</span> function<span style="color:#c792ea">(</span><span style="color:#c792ea">)</span> <span style="color:#c792ea">{</span><span style="color:#bfc7d5">navigator</span><span style="color:#c792ea">.</span><span style="color:#82aaff">getUserMedia</span><span style="color:#c792ea">(</span>constraints<span style="color:#c792ea">,</span> success<span style="color:#c792ea">,</span> error<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span></code></span></span>
在成功授予访问用户网络摄像头的权限后,我们将流对象作为 HTML5video
标记的源传递。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">function <span style="color:#82aaff">success</span><span style="color:#c792ea">(</span>stream<span style="color:#c792ea">)</span> <span style="color:#c792ea">{</span><span style="color:#697098">/* hide the start button*/</span>start<span style="color:#c792ea">.</span>style<span style="color:#c792ea">.</span>display <span style="color:#89ddff">=</span> <span style="color:#c3e88d">'none'</span><span style="color:#c792ea">;</span><span style="color:#697098">/* show the snapshot button*/</span>snapshot<span style="color:#c792ea">.</span>style<span style="color:#c792ea">.</span>display <span style="color:#89ddff">=</span> <span style="color:#c3e88d">'block'</span><span style="color:#c792ea">;</span><span style="color:#697098">/* show the filter button*/</span>filter<span style="color:#c792ea">.</span>style<span style="color:#c792ea">.</span>display <span style="color:#89ddff">=</span> <span style="color:#c3e88d">'block'</span><span style="color:#c792ea">;</span>if<span style="color:#c792ea">(</span><span style="color:#bfc7d5">window</span><span style="color:#c792ea">.</span><span style="color:#82aaff">URL</span><span style="color:#c792ea">)</span> <span style="color:#c792ea">{</span>video<span style="color:#c792ea">.</span>src <span style="color:#89ddff">=</span> <span style="color:#bfc7d5">window</span><span style="color:#c792ea">.</span><span style="color:#82aaff">URL</span><span style="color:#c792ea">.</span><span style="color:#82aaff">createObjectURL</span><span style="color:#c792ea">(</span>stream<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span><span style="color:#c792ea">}</span> else <span style="color:#c792ea">{</span>video<span style="color:#c792ea">.</span>src <span style="color:#89ddff">=</span> stream<span style="color:#c792ea">;</span><span style="color:#c792ea">}</span>
<span style="color:#c792ea">}</span></code></span></span>
如果访问用户的网络摄像头发生错误或权限被拒绝,您将收到将打印到控制台的错误。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">function <span style="color:#82aaff">error</span><span style="color:#c792ea">(</span>e<span style="color:#c792ea">)</span> <span style="color:#c792ea">{</span><span style="color:#ffcb6b">console</span><span style="color:#c792ea">.</span><span style="color:#82aaff">log</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'navigator.getUserMedia error: '</span><span style="color:#c792ea">,</span> e<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span></code></span></span>
接下来我们创建一个简单的函数来将我们的 CSS 过滤器应用于canvas
和video
元素。该函数将找到 CSS 类的名称并将过滤器应用于画布。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">filter<span style="color:#c792ea">.</span><span style="color:#82aaff">addEventListener</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'click'</span><span style="color:#c792ea">,</span> function<span style="color:#c792ea">(</span><span style="color:#c792ea">)</span> <span style="color:#c792ea">{</span> var index <span style="color:#89ddff">=</span> <span style="color:#c792ea">(</span>filters<span style="color:#c792ea">.</span><span style="color:#82aaff">indexOf</span><span style="color:#c792ea">(</span>canvas<span style="color:#c792ea">.</span>className<span style="color:#c792ea">)</span> <span style="color:#89ddff">+</span> <span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span> <span style="color:#89ddff">%</span> filters<span style="color:#c792ea">.</span>length<span style="color:#c792ea">;</span>video<span style="color:#c792ea">.</span>className <span style="color:#89ddff">=</span> filters<span style="color:#c792ea">[</span>index<span style="color:#c792ea">]</span><span style="color:#c792ea">;</span>canvas<span style="color:#c792ea">.</span>className <span style="color:#89ddff">=</span> filters<span style="color:#c792ea">[</span>index<span style="color:#c792ea">]</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span></code></span></span>
最后,我们拍摄本地视频流的快照并将其渲染到canvas
.
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-javascript">snapshot<span style="color:#c792ea">.</span><span style="color:#82aaff">addEventListener</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'click'</span><span style="color:#c792ea">,</span> function<span style="color:#c792ea">(</span><span style="color:#c792ea">)</span> <span style="color:#c792ea">{</span>canvas<span style="color:#c792ea">.</span>width <span style="color:#89ddff">=</span> <span style="color:#f78c6c">360</span><span style="color:#c792ea">;</span>canvas<span style="color:#c792ea">.</span>height <span style="color:#89ddff">=</span> <span style="color:#f78c6c">270</span><span style="color:#c792ea">;</span>canvas<span style="color:#c792ea">.</span><span style="color:#82aaff">getContext</span><span style="color:#c792ea">(</span><span style="color:#c3e88d">'2d'</span><span style="color:#c792ea">)</span><span style="color:#c792ea">.</span><span style="color:#82aaff">drawImage</span><span style="color:#c792ea">(</span>video<span style="color:#c792ea">,</span> <span style="color:#f78c6c">0</span><span style="color:#c792ea">,</span> <span style="color:#f78c6c">0</span><span style="color:#c792ea">,</span> canvas<span style="color:#c792ea">.</span>width<span style="color:#c792ea">,</span> canvas<span style="color:#c792ea">.</span>height<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span></code></span></span>
CSS
您将在下面找到为您的第一个 WebRTC 应用程序设置样式的基础知识。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-css"><span style="color:#c792ea">body</span>
<span style="color:#c792ea">{</span>font-family<span style="color:#c792ea">:</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">'Open Sans'</span></span><span style="color:#c792ea">,</span> sans-serif<span style="color:#c792ea">;</span>background-color<span style="color:#c792ea">:</span> #e4e4e4<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">h1</span>
<span style="color:#c792ea">{</span>width<span style="color:#c792ea">:</span> <span style="color:#f78c6c">780</span>px<span style="color:#c792ea">;</span>margin-left<span style="color:#c792ea">:</span> <span style="color:#f78c6c">20</span>px<span style="color:#c792ea">;</span>float<span style="color:#c792ea">:</span> left<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.m-content</span>
<span style="color:#c792ea">{</span>width<span style="color:#c792ea">:</span> <span style="color:#f78c6c">800</span>px<span style="color:#c792ea">;</span>height<span style="color:#c792ea">:</span> <span style="color:#f78c6c">310</span>px<span style="color:#c792ea">;</span>margin<span style="color:#c792ea">:</span> auto<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.photo-booth</span>
<span style="color:#c792ea">{</span>width<span style="color:#c792ea">:</span> <span style="color:#f78c6c">800</span>px<span style="color:#c792ea">;</span>height<span style="color:#c792ea">:</span> <span style="color:#f78c6c">310</span>px<span style="color:#c792ea">;</span>float<span style="color:#c792ea">:</span> left<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span></code></span></span>
WebRTC 允许通过两种方式定义视频流的大小。您可以在contraints
传递给的变量中navigator.getUserMedia(contraints, success, error);
定义它,也可以在 CSS 中定义它。在这个例子中,我们使用 CSS 来定义video
本地视频流和canvas
元素的尺寸。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-css"><span style="color:#c792ea">video</span>
<span style="color:#c792ea">{</span>width<span style="color:#c792ea">:</span> <span style="color:#f78c6c">360</span>px<span style="color:#c792ea">;</span>height<span style="color:#c792ea">:</span> <span style="color:#f78c6c">270</span>px<span style="color:#c792ea">;</span>float<span style="color:#c792ea">:</span> left<span style="color:#c792ea">;</span>margin<span style="color:#c792ea">:</span> <span style="color:#f78c6c">20</span>px<span style="color:#c792ea">;</span>background-color<span style="color:#c792ea">:</span> #333<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">canvas</span>
<span style="color:#c792ea">{</span>width<span style="color:#c792ea">:</span> <span style="color:#f78c6c">360</span>px<span style="color:#c792ea">;</span>height<span style="color:#c792ea">:</span> <span style="color:#f78c6c">270</span>px<span style="color:#c792ea">;</span>float<span style="color:#c792ea">:</span> left<span style="color:#c792ea">;</span>margin<span style="color:#c792ea">:</span> <span style="color:#f78c6c">20</span>px<span style="color:#c792ea">;</span>background-color<span style="color:#c792ea">:</span> #777<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span></code></span></span>
接下来我们给我们的按钮一点闪光。我们将隐藏我们的过滤器和快照按钮,直到我们可以使用 访问我们的麦克风和摄像头getUserMedia()
。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-css"><span style="color:#c792ea">.buttons</span>
<span style="color:#c792ea">{</span>margin-left<span style="color:#c792ea">:</span> <span style="color:#f78c6c">20</span>px<span style="color:#c792ea">;</span>float<span style="color:#c792ea">:</span> left<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">button</span>
<span style="color:#c792ea">{</span>background-color<span style="color:#c792ea">:</span> #d84a38<span style="color:#c792ea">;</span>border<span style="color:#c792ea">:</span> none<span style="color:#c792ea">;</span>border-radius<span style="color:#c792ea">:</span> <span style="color:#f78c6c">2</span>px<span style="color:#c792ea">;</span>color<span style="color:#c792ea">:</span> white<span style="color:#c792ea">;</span>font-family<span style="color:#c792ea">:</span> <span style="background-color:rgba(255, 255, 255, 0.5)"><span style="color:#9a6e3a">'Open Sans'</span></span><span style="color:#c792ea">,</span> sans-serif<span style="color:#c792ea">;</span>font-size<span style="color:#c792ea">:</span> <span style="color:#f78c6c">0.8</span>em<span style="color:#c792ea">;</span>margin<span style="color:#c792ea">:</span> <span style="color:#f78c6c">0</span> <span style="color:#f78c6c">0</span> <span style="color:#f78c6c">1</span>em <span style="color:#f78c6c">0</span><span style="color:#c792ea">;</span>padding<span style="color:#c792ea">:</span> <span style="color:#f78c6c">0.5</span>em <span style="color:#f78c6c">0.7</span>em <span style="color:#f78c6c">0.6</span>em <span style="color:#f78c6c">0.7</span>em<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">button:active</span>
<span style="color:#c792ea">{</span>background-color<span style="color:#c792ea">:</span> #cf402f<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">button:hover</span>
<span style="color:#c792ea">{</span>background-color<span style="color:#c792ea">:</span> #cf402f<span style="color:#c792ea">;</span>cursor<span style="color:#c792ea">:</span> pointer<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">#filter<span style="color:#c792ea">,</span> #snapshot</span>
<span style="color:#c792ea">{</span>display<span style="color:#c792ea">:</span> none<span style="color:#c792ea">;</span>margin-right<span style="color:#c792ea">:</span> <span style="color:#f78c6c">20</span>px<span style="color:#c792ea">;</span>float<span style="color:#c792ea">:</span> left<span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span></code></span></span>
接下来,我将使用 CSS 定义照相亭的过滤器。您可以在相关的 MDN 页面上找到支持的过滤器列表。
<span style="background-color:#292d3e"><span style="color:#bfc7d5"><code class="language-css"><span style="color:#c792ea">.blur</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">blur</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">2</span>px<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">blur</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">2</span>px<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.grayscale</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">grayscale</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">grayscale</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.sepia</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">sepia</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">sepia</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.brightness</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">brightness</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">2.2</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">brightness</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">2.2</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.contrast</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">contrast</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">3</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">contrast</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">3</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.hue</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">hue-rotate</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">120</span>deg<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">hue-rotate</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">120</span>deg<span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.invert</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">invert</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">invert</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">1</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span><span style="color:#c792ea">.saturate</span>
<span style="color:#c792ea">{</span>filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">staurate</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">5</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>-webkit-filter<span style="color:#c792ea">:</span> <span style="color:#82aaff">staurate</span><span style="color:#c792ea">(</span><span style="color:#f78c6c">5</span><span style="color:#c792ea">)</span><span style="color:#c792ea">;</span>
<span style="color:#c792ea">}</span></code></span></span>
如果您熟悉 MailChimp,您可能已经注意到使用网络摄像头添加个人资料图片的功能。MailChimp 为其用户添加了一个简单但有效的解决方案,以使用与此演示类似的方式使用 WebRTC 修改他们的个人资料图像。
本文中开发的代码可在 GitHub 上找到。您可以在WebRTC Challenge上查看照片应用程序的现场演示。
兼容性
因此,您可能想知道 WebRTC 在浏览器供应商和移动设备上的可用性。就目前而言,WebRTC 仅与 Chrome、Firefox 和 Opera 的桌面版本以及 Android 上的移动浏览器兼容。WebRTC 尚未在 iOS 上用于移动浏览器,但您可以使用本机库来构建您的 iOS 和 Android 应用程序。微软正在积极推动对象实时通信 (ORTC),目前计划成为 WebRTC 1.1 规范的一部分。在那之前,有一种解决方法是使用 Temasys 的托管开源插件来支持 Internet Explorer 和 Safari。
爱立信目前正在通过他们的“Bowser”应用程序支持 WebRTC,您可以从 Apple应用商店下载该应用程序。它是他们新框架OpenWebRTC的一部分,OpenWebRTC是一个基于 GStreamer 的跨平台 WebRTC 客户端框架。
网站iswebrtcreadyyet.com是一个方便的工具,可用于检查您喜欢的浏览器的状态。
WebRTC 资源
Web 实时通信是一项激动人心的技术,它为创新打开了大门。开发人员现在可以增强用户体验并在其应用程序中提供上下文信息。以下是一些资源,您可以查看这些资源以查找有关 WebRTC 的更多信息。
- Webrtc.org主页,由 Google Chrome 团队维护
- 使用 WebRTC 进行实时通信:Google I/O 2013 演示文稿
- WebRTC GitHub 存储库
如果您想使用 WebRTC 与朋友进行简单的会议或对话,以下是您可以免费使用的资源列表:
- Tawk.com
- Talky.io
- Appear.in
WebRTC 挑战
如果您想了解更多有关 WebRTC 生态系统的信息,请前往WebRTC 挑战赛。这是Blacc Spot Media团队发起的一项新计划,旨在向 Web 和移动社区的开发人员介绍和教育 WebRTC 的好处和功能。
结论
这只是 Web 实时通信 (WebRTC) 的强大功能的一瞥。随着我们继续这个系列,我们将深入探讨 WebRTC 的末端和外在,它在市场中的地位以及大小公司如何已经开始利用它的力量。重要的是要记住,WebRTC不是一个开箱即用的解决方案,而是一个允许您增强应用程序的工具。敬请期待更多!
WebRTC 的黎明相关推荐
- 使用 SimpleWebRTC 构建 WebRTC 视频聊天应用程序
Building a WebRTC Video Chat Application with SimpleWebRTC 机翻 原文:Building a WebRTC Video Chat Applic ...
- 经历过黑暗才更渴望黎明_黑暗的图案,你如何操纵以给予更多
经历过黑暗才更渴望黎明 On every major website, a game is being played. 在每个主要网站上,都在玩游戏. The aim? To take as much ...
- WebRTC框架中的硬件加速
WebRTC框架中的硬件加速 典型缓冲流量 应用程序和单元测试设置 重要方法调用 WebRTC软件包 局限性 WebRTC是一个免费的开源项目,可为浏览器和移动应用程序提供实时通信功能. WebRTC ...
- webrtc android ndk,webrtc 针对 android 平台的编译和运行
1环境准备 官方说明: 针对android构建需要Ubuntu64位机器,虚拟机也行. 1.1安装SVN 直接用apt-get安装 sudoapt-getinstallsubversion 1.2安装 ...
- 展望2018:WebRTC大规模商用元年
历经6年长跑,WebRTC终于在去年迎来了1.0标准(candidate recommendation)的发布,而它也将成为2018年视频通信商业应用场景爆发的主要技术推动力.一站式WebRTC通信技 ...
- 黎明觉醒火种测试服务器维护,黎明觉醒火种测试什么时候上线 黎明觉醒火种测试资格获取方式(图文)...
黎明觉醒是腾讯旗下的多人开放世界生存手游,对标的就是网易旗下的明日之后.在之前的曙光测试之后,这款游戏长时间来都没有传出过新消息,下面game234就来介绍一下黎明觉醒最新的火种测试什么时候上线,怎么 ...
- 使用WebRTC搭建前端视频聊天室——数据通道篇
转自 使用WebRTC搭建前端视频聊天室--数据通道篇 在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩 ...
- Android IOS WebRTC 音视频开发总结(三八)-- tx help
Android IOS WebRTC 音视频开发总结(三八)-- tx help 本文主要介绍帮一个程序员解决webrtc疑问的过程,文章来自博客园RTC.Blacker,支持原创,转载请说明出处(w ...
- WebRTC的拥塞控制技术转
转载地址:http://www.jianshu.com/p/9061b6d0a901 1. 概述 对于共享网络资源的各类应用来说,拥塞控制技术的使用有利于提高带宽利用率,同时也使得终端用户在使用网络时 ...
最新文章
- php经典操作,php数组的经典操作(遍历数组、基本操作)实例
- python删除列表中的重复元素并保持相对顺序不变
- 【收藏】ABAP Bom按层展开的几种实现方法
- linux重启mysqlsystemctl_解决linux(centos7)重新安装mysql systemctl start mysqld.service时报错...
- gocd_如何将DangerJS集成到GoCD管道中
- 只卖男人,年赚5.6亿!全网最火“爱情骗子”,被戳穿了
- HandyJSON:Swift语言JSON转Model工具库
- (转 )Unity对Lua的编辑器拓展
- CentOS7.2下python安装pip-8.0.2管理
- Android studio导入项目报错Please refer to the user guide chapter on the daemon at http://gradle.org/docs/2
- 记一次python cpu100%分析记录
- 基于ssm+vue的综合项目 健康体检管理系统-第十章-权限控制、图形报表
- 实现电脑同时上内网和外网(或通过外网访问到该电脑通过该电脑访问内网)
- 2023齐齐哈尔大学计算机考研信息汇总
- 深大uooc学术道德与学术规范教育第十章
- linux tar压缩权限,linux tar压缩命令
- 内蒙古大学计算机学院教授,内蒙古大学计算机学院软件学院硕士生导师:张俊星...
- Linux centos7 代码运行时出现已放弃(吐核)的问题解决
- ADSL上网TP-LINK路由器设置方法
- 常见安全漏洞及整改建议