第13章 高级配置
在本章中,我们将深入学习RecordRTC的高级配置选项,包括性能优化、兼容性设置和安全配置等。
13.1 性能优化配置
通过合理的配置优化录制性能:
性能优化配置
// 性能优化配置选项
var performanceOptions = {
type: 'video',
mimeType: 'video/webm;codecs=vp9',
// 视频性能配置
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: { ideal: 30, max: 30 }, // 限制帧率
aspectRatio: 16/9
},
// Canvas性能配置
canvas: {
width: 1280,
height: 720,
// 禁用WebAssembly以提高兼容性
disableWebAssembly: true,
// 使用更高效的绘制方法
useWham: false
},
// 时间切片优化
timeSlice: 2000, // 2秒切片,平衡性能和内存
// 禁用日志以提高性能
disableLogs: true,
// 设置合适的缓冲区大小
bufferSize: 4096,
// 音频性能配置
numberOfAudioChannels: 1, // 单声道以减少处理负担
sampleRate: 44100
};
// 根据设备性能动态调整配置
function getPerformanceOptimizedConfig(devicePerformance) {
const baseConfig = {
type: 'video',
mimeType: 'video/webm'
};
switch(devicePerformance) {
case 'high':
// 高性能设备
return Object.assign(baseConfig, {
video: {
width: { ideal: 1920 },
height: { ideal: 1080 },
frameRate: { ideal: 30 }
},
canvas: {
width: 1920,
height: 1080
},
bitrate: 2048 * 1024 // 2Mbps
});
case 'medium':
// 中等性能设备
return Object.assign(baseConfig, {
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: { ideal: 30 }
},
canvas: {
width: 1280,
height: 720
},
bitrate: 1024 * 1024 // 1Mbps
});
case 'low':
// 低性能设备
return Object.assign(baseConfig, {
video: {
width: { ideal: 640 },
height: { ideal: 480 },
frameRate: { ideal: 15 }
},
canvas: {
width: 640,
height: 480
},
bitrate: 512 * 1024 // 0.5Mbps
});
default:
return baseConfig;
}
}
13.2 兼容性配置
确保在不同浏览器和设备上的兼容性:
兼容性配置
// 浏览器兼容性检测和配置
class CompatibilityConfig {
static detectBrowser() {
const userAgent = navigator.userAgent;
if (userAgent.indexOf('Chrome') > -1) {
return 'chrome';
} else if (userAgent.indexOf('Firefox') > -1) {
return 'firefox';
} else if (userAgent.indexOf('Safari') > -1) {
return 'safari';
} else if (userAgent.indexOf('Edg') > -1) {
return 'edge';
} else {
return 'unknown';
}
}
static getBrowserSpecificConfig() {
const browser = this.detectBrowser();
const baseConfig = {
type: 'video'
};
switch(browser) {
case 'chrome':
return Object.assign(baseConfig, {
mimeType: 'video/webm;codecs=vp9',
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
}
});
case 'firefox':
return Object.assign(baseConfig, {
mimeType: 'video/webm;codecs=vp8',
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
}
});
case 'safari':
return Object.assign(baseConfig, {
mimeType: 'video/mp4',
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
}
});
case 'edge':
return Object.assign(baseConfig, {
mimeType: 'video/webm;codecs=vp9',
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
}
});
default:
// 通用配置
return Object.assign(baseConfig, {
mimeType: 'video/webm',
video: {
width: { max: 1280 },
height: { max: 720 }
}
});
}
}
static getMobileConfig() {
const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
if (isMobile) {
return {
type: 'video',
mimeType: 'video/webm',
video: {
facingMode: 'user', // 默认前置摄像头
width: { ideal: 640 },
height: { ideal: 480 },
frameRate: { ideal: 24 }
},
canvas: {
width: 640,
height: 480
},
numberOfAudioChannels: 1,
sampleRate: 22050 // 降低采样率以节省资源
};
}
return null;
}
}
// 使用兼容性配置
function getOptimalConfig() {
// 检查是否为移动设备
const mobileConfig = CompatibilityConfig.getMobileConfig();
if (mobileConfig) {
return mobileConfig;
}
// 获取浏览器特定配置
return CompatibilityConfig.getBrowserSpecificConfig();
}
13.3 安全配置
确保录制过程中的数据安全:
安全配置
// 安全录制配置
class SecureRecordingConfig {
static getSecureOptions() {
return {
type: 'video',
mimeType: 'video/webm',
// 视频安全配置
video: {
// 不要求特定设备以保护隐私
// deviceId: undefined,
// 限制分辨率以减少数据量
width: { max: 1920 },
height: { max: 1080 },
// 启用隐私保护功能
noiseSuppression: true,
echoCancellation: true
},
// 音频安全配置
numberOfAudioChannels: 1,
sampleRate: 44100,
// 禁用可能泄露信息的功能
disableLogs: true,
// 使用本地处理,避免数据上传
ondataavailable: function(blob) {
// 仅在本地处理数据
console.log('数据块已生成,大小:', blob.size);
// 可以选择不上传或加密后上传
// this.handleSecureUpload(blob);
}
};
}
// 安全上传处理
static handleSecureUpload(blob) {
// 加密数据
this.encryptAndUpload(blob)
.then(response => {
console.log('安全上传成功');
})
.catch(error => {
console.error('上传失败:', error);
});
}
// 数据加密和上传
static async encryptAndUpload(blob) {
// 这里可以实现数据加密逻辑
// 例如使用Web Crypto API
try {
// 模拟加密过程
const encryptedData = await this.encryptData(blob);
// 上传加密数据
const formData = new FormData();
formData.append('data', encryptedData);
formData.append('timestamp', Date.now());
const response = await fetch('/api/secure-upload', {
method: 'POST',
body: formData
});
return response;
} catch (error) {
throw new Error('加密上传失败: ' + error.message);
}
}
// 数据加密方法
static async encryptData(blob) {
// 使用Web Crypto API进行加密
// 这里是简化示例
const arrayBuffer = await blob.arrayBuffer();
console.log('数据加密完成,原始大小:', arrayBuffer.byteLength);
// 实际项目中应实现真正的加密逻辑
return new Blob([arrayBuffer], { type: blob.type });
}
// 权限管理
static async requestPermissions() {
try {
// 请求媒体权限
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
// 立即停止流以保护隐私
stream.getTracks().forEach(track => track.stop());
return true;
} catch (error) {
console.error('权限请求失败:', error);
return false;
}
}
}
13.4 内存管理配置
优化内存使用,防止内存泄漏:
内存管理配置
// 内存管理配置
class MemoryManagementConfig {
static getMemoryOptimizedConfig() {
return {
type: 'video',
mimeType: 'video/webm',
// 时间切片配置以控制内存使用
timeSlice: 1000, // 1秒切片
// 限制缓冲区大小
bufferSize: 2048,
// 视频配置
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
},
// Canvas配置
canvas: {
width: 1280,
height: 720,
// 禁用可能消耗大量内存的功能
disableWebAssembly: true
},
// 数据可用回调中及时处理数据
ondataavailable: function(blob) {
// 处理完数据后及时释放
this.handleAndReleaseBlob(blob);
}
};
}
// 处理并释放Blob数据
static handleAndReleaseBlob(blob) {
// 处理数据
console.log('处理数据块,大小:', blob.size);
// 如果创建了URL,记得及时释放
// const url = URL.createObjectURL(blob);
// 使用完后: URL.revokeObjectURL(url);
}
// 内存监控
static monitorMemory() {
if (performance.memory) {
const memoryInfo = performance.memory;
console.log('内存使用情况:');
console.log('- 总内存:', Math.round(memoryInfo.totalJSHeapSize / 1024 / 1024), 'MB');
console.log('- 已使用:', Math.round(memoryInfo.usedJSHeapSize / 1024 / 1024), 'MB');
console.log('- 限制:', Math.round(memoryInfo.jsHeapSizeLimit / 1024 / 1024), 'MB');
// 如果内存使用过高,可以采取措施
if (memoryInfo.usedJSHeapSize > memoryInfo.jsHeapSizeLimit * 0.8) {
console.warn('内存使用接近限制,建议停止录制');
return false;
}
}
return true;
}
// 资源清理
static cleanupResources(recorder, stream) {
// 停止录制器
if (recorder) {
recorder.destroy();
}
// 停止媒体流
if (stream) {
stream.getTracks().forEach(track => {
track.stop();
});
}
// 强制垃圾回收(如果可用)
if (window.gc) {
window.gc();
}
console.log('资源清理完成');
}
}
// 使用内存管理配置
function startMemoryOptimizedRecording(stream) {
const config = MemoryManagementConfig.getMemoryOptimizedConfig();
const recorder = RecordRTC(stream, config);
// 定期监控内存
const memoryCheckInterval = setInterval(() => {
if (!MemoryManagementConfig.monitorMemory()) {
// 内存使用过高,停止录制
recorder.stopRecording();
clearInterval(memoryCheckInterval);
}
}, 5000);
// 录制结束后清理
recorder.onstop = () => {
clearInterval(memoryCheckInterval);
MemoryManagementConfig.cleanupResources(recorder, stream);
};
recorder.startRecording();
return recorder;
}
13.5 网络优化配置
在网络环境较差时的配置优化:
网络优化配置
// 网络优化配置
class NetworkOptimizedConfig {
static getConnectionType() {
if (navigator.connection) {
return {
type: navigator.connection.effectiveType,
downlink: navigator.connection.downlink,
rtt: navigator.connection.rtt
};
}
return { type: 'unknown' };
}
static getNetworkAdaptiveConfig() {
const connection = this.getConnectionType();
const baseConfig = {
type: 'video',
mimeType: 'video/webm'
};
switch(connection.type) {
case 'slow-2g':
case '2g':
// 极慢网络
return Object.assign(baseConfig, {
video: {
width: { ideal: 320 },
height: { ideal: 240 },
frameRate: { ideal: 10 }
},
canvas: {
width: 320,
height: 240
},
bitrate: 256 * 1024, // 0.25Mbps
timeSlice: 3000, // 3秒切片
numberOfAudioChannels: 1,
sampleRate: 22050
});
case '3g':
// 中等网络
return Object.assign(baseConfig, {
video: {
width: { ideal: 640 },
height: { ideal: 480 },
frameRate: { ideal: 20 }
},
canvas: {
width: 640,
height: 480
},
bitrate: 512 * 1024, // 0.5Mbps
timeSlice: 2000, // 2秒切片
numberOfAudioChannels: 1,
sampleRate: 44100
});
case '4g':
case 'wifi':
// 快速网络
return Object.assign(baseConfig, {
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: { ideal: 30 }
},
canvas: {
width: 1280,
height: 720
},
bitrate: 1024 * 1024, // 1Mbps
timeSlice: 1000, // 1秒切片
numberOfAudioChannels: 2,
sampleRate: 44100
});
default:
// 默认配置
return Object.assign(baseConfig, {
video: {
width: { ideal: 640 },
height: { ideal: 480 }
},
canvas: {
width: 640,
height: 480
},
bitrate: 512 * 1024,
timeSlice: 2000
});
}
}
// 断点续传配置
static getResumableConfig() {
return {
type: 'video',
mimeType: 'video/webm',
timeSlice: 5000, // 5秒切片便于断点续传
ondataavailable: function(blob) {
// 保存数据块用于断点续传
this.saveChunkForResume(blob);
}
};
}
// 保存数据块用于断点续传
static saveChunkForResume(blob) {
// 保存到本地存储或IndexedDB
const chunkId = 'chunk_' + Date.now();
const reader = new FileReader();
reader.onload = function(e) {
const arrayBuffer = e.target.result;
// 保存到IndexedDB或其他存储
localStorage.setItem(chunkId, JSON.stringify({
data: Array.from(new Uint8Array(arrayBuffer)),
timestamp: Date.now()
}));
};
reader.readAsArrayBuffer(blob);
}
// 恢复录制
static async resumeRecording() {
// 从存储中恢复之前的数据块
const chunks = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key.startsWith('chunk_')) {
const chunkData = JSON.parse(localStorage.getItem(key));
chunks.push(chunkData);
}
}
console.log('恢复录制,找到', chunks.length, '个数据块');
return chunks;
}
}