最近使用electron做APP,主要就是模仿stf,想要实时显示手机图像,然后再做一点其他的操作。使用minicap获取手机屏幕截图,然后使用img实时刷新图片,然后发现,内存持正增长模式,毫无下降,直至电脑死机。。。。
为什么呢?经过各种研究发现如果不显示图片,从minicap中获得的二进制数组无论怎么操作都没有问题,只要把图片显示出来,立马崩溃。。。然后,尝试换了nwjs做实验,虽然内存也很高,但是并没有持续增长到死机。。。
由于图片不显示是不行的,因此最后采取了迂回的策略,将minicap传过来的图片用ffmpeg转换成了视频流,然后使用flvjs播放解决了内存问题。
flvjs播放视频流的代码如下:其中myvideo是<video>控件的id
let flvjs = require('flv.js')
if (flvjs.isSupported()) {
var videoElement = document.getElementById('myvideo');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true,
url: 'http://localhost:8888'
}, {
isLive: true,
enableStashBuffer: false
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
使用ffmpeg转换视频流的代码如下:
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffprobePath = require('@ffprobe-installer/ffprobe').path;
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath);
let source = new stream.Duplex({objectMode: true});
source._write = () => {}
source.resume();
source._read = (data) => {
}
source.on('data', (chunk) => {
})
let videoStream = null
var http = require('http');
//创建server,监听8888端口,发送视频流
http.createServer(function (request, response) {
let command = ffmpeg().input(source).inputOptions([
'-f image2pipe',
])
.videoCodec('libx264')
.videoBitrate('1000k')
.size('480x800')
.outputOptions(
'-tune zerolatency',
)
.format('flv')
.inputFPS(100)
.on('error', function(err) {
console.log('An error occurred: ' + err.message);
})
.on('end', function() {
console.log('Processing finished !');
videoStream = null;
})
videoStream = command.pipe();
videoStream.pipe(response)
}).listen(8888);
其中,source是图片的流,minicap获得图片都push到该stream中,ffmpeg将从中取出图片转换成视频流。其中, @ffmpeg-installer/ffmpeg是ffmpeg命令的包,调试的时候使用没有问题,打包之后却启动ffmpeg失败了,最后将其中的ffmpeg取出放到用户电脑的固定目录下,并将path设置为该目录后,执行成功。当然,如果你的电脑上安装了ffmpeg的话,它就没有用了,不过,我打算做一个app,感觉让用户安装太多的命令不怎么友好。
使用一个interval定时往source里面添加图片,其中的image在minicap获得新图片的时候更新。
let inter = setInterval(()=>{
if(image){
source.push(image)
}
}, 30)
记录一下解决方案。
