const { RTCVideoSource } = require('wrtc').nonstandard; const ffmpeg = require('fluent-ffmpeg') class VideoSourceService extends RTCVideoSource { constructor() { super() //videosource int this.command = null // 存储视频源 this.cache = Buffer.alloc(0) } // 创建通道 createTrack() { const track = super.createTrack() return track } // 获取视频源 async start() { if (this.command !== null) this.stop() const width = 400, height = 300 // libx264编码后花屏 this.command = ffmpeg('/dev/video0') .size(`${width}x${height}`) .outputOptions(['-pix_fmt yuv420p']) .format("rawvideo") .on('start', () => { console.log('Video start !'); }) .on('error', (err) => { console.log('Video processing An error occurred: ' + err.message); // 退出进程 process.exit(1) }) this.ffstream = this.command.pipe(); this.ffstream.on('data', (buffer) => { this.cache = Buffer.concat([this.cache, buffer]) }); // 整理buffer const frameSize = width * height * 1.5; const processData = () => { while (this.cache.length > frameSize) { const buffer = this.cache.slice(0, frameSize) this.cache = this.cache.slice(frameSize) this.onFrame({ width, height, data: new Uint8ClampedArray(buffer) }) } if (this.command !== null) { setTimeout(() => processData()) } } processData() } // 停止获取 stop() { console.log("Video source stop"); if (this.command != null) { this.command.kill("SIGHUP") this.command = null } } } module.exports = VideoSourceService