浏览器实现屏幕以及人像录制

简介

本文章主要介绍了,通过浏览器实现屏幕录制以及摄像头调用功能。

开始

1、调用相机

首先简单了解一下如何调用摄像头

  <video id="video" width="640" height="480" autoplay></video>
// 判断浏览器是否支持 getUserMedia API  
    if (navigator.mediaDevices.getUserMedia) {
        // 约束条件,这里表示使用用户的摄像头  
        const constraints = {video: true};

        // 调用 getUserMedia API  
        navigator.mediaDevices.getUserMedia(constraints)
            .then(function (stream) {
                // 获取 video 元素  
                const video = document.getElementById('video');

                // 设置视频源为用户的摄像头  
                video.srcObject = stream;
            })
            .catch(function (err) {
                console.log("Something went wrong: " + err);
            });
    } else {
        console.log("Your browser does not support getUserMedia API");
    }
2、实现摄像头悬浮小窗

实现小窗的思路主要是利用了video视频标签的画中画功能 requestPictureInPicture()api,调用此api并将video标签隐藏就实现了摄像头小窗悬浮功能;

 <video id="video" width="0" height="0" autoplay></video> // 或者利用css display:
video.requestPictureInPicture()
3、屏幕录制
    let btn = document.querySelector(".record-btn")

    btn.addEventListener("click", async function () {

      // 这个 MediaDevices 接口的 getDisplayMedia() 方法提示用户去选择和授权捕获展示的内容或部分内容(如一个窗口)在一个MediaStream 里
      let stream = await navigator.mediaDevices.getDisplayMedia({
        video: true
      })

      // 需要更好的浏览器支持
      const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
        ? "video/webm; codecs=vp9"
        : "video/webm"
      // MediaRecorder 是 MediaStream Recording API 提供的用来进行媒体轻松录制的接口,他需要通过调用 MediaRecorder() 构造方法进行实例化
      let mediaRecorder = new MediaRecorder(stream, {
        mimeType: mime,
      })

      let chunks = []

      mediaRecorder.addEventListener('dataavailable', function (e) {
        chunks.push(e.data)
      })

      mediaRecorder.addEventListener('stop', function () {
        let blob = new Blob(chunks, {
          type: chunks[0].type
        })
        let url = URL.createObjectURL(blob)

        let video = document.querySelector("video")
        video.src = url



        // 自动下载
        let a = document.createElement('a')
        a.href = url
        a.download = 'video.webm'
        a.click()
      })

      // 必须手动启动
      mediaRecorder.start()
    })
4、最后整合

最后我是用vue(大家可以随意选择框架,原生js实现也可以)将两块代码粘合起来,简单实现功能代码写的比较杂乱-。-;

<script setup lang="ts">
import { ref, watch } from 'vue';
let recordtype = ref();
let personVideo = ref()
let videoList = ref<string[]>([])

const personVideoHandle = () => {
    // 判断浏览器是否支持 getUserMedia API  
    if (navigator.mediaDevices.getUserMedia) {
        // 约束条件,这里表示使用用户的摄像头  
        const constraints = { video: true };
        // 调用 getUserMedia API  
        navigator.mediaDevices.getUserMedia(constraints)
            .then(function (stream) {
                // 获取 video 元素  
                // 设置视频源为用户的摄像头  
                personVideo.value.srcObject = stream;
                setTimeout(async () => {
                    screenHandle()
                    await personVideo.value.requestPictureInPicture();
                    personVideo.value.addEventListener('leavepictureinpicture', function () {
                        personVideo.value.srcObject.getTracks().forEach(track => {
                            track.stop()
                        });
                    })
                }, 1000);
            })
            .catch(function (err) {
                console.log("Something went wrong: " + err);
            });
    } else {
        console.log("Your browser does not support getUserMedia API");
    }
}

const screenHandle = async () => {
    // 这个 MediaDevices 接口的 getDisplayMedia() 方法提示用户去选择和授权捕获展示的内容或部分内容(如一个窗口)在一个MediaStream 里
    let stream = await navigator.mediaDevices.getDisplayMedia({
        video: {
            height: 1920
        }
    })

    // 需要更好的浏览器支持
    const mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
        ? "video/webm; codecs=vp9"
        : "video/webm"
    // MediaRecorder 是 MediaStream Recording API 提供的用来进行媒体轻松录制的接口,他需要通过调用 MediaRecorder() 构造方法进行实例化
    let mediaRecorder = new MediaRecorder(stream, {
        mimeType: mime,
    })

    let chunks: Blob[] = []

    mediaRecorder.addEventListener('dataavailable', function (e) {
        chunks.push(e.data)
    })

    mediaRecorder.addEventListener('stop', function () {
        let blob = new Blob(chunks, {
            type: chunks[0].type
        })
        let url = URL.createObjectURL(blob)
        videoList.value.push(url)
    })

    // 必须手动启动
    mediaRecorder.start()
}

const downloadVideo = (url: string) => {
    let a = document.createElement('a')
    a.href = url
    a.download = 'video.webm'
    a.click()
}

watch(() => recordtype.value, () => {
    switch (recordtype.value) {
        case '1':
            screenHandle()
            break;
        case '2':
            personVideoHandle()
            break;
        default:
            break;
    }
})

</script>

<template>
    <div>
        <span>录制类型:</span>
        <el-radio-group v-model="recordtype" class="ml-4">
            <el-radio label="1" size="large">仅录制屏幕</el-radio>
            <el-radio label="2" size="large">屏幕以及人像</el-radio>
        </el-radio-group>
    </div>
    <div class="video-files">
        <div>
            视频文件列表
        </div>
        <div v-for="item in videoList" :key="item">
            <video class="video-item" :src="item" controls></video>
            <div @click="downloadVideo(item)">下载视频</div>
        </div>
        <video class="personVideo" ref="personVideo" autoplay></video>
    </div>
</template>

<style scoped>
.personVideo {
    display: none;
}

.video-item {
    width: 180px;
}
</style>

posted @   spongeCoder  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Blazor Hybrid适配到HarmonyOS系统
· 万字调研——AI生成内容检测
· 解决跨域问题的这6种方案,真香!
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
点击右上角即可分享
微信分享提示