| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- 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
|