4.6 共享屏幕
在视频会议系统里共享屏幕是一项重要的功能,即把你的计算机桌面或者某一个应用窗口分享给其他人观看。这里主要阐述的是如何将应用窗口采集到屏幕画面,可以使用WebRTC的navigator.mediaDevices.getDisplayMedia()方法获取屏幕数据。
接下来通过一个例子来展示如何共享屏幕,具体步骤如下所示。
步骤1 打开h5-samples工程下的src目录,添加ScreenShare.jsx文件。编写捕获屏幕方法,添加约束条件,只需要设置{video:true}即可。代码如下所示。
const stream = await navigator.mediaDevices.getDisplayMedia({video: true});
约束条件只需要设置{video:true}的目的是将其转化成视频流,这里不需要设置宽高约束,这样可以使得共享出来的屏幕达到清晰的效果。
getDisplayMedia()是一个特殊方法,需要与getUserMedia()区分开来。旧的Chrome浏览器需要安装扩展插件才可以使用,新版的Chrome则不需要。
步骤2 当成功获取到屏幕视频流后,将其传递给video对象的srcObject即可,这样视频流就会源源不断地向video对象输出并渲染出来。大致处理如下所示。
//成功返回视频流 handleSuccess = (stream) => { //获取video对象 ... //将video对象的视频源指定为stream video.srcObject = stream; }
步骤3 在页面渲染部分添加video标签,由于现在已经将捕获到的屏幕数据转化成视频流了,所以可以在video对象里进行渲染。代码如下所示。
{/* 捕获屏幕数据渲染 */} <video autoPlay playsInline></video>
步骤4 在src目录下的App.jsx及Samples.jsx里加上链接及路由绑定,参考第3章即可。完整的代码如下所示。
import React from "react"; import { Button, message } from "antd"; /** * 共享屏幕示例 */ class ScreenSharing extends React.Component { //开始捕获桌面 startScreenShare = async (e) => { try { //调用getDisplayMedia()方法,约束设置成{video:true}即可 const stream = await navigator.mediaDevices.getDisplayMedia({video: true}); console.log('handleSuccess:'); this.handleSuccess(stream); } catch (e) { this.handleError(e); } } //成功捕获,返回视频流 handleSuccess = (stream) => { const video = this.refs['myVideo']; //获取视频轨道 const videoTracks = stream.getVideoTracks(); //读取视频资源名称 console.log(`视频资源名称: ${videoTracks[0].label}`); window.stream = stream; //将视频对象的源指定为stream video.srcObject = stream; } //错误处理 handleError(error) { if (error.name === 'ConstraintNotSatisfiedError') { const v = constraints.video; //宽高尺寸错误 message.error(`宽:${v.width.exact} 高:${v.height.exact} 设备不支持`); } else if (error.name === 'PermissionDeniedError') { message.error('没有摄像头和麦克风使用权限,请点击允许按钮'); } message.error(`getUserMedia错误: ${error.name}`, error); } render() { return ( <div className="container"> <h1> <span>共享屏幕示例</span> </h1> {/* 捕获屏幕数据渲染 */} <video className="video" ref="myVideo" autoPlay playsInline></video> <Button onClick={this.startScreenShare}>开始共享</Button> </div> ); } } //导出组件 export default ScreenSharing;
当获取到媒体数据流后,可以通过stream.getVideoTracks()得到视频轨道,然后通过videoTracks[0].label获取到摄像头的名称。输出内容如下所示。
视频资源名称: screen:1127248311:0
运行程序后,打开共享屏幕示例,点击“开始共享”按钮,会弹出一个对话框让你选择要捕获的屏幕或应用窗口,如图4-4所示。
当选择了某个整个屏幕或应用窗口后,画面就会呈现在视频对象上,此时屏幕上有任何操作,都可以同步、实时地在视频里播放,如图4-5所示。
图4-4 共享屏幕选择窗口
图4-5 共享屏幕显示效果图
与此同时,Chrome浏览器会弹出一个小的对话框,可以点击“停止共享”按钮随时停止捕获屏幕,如图4-6所示。
图4-6 停止共享对话框