【Web API系列】使用getDisplayMedia来实现录屏功能

在这里插入图片描述


前言

Web API经过长期的发展,尤其是最近,发展相当迅猛,现在已经支持很多功能了,一些原生就支持的功能也是做的相当好,这也带来了现在一些跨端应用的升级。有许多跨端的App框架可以考虑,就比如Tauri2.0就开启了跨端,又或者Uni X,现在也是在做原生级别的跨端应用框架。

最近用了好多相关内容,所以将其分享给大家。

本文直接开始使用Web API中MediaDevices的getDisplayMedia方法来实现录屏或直播效果。(如果你有兴趣可以上后探索探索)

如果你对这个API本身很感兴趣,建议看看原文


一、认识getD该处使用的url网络请求的数据。

—isplayMedia
getDisplayMedia方法是浏览器Web API中MediaDevices的一个函数。它允许网页开发者在浏览器中捕获和共享用户设备(如屏幕、窗口或摄像头)的媒体内容。

通过调用getDisplayMedia方法,网页开发者可以请求用户允许共享屏幕、窗口或摄像头的权限。一旦用户授权,网页开发者就可以在网页中获取媒体流,并将其用于实时通信、视频录制、屏幕分享等功能。

使用getDisplayMedia方法的一般步骤如下:

  1. 调用getDisplayMedia方法,传递一个MediaStreamConstraints对象作为参数,该对象描述了要请求的媒体类型和约束条件。

  2. 如果用户允许共享媒体内容,则返回一个Promise对象,该Promise对象解析为一个MediaStream对象。如果用户拒绝共享或硬件不可用,则Promise对象会被拒绝。

  3. 使用返回的媒体流进行进一步的操作,如获取媒体流中的轨道,显示在网页中,发送到服务器等。

getDisplayMedia方法该处使用的url网络请求的数据。

—通常与其他媒体相关的API(如MediaRecorder和WebRTC)结合使用,以便实现功能丰富的实时通信和多媒体应用程序。

二、使用步骤

经过我查找getDisplayMedia的相关资料,getDisplayMedia的使用方法基本上可以分为两种:

  1. 获取流,然后设置到一个新建的video标签,然都对video的流进行处理。
  2. 获取流,然后使用MediaStreamTrackProcessor转换为视频帧进行处理。

方法2会有更多的用处,比如实现在线剪辑,批量剪辑,以及AI剪辑都有很大的帮助。除此以外,还有另一种使用stream API的通道写法,但是我写了怎么也不生效,如果有大佬还麻烦请帮我看看怎么回事。

1.使用方法一实现录屏

方法一其实质就是将视频源直接设置到video标签,然后video标签会自动处理一些数据,算是比较常用的方式,代码如下

// 获取canvas元素
let canvas = document.getElementById('canvas');
// 获取2d上下文
let ctx = canvas.getContext('2d');
// 创建video标签
let video = document.createElement('video');
// 异步或者不异步都行,选择你喜欢的一种方式
async function start() {
    const userStream = await navigator.mediaDevices.getDisplayMedia({
    	// 开启视频
        video: true,
        // 关闭音频,选择适合你的
        audio: false
    });
    // video标签的源设置为获取到的流
    video.srcObject = userStream;
    // 播放视频
    video.play();
    // 请求动画帧
    window.requestAnimationFrame(frame);
}
// 这里是每帧进行的处理
frame = () => {
    if (video.readyState == video.HAVE_ENOUGH_DATA) {
        canvas.hidden = false;
        canvas.height = window.innerHeight;
        canvas.width = window.innerWidth;
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        // 做其他事情,比如绘制二维码或者文字或者扫描二维码,只要你有想法
    }
    window.requestAnimationFrame(frame);
}
function stop(){
    video.srcObject.getTracks().forEach((track) => track.stop());
}

2.使用方法二实现录屏

方法二是官方给出的结合stream API之前的一种死循环的方式来读取视频流的每帧,然后绘制到canvas。

// 获取canvas元素
let canvas = document.getElementById('canvas');
// 获取2d上下文
let ctx = canvas.getContext('2d');
// 创建video标签
let video = document.createElement('video');
// 异步或者不异步都行,选择你喜欢的一种方式
const track = null;
async function start() {
    const userStream = await navigator.mediaDevices.getDisplayMedia({
        video: true,
        audio: false
    });
    track = userStream.getVideoTracks()[0];
    const processor = new MediaStreamTrackProcessor(track);
    const reader = processor.readable.getReader();
    while (true) {
        const {done, value} = await reader.read();
        if (done) {
            break;
        }
        const frame = value;
        // 这里对每帧进行处理
        ctx.drawImage(frame, 0, 0, canvas.width, canvas.height);
        frame.close();
    }
}
function stop(){
    track.stop();
}

3. 运行效果


在这里插入图片描述

延伸


  1. 要想实现完整的录屏功能,还需要实现保存录像文件等功能,在后面如果接触到了文件操作等,我会详细的写如何将录制的文件保存下来。 如果你现在就有兴趣想要研究,建议看前面的MDN
  2. 该功能可以使用谷歌的stream api来做,但是我的代码一直不能正常运行,希望能有大佬帮我看看。
  3. 除了Stream API,实际上还可以用rxjs做,目前我也在研究中,如果有了结果我会发另一篇文章来介绍如何使用rxjs来实现,rxjs对于流操作还是比较擅长的。
  • 30
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
在 `uniapp` 中,可以使用 `uni-app` 的 `uni-record` 插件来实现功能。该插件支持在 iOS 和 Android 平台上幕或 App 内容,并可输出 MP4 格式的视频文件。具体实现步骤如下: 1. 安装 `uni-record` 插件 在 `uniapp` 项目的根目下,打开命令行窗口,执行以下命令安装插件: ``` npm install uni-record --save ``` 2. 在需要使用功能的 `vue` 文件中引入 `uni-record` 插件: ```javascript import uniRecord from '@dcloudio/uni-record'; ``` 3. 在需要的函数中调用 `uniRecord` 的 `startRecord` 方法开始: ```javascript uniRecord.startRecord({ success: res => { console.log('成功', res); // res.videoPath 为视频文件的本地路径 }, fail: err => { console.log('失败', err); } }); ``` 4. 在完成后,调用 `uniRecord` 的 `stopRecord` 方法停止: ```javascript uniRecord.stopRecord(); ``` 注意事项: - 期间,应保持 App 处于前台运行状态。 - 过程中 App 可能会出现卡顿现象,需要针对性地优化 App 性能。 - iOS 平台上需要在 `Info.plist` 文件中添加以下权限声明: ```xml <key>NSMicrophoneUsageDescription</key> <string>需要您的同意,才能进行</string> <key>NSAppleMusicUsageDescription</key> <string>需要您的同意,才能进行</string> <key>NSCameraUsageDescription</key> <string>需要您的同意,才能进行</string> <key>NSPhotoLibraryUsageDescription</key> <string>需要您的同意,才能进行</string> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广龙宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值