前端录制屏幕getDisplayMedia方法的视频分片问题

一、问题

最近在使用getDisplayMedia方法录制屏幕时遇到问题,总是在录制结束后才能得到全部的视频,最后通过查找资料发现有一个视频分片的配置参数,就是MediaRecorder: start() 方法中的timeslice参数。

timeslice 可选参数

要记录到每个 Blob 中的毫秒数。如果这 参数不包括在内,除非调用 requestData() 方法以获取 并触发创建新的媒体,否则整个媒体持续时间将记录到一个媒体中。

二、使用方法

start(timeslice) timeslice为切片的毫秒数值

const stream = await navigator.mediaDevices.getDisplayMedia({
            video: true,
            audio: true, // 如果需要录制音频,取消注释此行
        });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(1000); //切片毫秒数

三、完整示例代码

let chunks = []; // 确保 chunks 在全局作用域中定义
let mediaRecorder =[]

export const startRecord = async (callback) => {
    try {
        console.log("正在请求屏幕录制权限...");

        const stream = await navigator.mediaDevices.getDisplayMedia({
            video: true,
            audio: true, // 如果需要录制音频,取消注释此行
            preferCurrentTab:false
        });
        

        mediaRecorder = new MediaRecorder(stream);
        mediaRecorder.ondataavailable = event => {
            console.log("Received data chunk of size:", event.data.size);
            chunks.push(event.data);
        };
        mediaRecorder.onstart = () => {
            console.log("Recording has started.");
        };
        mediaRecorder.start(1000); //切片毫秒数
        console.log("屏幕录制已开始");
    } catch (error) {
        console.error("屏幕录制失败:", error);
    }
};

/**
 * 停止屏幕录制并压缩视频后发送到服务器
 */
export const stopRecordAndSendToServer = async () => {
    try {
        console.log("正在停止屏幕录制...");
        mediaRecorder.stop();

        await new Promise((resolve) => {
            mediaRecorder.onstop = resolve;
        });
        console.log("chunks:",chunks);
        const videoBlob = new Blob(chunks, {type: 'video/webm'});
        chunks = [];

        const compressedVideoBlob = videoBlob;

        // 发送到后端服务器
        const formData = new FormData();
        formData.append('video', compressedVideoBlob);

        const response = await fetch('/upload/file', { // 替换为你的服务器端点
            method: 'POST',
            body: formData
        });

        if (!response.ok) {
            throw new Error(`Server responded with status: ${response.status}`);
        }

        console.log("视频已发送到后端");
    } catch (error) {
        console.error("发送视频到后端失败:", error);
    } finally {
        if (mediaRecorder && mediaRecorder.stream) {
            const tracks = mediaRecorder.stream.getTracks();
            tracks.forEach(track => track.stop());
        }
    }
};




// 使用方法
// startRecord();
// 录制一段时间后,调用stopRecordAndSendToServer来停止录制并发送视频,或者在mediaRecorder.ondataavailable中获取切片数据
// stopRecordAndSendToServer();
posted @ 2024-07-11 15:52  莫颀  阅读(66)  评论(0编辑  收藏  举报