第6章 屏幕录制功能

在本章中,我们将学习如何使用RecordRTC实现屏幕录制功能,包括获取屏幕权限、配置选项和处理录制结果。

6.1 屏幕录制基础

屏幕录制是RecordRTC的重要功能,允许用户录制整个屏幕或特定窗口:

基本屏幕录制配置

// 基本屏幕录制配置
var options = {
    type: 'video',              // 录制类型
    mimeType: 'video/webm',     // 视频格式
    video: {
        width: 1920,
        height: 1080
    },
    canvas: {
        width: 1920,
        height: 1080
    }
};

// 获取屏幕共享流
navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: true
}).then(function(stream) {
    // 初始化RecordRTC
    var recorder = RecordRTC(stream, options);
    
    // 开始录制
    recorder.startRecording();
}).catch(function(error) {
    console.error('获取屏幕共享流失败:', error);
});

6.2 获取屏幕权限

屏幕录制需要用户明确授权,使用getDisplayMedia API:

获取屏幕权限

// 获取屏幕共享权限
async function getScreenStream() {
    try {
        // 使用getDisplayMedia获取屏幕流
        const stream = await navigator.mediaDevices.getDisplayMedia({
            video: {
                cursor: 'motion',       // 显示鼠标指针
                displaySurface: 'monitor' // 录制整个屏幕
            },
            audio: {
                echoCancellation: true,
                noiseSuppression: true
            }
        });
        
        return stream;
    } catch (error) {
        console.error('用户拒绝了屏幕共享权限:', error);
        throw error;
    }
}

6.3 屏幕录制配置选项

可以配置多种选项来控制屏幕录制行为:

屏幕录制配置

// 详细屏幕录制配置
var screenRecordOptions = {
    type: 'video',
    mimeType: 'video/webm;codecs=vp9',
    disableLogs: false,
    timeSlice: 1000, // 每秒触发一次数据可用事件
    // 视频配置
    video: {
        width: { ideal: 1920 },
        height: { ideal: 1080 },
        frameRate: { ideal: 30 }
    },
    // Canvas配置
    canvas: {
        width: 1920,
        height: 1080
    }
};

6.4 屏幕录制控制

实现完整的屏幕录制控制功能:

屏幕录制控制

// 屏幕录制控制器
class ScreenRecorder {
    constructor() {
        this.recorder = null;
        this.stream = null;
    }
    
    // 开始屏幕录制
    async startRecording() {
        try {
            // 获取屏幕流
            this.stream = await navigator.mediaDevices.getDisplayMedia({
                video: true,
                audio: true
            });
            
            // 监听屏幕共享结束事件
            this.stream.getVideoTracks()[0].onended = () => {
                this.stopRecording();
            };
            
            // 初始化RecordRTC
            this.recorder = RecordRTC(this.stream, {
                type: 'video',
                mimeType: 'video/webm'
            });
            
            // 开始录制
            this.recorder.startRecording();
            console.log('屏幕录制已开始');
        } catch (error) {
            console.error('开始屏幕录制失败:', error);
        }
    }
    
    // 停止屏幕录制
    stopRecording() {
        if (this.recorder) {
            this.recorder.stopRecording(() => {
                const blob = this.recorder.getBlob();
                console.log('屏幕录制已完成');
                
                // 处理录制结果
                this.handleRecording(blob);
                
                // 停止所有轨道
                if (this.stream) {
                    this.stream.getTracks().forEach(track => track.stop());
                }
            });
        }
    }
    
    // 处理录制结果
    handleRecording(blob) {
        // 创建下载链接
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `screen-recording-${new Date().getTime()}.webm`;
        a.click();
    }
}

// 使用示例
const screenRecorder = new ScreenRecorder();
// screenRecorder.startRecording();

6.5 屏幕录制高级功能

实现更高级的屏幕录制功能:

高级屏幕录制功能

// 带预览的屏幕录制
class AdvancedScreenRecorder {
    constructor() {
        this.recorder = null;
        this.stream = null;
        this.previewVideo = null;
    }
    
    // 初始化录制器
    init(previewElementId) {
        this.previewVideo = document.getElementById(previewElementId);
    }
    
    // 开始录制
    async startRecording() {
        try {
            // 获取屏幕流
            this.stream = await navigator.mediaDevices.getDisplayMedia({
                video: {
                    width: { ideal: 1920 },
                    height: { ideal: 1080 }
                },
                audio: true
            });
            
            // 显示预览
            if (this.previewVideo) {
                this.previewVideo.srcObject = this.stream;
            }
            
            // 监听结束事件
            this.stream.getVideoTracks()[0].onended = () => {
                this.stopRecording();
            };
            
            // 初始化RecordRTC
            this.recorder = RecordRTC(this.stream, {
                type: 'video',
                mimeType: 'video/webm',
                timeSlice: 1000,
                ondataavailable: (blob) => {
                    // 实时处理数据块(可选)
                    console.log('数据块可用:', blob.size);
                }
            });
            
            // 开始录制
            this.recorder.startRecording();
        } catch (error) {
            console.error('录制失败:', error);
        }
    }
    
    // 暂停录制
    pauseRecording() {
        if (this.recorder) {
            this.recorder.pauseRecording();
        }
    }
    
    // 恢复录制
    resumeRecording() {
        if (this.recorder) {
            this.recorder.resumeRecording();
        }
    }
    
    // 停止录制
    stopRecording() {
        if (this.recorder) {
            this.recorder.stopRecording(() => {
                const blob = this.recorder.getBlob();
                
                // 清除预览
                if (this.previewVideo) {
                    this.previewVideo.srcObject = null;
                }
                
                // 处理结果
                this.handleRecording(blob);
                
                // 停止流
                if (this.stream) {
                    this.stream.getTracks().forEach(track => track.stop());
                }
            });
        }
    }
    
    // 处理录制结果
    handleRecording(blob) {
        // 保存文件
        RecordRTC.invokeSaveAsDialog(blob);
    }
}