在 Chrome 中使用 WebRTC 进行屏幕录制





5.00/5 (5投票s)
Google Chrome 中已经支持屏幕共享(演示屏幕、屏幕共享)。该技术允许捕获浏览器本身窗口以及其他应用程序的窗口。例如,您可以捕获单独运行的 Firefox 窗口。
Chrome 中的屏幕共享
Google Chrome 中已经支持屏幕共享(演示屏幕、屏幕共享)。该技术允许捕获浏览器本身窗口以及其他应用程序的窗口。例如,您可以捕获单独运行的 Firefox 窗口。这很好,但存在一个安全问题。Chrome 浏览器中禁用了屏幕共享。要启用屏幕共享,您需要 **Chrome 桌面捕获 API**,本文将介绍如何做到这一点。
屏幕共享扩展
要使屏幕共享正常工作,用户应安装专为您的网站(域名)设计的 Chrome 扩展程序。首次运行屏幕共享需要用户执行以下操作:
- 用户打开网站并点击 **开始屏幕共享**。
- 系统会要求用户为此操作添加扩展程序。
Chrome 浏览器会在一个标准对话框中要求添加扩展程序,用户只需单击一次即可添加。该对话框会通知用户扩展程序可以捕获屏幕。
您自己的扩展程序
下一步是为您的域名创建扩展程序。假设您的测试域名是 **mysupercat.com**。在这种情况下,在创建扩展程序时,您应该将域名放入代码中。此外,您的域名(此域上的网站)必须通过 HTTPS 工作。相应地,您的屏幕共享页面应如下所示:**https://mysupercat.com/screen-sharing.php**。
域名和 HTTPS,基本上,就是创建您自己的屏幕共享扩展程序所需的一切。而且您无需购买 SSL 证书。只要您的页面通过 HTTPS 打开,即使它被读取和划掉,自签名证书也足够了。
哦,您还需要准备五美元。这是您需要支付的费用,才能成为 Chrome 开发者社区的一员。总结一下。要开始创建和测试您自己的扩展程序,您需要:
- 域名
- HTTPS 托管
- 信用卡上的 5 美元
发布扩展程序
- 前往 Chrome 开发者信息中心并支付 5 美元会员费。
- 准备一个包含扩展程序文件的 ZIP。为此,请在此处下载 2 个文件 这里。编辑 manifest.json 文件并填入您自己的
名称
author
description
homepage_url
例如
"Name" : "My cool screen sharing extension",
"Author" : "I am",
"Description" : "The extensions shares screens from my website",
"Homepage_url" : "https://mysupercat.com",
{
"name" : "Flashphoner Screen Sharing",
"author": "Flashphoner",
"version" : "1.4",
"manifest_version" : 2,
"minimum_chrome_version": "34",
"description" : "This Chrome extension is developed for
http://flashphoner.com WCS Api to enable screen capture.",
"homepage_url": "http://flashphoner.com",
"background": {
"scripts": ["background-script.js"],
"persistent": false
},
"externally_connectable": {
"matches": [
"https://flashphoner.com/*",
"https://*.flashphoner.com/*",
"*:///*",
"*://127.0.0.1/*"
]
},
"icons": {
"16": "logo16.png",
"48": "logo48.png",
"128": "logo128.png"
},
"permissions": [
"desktopCapture"
],
"web_accessible_resources": [
"logo48.png"
]
}
然后将这些文件打包成 ZIP 存档,其中包含所有图标和其他图片。您可以在此处 这里 阅读更多关于图标的信息。此处 这里 讨论了其他图片。然后点击 **添加新项目**。
然后,在阅读协议后,上传您的 ZIP 存档。
上传存档后,请验证一切并保存。
现在,您只需从信息中心点击 **发布** 按钮即可发布扩展程序。
已发布的扩展程序在信息中心中显示如下
完成。扩展程序已打包、发布并可供安装到浏览器中。
内联安装
如果没有内联安装,您的用户将不得不打开 Chrome 商店并从那里安装您的扩展程序。这也不是什么大问题,但是
- 这对于用户来说不太方便。
- 用户可能会在扩展程序安装页面迷路,再也回不到您的页面。
内联安装扩展程序就是那个巧妙的标准对话框,它允许用户跳过访问 Chrome 商店
要配置内联安装,您需要对清单中指定的域名和托管(**manifest.json 文件**)拥有控制权。例如,如果您的域名是 mysupercat.com,您将需要通过标准验证程序并确认您拥有该域名的所有权。要启用内联安装,请在扩展程序的配置页面上启用 **此项目使用内联安装** 标志。
然后,添加您自己的网站。
搜索控制台将在新窗口中打开,您可以在其中进行验证。
下一步是将标识符文件上传到您的托管服务器,以确认您域名的所有权/网站所有权。
验证成功。
已验证的网站显示在此扩展程序可用的网站列表中,现在您可以使用扩展程序的内联安装了。
将屏幕共享集成到网页
扩展程序已读取并配置为内联安装。我们只需要将调用扩展程序的代码嵌入到 HTML 页面并进行测试。Google Chrome 中的屏幕共享使用 **WebRTC API**。因此,要完成此测试,我们需要一个 WebRTC 平台。作为服务器端 WebRTc 平台,我们将使用 Web Call Server 和 Web SDK - 这个服务器的一组 API 脚本。
- 创建一个用于屏幕共享的 HTML 页面 screen-sharing.html。该页面包含 20 行代码,如下所示:
<p><title></p> <h1>Screen Sharing</h1> <p>Install Now</p> <h2>Capture</h2> <div id="localVideo" style="width: 320px; height: 240px"> </div> <h2>Preview</h2> <div id="remoteVideo" style="width: 320px; height: 240px"> </div> <p>Connect and share screen</p> <p id="status"> </p>
- 上传 screen-sharing.js 脚本。稍后我们将详细检查它。
<script type="text/javascript" src="screen-sharing.js"></script>
- 指定在哪里查找屏幕共享扩展程序。
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nlbaajplpmleofphigmgaifhoikjmbkg">
- 添加一个按钮以执行扩展程序的安装。
<button id="installExtensionButton" onclick="installExtension()" type="button">Install Now</button>
- 添加一个 `div` - `localVideo` 元素,它将本地显示捕获的屏幕。
<div id="localVideo" style="width: 320px; height: 240px"> </div>
- 添加一个 `div` - `remoteVideo` 元素,它将作为播放器显示从服务器接收到的内容,即显示在 `localVideo` 中捕获并发送到服务器的视频流。
<div id="remoteVideo" style="width: 320px; height: 240px"> </div>
- 启动屏幕共享并显示流状态的按钮。
<button id="publishBtn" onclick="connectAndShareScreen()" type="button">Connect and share screen</button> <p id="status"> </p>
或者页面看起来像这样
- 创建用于屏幕共享的 **JavaScript 代码** screen-sharing.js。该代码可在此处 这里 下载。代码包含几个屏幕,包含 5 个主要函数。
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS; var localVideo; var remoteVideo; var extensionId = "nlbaajplpmleofphigmgaifhoikjmbkg"; function init_page() { //init api try { Flashphoner.init({screenSharingExtensionId: extensionId}); } catch (e) { //can't init return; } var interval = setInterval(function () { chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) { if (response) { document.getElementById("installExtensionButton").disabled = true; clearInterval(interval); localVideo = document.getElementById("localVideo"); remoteVideo = document.getElementById("remoteVideo"); } else { document.getElementById("installExtensionButton").disabled = false; } }); }, 500); } function connectAndShareScreen() { var url = "wss://wcs5-eu.flashphoner.com:8443"; console.log("Create new session with url " + url); Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) { //session connected, start streaming startStreaming(session); }).on(SESSION_STATUS.DISCONNECTED, function () { setStatus(SESSION_STATUS.DISCONNECTED); }).on(SESSION_STATUS.FAILED, function () { setStatus(SESSION_STATUS.FAILED); }); } function startStreaming(session) { var streamName = "test123"; var constraints = { video: { width: 320, height: 240, frameRate: 10, type: "screen" } }; session.createStream({ name: streamName, display: localVideo, constraints: constraints }).on(STREAM_STATUS.PUBLISHING, function (publishStream) { setStatus(STREAM_STATUS.PUBLISHING); //play preview session.createStream({ name: streamName, display: remoteVideo }).on(STREAM_STATUS.PLAYING, function (previewStream) { //enable stop button }).on(STREAM_STATUS.STOPPED, function () { publishStream.stop(); }).on(STREAM_STATUS.FAILED, function () { //preview failed, stop publishStream if (publishStream.status() == STREAM_STATUS.PUBLISHING) { setStatus(STREAM_STATUS.FAILED); publishStream.stop(); } }).play(); }).on(STREAM_STATUS.UNPUBLISHED, function () { setStatus(STREAM_STATUS.UNPUBLISHED); //enable start button }).on(STREAM_STATUS.FAILED, function () { setStatus(STREAM_STATUS.FAILED); }).publish(); } //show connection or local stream status function setStatus(status) { var statusField = document.getElementById("status"); statusField.innerHTML = status; } //install extension function installExtension() { chrome.webstore.install(); }
让我们详细研究一下这段代码。
- 首先,我们声明了几个变量:`statuses`、`localVideo` 和 `remoteVideo` 元素,以及包含屏幕共享扩展程序唯一 ID 的 `extensionId`。
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS; var localVideo; var remoteVideo; var extensionId = "nlbaajplpmleofphigmgaifhoikjmbkg"
- 然后,我们将 `extensionId` 发送到 `Flashphoner` API,结果 API 就知道使用了哪个扩展程序进行屏幕共享。
Flashphoner.init({screenSharingExtensionId: extensionId});
- 我们定期检查 Chrome,查看扩展程序是否已安装。如果扩展程序已安装,我们就不再需要 **安装扩展程序** 按钮,并且可以隐藏它。
chrome.runtime.sendMessage(extensionId, {type: "isInstalled"}, function (response) {...}
- `connectAndShareScreen` 函数建立与服务器的连接,一旦连接成功(ESTABLISHED),它就会通过委托控制给 `startStreaming` 函数来开始捕获和发送视频流。
function connectAndShareScreen() { var url = "wss://wcs5-eu.flashphoner.com:8443"; console.log("Create new session with url " + url); Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) { //session connected, start streaming startStreaming(session); }).on(SESSION_STATUS.DISCONNECTED, function () { setStatus(SESSION_STATUS.DISCONNECTED); }).on(SESSION_STATUS.FAILED, function () { setStatus(SESSION_STATUS.FAILED); }); }
- 在屏幕共享开始之前,我们设置流参数,如视频分辨率和 FPS。
var constraints = { video: { width: 320, height: 240, frameRate: 10, type: "screen" } };
- 然后我们创建 `stream` 本身并调用 `publish()` 方法。请注意,`stream` 被命名为 `test123`。
session.createStream({ name: streamName, display: localVideo, constraints: constraints }).publish();
- 在 `test123 stream` 成功发送到服务器后,执行将转移到 `PUBLISHING` 事件的处理程序。
on(STREAM_STATUS.PUBLISHING, function (publishStream) {...}
- 现在我们只需要在相邻的 `div remoteVideo` 中播放流。为此,我们调用 `play()` 函数。
session.createStream({ name: streamName, display: remoteVideo }).play();
页面和脚本已准备好进行测试。
准备测试
结果,我们有了以下文件:
- screen-sharing.html
- screen-sharing.js
- flashphoner.js
flashphoner.js 已包含在 Web SDK 构建中。最新版本可在此处 这里 下载。除了 HTML 和 JS 文件,我们还需要一个用于接收视频流并将其广播给所有其他人(在我们的例子中是回到同一页面)的转播服务器。
屏幕共享的测试遵循以下图示
同样,我们可以将屏幕共享流广播给多个连接的用户
在 Chrome 中测试屏幕共享
- 在 Google Chrome 中通过 HTTPS 打开 screen-sharing.html 页面。
- 点击立即安装按钮,使用 **内联安装** 添加扩展程序。
- 点击 **添加扩展程序**,然后点击 **连接并共享屏幕** 开始屏幕共享。Chrome 会要求选择要捕获的内容。这可以是 Chrome 本身的标签页或窗口,或者是另一个应用程序。
- 点击 **共享**,最后享受最终结果。屏幕被捕获,通过 `WebRTC` 发送到服务器,并在 **预览** 块显示它时返回。
结论
因此,我们在 **Google Chrome** 浏览器中通过一个简单的测试页面 screen-sharing.html 成功测试了屏幕共享。测试页面包含我们已发布到 **Chrome 商店** 的屏幕共享扩展程序,并可一键安装,无需打开商店。
在测试期间,页面通过 **HTTPS** 协议运行,并通过 Web Call Server - 一个用于广播流媒体视频的 **WebRTC 媒体服务器** 发送和接收视频。
我们将 flashphoner.js 脚本集成到 HTML 页面以进行屏幕共享,该脚本是 WCS 服务器的 Web SDK 构建的一部分。