Electron内存爆炸

最近使用electron做APP,主要就是模仿stf,想要实时显示手机图像,然后再做一点其他的操作。使用minicap获取手机屏幕截图,然后使用img实时刷新图片,然后发现,内存持正增长模式,毫无下降,直至电脑死机。。。。

为什么呢?经过各种研究发现如果不显示图片,从minicap中获得的二进制数组无论怎么操作都没有问题,只要把图片显示出来,立马崩溃。。。然后,尝试换了nwjs做实验,虽然内存也很高,但是并没有持续增长到死机。。。

由于图片不显示是不行的,因此最后采取了迂回的策略,将minicap传过来的图片用ffmpeg转换成了视频流,然后使用flvjs播放解决了内存问题。

flvjs播放视频流的代码如下:其中myvideo是

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)

记录一下解决方案。


你可能感兴趣的:(nodejs)