// utils/record.js // 录屏工具类 class ScreenRecorder { constructor() { this.recordModule = null this.eventModule = null this.isRecording = false this.recordTime = 0 this.recordTimer = null this.eventListeners = new Map() this.init() } // 初始化 init() { try { // 获取原生模块 this.recordModule = uni.requireNativePlugin('Record-Module') this.eventModule = uni.requireNativePlugin('RecordEvent-Module') console.log('录屏模块初始化成功') } catch (error) { console.error('录屏模块初始化失败:', error) } } // 开始录屏 start(options = {}) { return new Promise((resolve, reject) => { if (!this.recordModule) { reject(new Error('录屏模块未初始化')) return } if (this.isRecording) { reject(new Error('已经在录制中')) return } const defaultOptions = { width: 720, // 宽度 height: 1280, // 高度 bitRate: 4000000, // 比特率 4Mbps fileName: null, // 自定义文件名 recordAudio: true // 是否录制音频 } const recordOptions = { ...defaultOptions, ...options } console.log('开始录屏,参数:', recordOptions) this.recordModule.startRecording(recordOptions, (result) => { console.log('开始录屏结果:', result) if (result.code === 0 && result.success) { this.isRecording = true this.startTimer() // 触发开始事件 this.emit('start', { options: recordOptions }) resolve({ success: true, message: '开始录屏成功', data: result }) } else { reject(new Error(result.message || '开始录屏失败')) } }) }) } // 停止录屏 stop() { return new Promise((resolve, reject) => { if (!this.recordModule) { reject(new Error('录屏模块未初始化')) return } if (!this.isRecording) { resolve({ success: true, message: '当前没有在录制' }) return } console.log('停止录屏') this.recordModule.stopRecording((result) => { console.log('停止录屏结果:', result) this.isRecording = false this.stopTimer() if (result.code === 0 && result.success) { // 触发停止事件 this.emit('stop', {}) resolve({ success: true, message: '停止录屏成功', data: result }) } else { reject(new Error(result.message || '停止录屏失败')) } }) }) } // 获取录屏状态 getStatus() { return new Promise((resolve, reject) => { if (!this.recordModule) { reject(new Error('录屏模块未初始化')) return } this.recordModule.getRecordingStatus((result) => { this.isRecording = result.isRecording resolve({ isRecording: result.isRecording, duration: result.duration, filePath: result.filePath, ...result }) }) }) } // 获取录屏文件列表 getFileList() { return new Promise((resolve, reject) => { if (!this.recordModule) { reject(new Error('录屏模块未初始化')) return } this.recordModule.getRecordFiles((result) => { if (result.code === 0) { resolve({ success: true, files: result.files, count: result.count }) } else { reject(new Error(result.message || '获取文件列表失败')) } }) }) } // 删除录屏文件 deleteFile(filePath) { return new Promise((resolve, reject) => { if (!this.recordModule) { reject(new Error('录屏模块未初始化')) return } this.recordModule.deleteRecordFile(filePath, (result) => { if (result.code === 0 && result.success) { resolve({ success: true, message: '删除成功' }) } else { reject(new Error(result.message || '删除失败')) } }) }) } // 检查录屏权限 checkPermission() { return new Promise((resolve, reject) => { if (!this.recordModule) { reject(new Error('录屏模块未初始化')) return } this.recordModule.checkPermission((result) => { resolve({ hasPermission: result.hasPermission, message: result.message, ...result }) }) }) } // 开始事件监听 startListen() { return new Promise((resolve, reject) => { if (!this.eventModule) { reject(new Error('事件模块未初始化')) return } this.eventModule.startListen((result) => { if (result.code === 0 && result.success) { // 监听全局事件 uni.$on('recordEvent', this.handleRecordEvent.bind(this)) resolve({ success: true, message: '开始监听成功' }) } else { reject(new Error(result.message || '开始监听失败')) } }) }) } // 停止事件监听 stopListen() { return new Promise((resolve, reject) => { if (!this.eventModule) { reject(new Error('事件模块未初始化')) return } this.eventModule.stopListen((result) => { if (result.code === 0 && result.success) { // 移除全局事件监听 uni.$off('recordEvent', this.handleRecordEvent.bind(this)) resolve({ success: true, message: '停止监听成功' }) } else { reject(new Error(result.message || '停止监听失败')) } }) }) } // 处理录屏事件 handleRecordEvent(event) { console.log('收到录屏事件:', event) const { type, data } = event switch (type) { case 'onRecordEvent': this.handleNativeEvent(data) break } } // 处理原生事件 handleNativeEvent(data) { const { event, filePath } = data switch (event) { case 'start': console.log('录屏开始,文件路径:', filePath) this.emit('started', { filePath }) break case 'stop': console.log('录屏停止,文件路径:', filePath) this.emit('stopped', { filePath }) break } } // 开始计时器 startTimer() { this.recordTime = 0 this.recordTimer = setInterval(() => { this.recordTime++ // 触发计时事件 this.emit('timeupdate', { currentTime: this.recordTime }) }, 1000) } // 停止计时器 stopTimer() { if (this.recordTimer) { clearInterval(this.recordTimer) this.recordTimer = null this.recordTime = 0 } } // 格式化时间 formatTime(seconds) { const hours = Math.floor(seconds / 3600) const minutes = Math.floor((seconds % 3600) / 60) const secs = seconds % 60 if (hours > 0) { return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}` } else { return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}` } } // 事件监听 on(event, callback) { if (!this.eventListeners.has(event)) { this.eventListeners.set(event, []) } this.eventListeners.get(event).push(callback) } // 取消事件监听 off(event, callback) { if (this.eventListeners.has(event)) { const listeners = this.eventListeners.get(event) const index = listeners.indexOf(callback) if (index > -1) { listeners.splice(index, 1) } } } // 触发事件 emit(event, data) { if (this.eventListeners.has(event)) { this.eventListeners.get(event).forEach(callback => { try { callback(data) } catch (error) { console.error(`执行事件 ${event} 的回调失败:`, error) } }) } } // 销毁 destroy() { this.stop() this.stopListen() this.eventListeners.clear() this.recordModule = null this.eventModule = null } } // 创建单例 let recorderInstance = null export function getScreenRecorder() { if (!recorderInstance) { recorderInstance = new ScreenRecorder() } return recorderInstance } export default getScreenRecorder