Vue.js项目中如何从摄像头流逐帧提取画面并通过WebSocket发送
Vue.js实现摄像头实时逐帧提取与WebSocket传输方案
实现核心逻辑
原生HTML中用document.getElementById获取视频元素的操作,在Vue中替换为ref绑定获取DOM/组件实例即可,原有帧提取的Canvas绘制逻辑可以完全复用,不受框架影响。
具体实现步骤
- 给video-js-record组件绑定ref
修改模板中的组件代码,添加ref属性用于后续获取组件内的视频实例:
<video-js-record ref="videoRecorder" @recordingStarted="onVideoRecording" @recordingEnded="onRecordingEnded" ></video-js-record>
- 扩展data变量存储采集状态
在现有data中新增两个变量,用于控制采集定时任务和存储Canvas实例:
data() { return { // 原有变量保持不变 countDown: 10, showVideo: false, timeShow: false, // 新增帧采集相关变量 frameCaptureTimer: null, captureCanvas: null } }
- 实现帧采集与发送方法
在methods中新增两个方法,负责逐帧提取和WebSocket发送:
// 启动帧采集 startFrameCapture() { // 从videoJsRecord组件中获取原生video元素,根据你的组件实际暴露的实例调整属性名 const videoElement = this.$refs.videoRecorder.$el.querySelector('video') // 初始化Canvas this.captureCanvas = document.createElement('canvas') this.captureCanvas.width = videoElement.videoWidth this.captureCanvas.height = videoElement.videoHeight const ctx = this.captureCanvas.getContext('2d') // 按自定义间隔采集,不受页面渲染帧率限制,调整间隔数值可控制采集帧率 // 例:30帧/秒对应间隔约33ms,60帧/秒对应间隔约16ms this.frameCaptureTimer = setInterval(() => { // 绘制当前视频帧到Canvas ctx.drawImage(videoElement, 0, 0, this.captureCanvas.width, this.captureCanvas.height) // 转成Blob二进制数据发送(比base64性能更好、带宽占用更低) this.captureCanvas.toBlob((blob) => { // 通过WebSocket发送帧数据 this.$socket.emit('videoFrame', { segmentId: this.dataSegmentId, frame: blob, timestamp: Date.now() }) }, 'image/jpeg', 0.8) // 可调整图片格式和质量参数 }, 33) }, // 停止帧采集 stopFrameCapture() { if (this.frameCaptureTimer) { clearInterval(this.frameCaptureTimer) this.frameCaptureTimer = null } this.captureCanvas = null }
- 关联录制生命周期回调
在现有的录制开始、结束回调中调用对应的采集控制方法:
onVideoRecording() { this.timeShow = true this.showVideo = false this.countDownTimer() // 启动帧采集 this.startFrameCapture() }, async onRecordingEnded(player) { // 停止帧采集 this.stopFrameCapture() // 原有逻辑保持不变 this.showVideo = true this.timeShow = false this.countDown = 10 // ... 原有视频上传逻辑 }
注意事项
- 若你的
videoJsRecord组件已经暴露了原生video实例,可直接通过实例属性获取,不需要手动querySelector查询 - 可根据业务需求调整采集间隔、图片格式、压缩质量参数,平衡传输带宽和画面清晰度
- 发送大体积帧数据时建议开启WebSocket二进制传输模式,进一步降低传输开销
内容的提问来源于stack exchange,提问作者Aimen Wajahat
相关产品推荐
相关产品推荐

