高级功能

本章将介绍videojs-record的高级功能,包括时间切片录制、实时处理、性能优化等专业特性。

9.1 时间切片录制

时间切片录制允许将长录制分割成多个小片段:

时间切片录制配置

// 启用时间切片录制
var player = videojs('myVideo', {
    controls: true,
    plugins: {
        record: {
            audio: true,
            video: true,
            // 设置时间切片为5秒
            timeSlice: 5000,
            // 启用实时预览
            preview: true
        }
    }
});

// 监听时间切片事件
player.on('timestamp', function(event, timestamp) {
    console.log('时间戳更新:', timestamp);
});

// 盪听数据可用事件
player.on('dataAvailable', function(event, data) {
    console.log('数据可用:', data);
    
    // 处理每个时间切片的数据
    handleTimeSliceData(data);
});

// 处理时间切片数据
function handleTimeSliceData(data) {
    // data包含当前时间切片的录制数据
    // 可以实时上传到服务器或进行其他处理
    
    // 上传到服务器
    uploadTimeSlice(data);
    
    // 或者保存到本地
    saveTimeSliceLocally(data);
}

// 上传时间切片数据
function uploadTimeSlice(data) {
    const formData = new FormData();
    formData.append('video', data.video, 'slice-' + Date.now() + '.webm');
    
    fetch('/upload', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(result => {
        console.log('上传成功:', result);
    })
    .catch(error => {
        console.error('上传失败:', error);
    });
}

9.2 实时数据处理

在录制过程中实时处理数据:

实时数据处理

// 实时数据处理配置
var player = videojs('myVideo', {
    controls: true,
    plugins: {
        record: {
            audio: true,
            video: true,
            timeSlice: 1000, // 每秒处理一次
            // 启用实时处理
            realTimeProcessing: true
        }
    }
});

// 实时处理类
class RealTimeProcessor {
    constructor() {
        this.processingQueue = [];
        this.isProcessing = false;
    }
    
    // 添加数据到处理队列
    addData(data) {
        this.processingQueue.push(data);
        this.processQueue();
    }
    
    // 处理队列
    async processQueue() {
        if (this.isProcessing || this.processingQueue.length === 0) {
            return;
        }
        
        this.isProcessing = true;
        
        while (this.processingQueue.length > 0) {
            const data = this.processingQueue.shift();
            await this.processData(data);
        }
        
        this.isProcessing = false;
    }
    
    // 处理单个数据块
    async processData(data) {
        try {
            // 实时分析数据
            const analysis = await this.analyzeData(data);
            
            // 实时转换数据
            const transformed = await this.transformData(data);
            
            // 实时上传数据
            await this.uploadData(transformed);
            
            console.log('数据处理完成:', analysis);
        } catch (error) {
            console.error('数据处理失败:', error);
        }
    }
    
    // 分析数据
    async analyzeData(data) {
        // 这里可以进行实时数据分析
        // 例如:音量检测、运动检测等
        return {
            timestamp: Date.now(),
            dataSize: data.video.size,
            duration: data.video.duration || 0
        };
    }
    
    // 转换数据
    async transformData(data) {
        // 这里可以进行实时数据转换
        // 例如:格式转换、压缩等
        return data;
    }
    
    // 上传数据
    async uploadData(data) {
        // 这里可以实时上传数据
        const formData = new FormData();
        formData.append('video', data.video);
        
        const response = await fetch('/realtime-upload', {
            method: 'POST',
            body: formData
        });
        
        return response.json();
    }
}

// 创建处理器实例
const processor = new RealTimeProcessor();

// 监听数据可用事件
player.on('dataAvailable', function(event, data) {
    // 将数据添加到处理队列
    processor.addData(data);
});

9.3 内存管理

优化内存使用,防止内存泄漏:

内存管理策略

// 内存管理配置
var player = videojs('myVideo', {
    controls: true,
    plugins: {
        record: {
            audio: true,
            video: true,
            // 限制内存使用
            maxMemory: 100 * 1024 * 1024, // 100MB
            // 自动清理录制数据
            autoCleanup: true,
            // 清理间隔
            cleanupInterval: 30000 // 30秒
        }
    }
});

// 内存监控类
class MemoryMonitor {
    constructor(player) {
        this.player = player;
        this.monitoring = false;
        this.threshold = 80; // 内存使用阈值(百分比)
    }
    
    // 开始监控
    startMonitoring() {
        this.monitoring = true;
        this.checkMemoryUsage();
    }
    
    // 停止监控
    stopMonitoring() {
        this.monitoring = false;
    }
    
    // 检查内存使用情况
    checkMemoryUsage() {
        if (!this.monitoring) return;
        
        // 获取内存使用信息(仅在支持的浏览器中)
        if (performance.memory) {
            const memoryInfo = performance.memory;
            const usedPercent = (memoryInfo.usedJSHeapSize / memoryInfo.jsHeapSizeLimit) * 100;
            
            console.log(`内存使用: ${usedPercent.toFixed(2)}%`);
            
            // 如果内存使用超过阈值,执行清理
            if (usedPercent > this.threshold) {
                this.cleanupMemory();
            }
        }
        
        // 每5秒检查一次
        setTimeout(() => this.checkMemoryUsage(), 5000);
    }
    
    // 清理内存
    cleanupMemory() {
        console.log('执行内存清理');
        
        // 清理录制数据
        if (this.player.recordedData) {
            // 释放Blob URL
            if (this.player.recordedData.video) {
                URL.revokeObjectURL(this.player.recordedData.video);
            }
            if (this.player.recordedData.audio) {
                URL.revokeObjectURL(this.player.recordedData.audio);
            }
            
            // 清空录制数据
            this.player.recordedData = null;
        }
        
        // 强制垃圾回收(如果可用)
        if (window.gc) {
            window.gc();
        }
        
        // 触发垃圾回收
        if (window.requestIdleCallback) {
            window.requestIdleCallback(() => {
                if (window.gc) {
                    window.gc();
                }
            });
        }
    }
}

// 创建内存监控器
const memoryMonitor = new MemoryMonitor(player);

// 开始内存监控
memoryMonitor.startMonitoring();

// 监听录制完成事件
player.on('finishRecord', function() {
    // 录制完成后清理内存
    setTimeout(() => {
        memoryMonitor.cleanupMemory();
    }, 1000);
});

9.4 性能优化

优化录制性能,提升用户体验:

性能优化策略

// 性能优化配置
var player = videojs('myVideo', {
    controls: true,
    plugins: {
        record: {
            audio: {
                sampleRate: 44100,
                channelCount: 1, // 单声道以减少处理负担
                audioBitRate: 64  // 降低比特率
            },
            video: {
                width: 1280,
                height: 720,
                frameRate: 24,   // 降低帧率
                videoBitRate: 1000 // 降低比特率
            },
            // 启用性能优化
            performanceOptimization: true,
            // 禁用不必要的功能
            thumbnail: false,
            // 使用worker处理
            useWorker: true,
            // 启用硬件加速
            hardwareAcceleration: true
        }
    }
});

// 性能监控类
class PerformanceMonitor {
    constructor(player) {
        this.player = player;
        this.metrics = {
            frameRate: 0,
            cpuUsage: 0,
            memoryUsage: 0,
            recordingQuality: 'high'
        };
        this.monitoring = false;
    }
    
    // 开始性能监控
    startMonitoring() {
        this.monitoring = true;
        this.collectMetrics();
    }
    
    // 停止性能监控
    stopMonitoring() {
        this.monitoring = false;
    }
    
    // 收集性能指标
    collectMetrics() {
        if (!this.monitoring) return;
        
        // 收集帧率信息
        this.collectFrameRate();
        
        // 收集CPU使用率
        this.collectCPUUsage();
        
        // 收集内存使用
        this.collectMemoryUsage();
        
        // 根据性能指标调整录制质量
        this.adjustRecordingQuality();
        
        // 每秒收集一次
        setTimeout(() => this.collectMetrics(), 1000);
    }
    
    // 收集帧率
    collectFrameRate() {
        // 这里可以使用Performance API或其他方法收集帧率
        // 简化示例:
        this.metrics.frameRate = Math.random() * 60;
    }
    
    // 收集CPU使用率
    collectCPUUsage() {
        // 这里可以使用Performance API或其他方法收集CPU使用率
        // 简化示例:
        this.metrics.cpuUsage = Math.random() * 100;
    }
    
    // 收集内存使用
    collectMemoryUsage() {
        if (performance.memory) {
            this.metrics.memoryUsage = 
                (performance.memory.usedJSHeapSize / performance.memory.jsHeapSizeLimit) * 100;
        }
    }
    
    // 调整录制质量
    adjustRecordingQuality() {
        const { cpuUsage, memoryUsage, frameRate } = this.metrics;
        
        // 如果CPU使用率过高或帧率过低,降低录制质量
        if (cpuUsage > 80 || frameRate < 20) {
            if (this.metrics.recordingQuality !== 'low') {
                this.metrics.recordingQuality = 'low';
                this.adjustSettings('low');
            }
        }
        // 如果性能良好,可以提高录制质量
        else if (cpuUsage < 50 && frameRate > 50) {
            if (this.metrics.recordingQuality !== 'high') {
                this.metrics.recordingQuality = 'high';
                this.adjustSettings('high');
            }
        }
    }
    
    // 调整设置
    adjustSettings(quality) {
        console.log(`调整录制质量到: ${quality}`);
        
        switch (quality) {
            case 'low':
                // 降低视频质量
                this.player.record().setVideoSettings({
                    width: 640,
                    height: 480,
                    frameRate: 15,
                    videoBitRate: 500
                });
                
                // 降低音频质量
                this.player.record().setAudioSettings({
                    sampleRate: 22050,
                    channelCount: 1,
                    audioBitRate: 32
                });
                break;
                
            case 'high':
                // 提高视频质量
                this.player.record().setVideoSettings({
                    width: 1920,
                    height: 1080,
                    frameRate: 30,
                    videoBitRate: 2500
                });
                
                // 提高音频质量
                this.player.record().setAudioSettings({
                    sampleRate: 48000,
                    channelCount: 2,
                    audioBitRate: 128
                });
                break;
        }
    }
}

// 创建性能监控器
const perfMonitor = new PerformanceMonitor(player);

// 开始性能监控
perfMonitor.startMonitoring();

9.5 错误恢复

实现错误恢复机制,提高录制稳定性:

错误恢复机制

// 错误恢复配置
var player = videojs('myVideo', {
    controls: true,
    plugins: {
        record: {
            audio: true,
            video: true,
            // 启用自动重试
            autoRetry: true,
            // 重试次数
            retryTimes: 3,
            // 重试延迟
            retryDelay: 2000,
            // 启用错误恢复
            errorRecovery: true
        }
    }
});

// 错误恢复管理器
class ErrorRecoveryManager {
    constructor(player) {
        this.player = player;
        this.retryCount = 0;
        this.maxRetries = 3;
        this.retryDelay = 2000;
        this.isRecovering = false;
    }
    
    // 处理录制错误
    handleRecordingError(error) {
        console.error('录制错误:', error);
        
        // 增加重试计数
        this.retryCount++;
        
        // 如果超过最大重试次数,显示错误信息
        if (this.retryCount > this.maxRetries) {
            this.showErrorMessage('录制失败,请检查设备连接后重试');
            return;
        }
        
        // 开始恢复过程
        this.startRecovery();
    }
    
    // 开始恢复过程
    async startRecovery() {
        if (this.isRecovering) return;
        
        this.isRecovering = true;
        console.log(`开始错误恢复,第 ${this.retryCount} 次重试`);
        
        try {
            // 显示恢复提示
            this.showRecoveryMessage(`录制中断,正在尝试恢复... (${this.retryCount}/${this.maxRetries})`);
            
            // 等待重试延迟
            await this.delay(this.retryDelay);
            
            // 停止当前录制
            this.player.record().stop();
            
            // 重新加载设备
            await this.player.record().loadDevice();
            
            // 重新开始录制
            this.player.record().start();
            
            // 恢复成功
            this.recoverySuccess();
        } catch (error) {
            console.error('恢复失败:', error);
            this.recoveryFailed(error);
        } finally {
            this.isRecovering = false;
        }
    }
    
    // 恢复成功
    recoverySuccess() {
        console.log('错误恢复成功');
        this.retryCount = 0; // 重置重试计数
        this.hideRecoveryMessage();
    }
    
    // 恢复失败
    recoveryFailed(error) {
        console.log('错误恢复失败');
        
        // 继续重试
        if (this.retryCount <= this.maxRetries) {
            setTimeout(() => this.startRecovery(), this.retryDelay);
        } else {
            this.showErrorMessage('录制失败,请检查设备连接后重试');
        }
    }
    
    // 显示恢复消息
    showRecoveryMessage(message) {
        const messageElement = document.getElementById('recoveryMessage');
        if (messageElement) {
            messageElement.textContent = message;
            messageElement.style.display = 'block';
        }
    }
    
    // 隐藏恢复消息
    hideRecoveryMessage() {
        const messageElement = document.getElementById('recoveryMessage');
        if (messageElement) {
            messageElement.style.display = 'none';
        }
    }
    
    // 显示错误消息
    showErrorMessage(message) {
        const errorElement = document.getElementById('errorMessage');
        if (errorElement) {
            errorElement.textContent = message;
            errorElement.style.display = 'block';
        }
        
        // 隐藏恢复消息
        this.hideRecoveryMessage();
    }
    
    // 延迟函数
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

// 创建错误恢复管理器
const errorRecovery = new ErrorRecoveryManager(player);

// 监听设备错误事件
player.on('deviceError', function(event, error) {
    errorRecovery.handleRecordingError(error);
});

// 监听录制错误事件
player.on('recordError', function(event, error) {
    errorRecovery.handleRecordingError(error);
});

提示:在实现高级功能时,需要充分考虑浏览器兼容性和性能影响,确保功能的稳定性和用户体验。