胡斌

use timer to feed captured bitmap to ffmpeg,to avoid locking of frame

正在显示 1 个修改的文件 包含 55 行增加9 行删除
@@ -22,13 +22,32 @@ ipc.on('close-main-window', function () { @@ -22,13 +22,32 @@ ipc.on('close-main-window', function () {
22 22
23 var lastRenderTime = 0; 23 var lastRenderTime = 0;
24 24
  25 +var contentBitmap = null;
  26 +
  27 +var duration = 10000;//set duration 10s
  28 +
  29 +var start = Date.now()
  30 +
25 ipc.on('to-main-timer', function () { 31 ipc.on('to-main-timer', function () {
26 - if (Date.now() - lastRenderTime >= 10000) { 32 + /* if(lastMainTimerCalledTime){
  33 + var now = Date.now();
  34 + console.log("time-diff:",now - lastMainTimerCalledTime);
  35 + lastMainTimerCalledTime = now;
  36 + }
  37 + else{
  38 + lastMainTimerCalledTime = Date.now();
  39 + }
  40 +*/
  41 + if(contentBitmap && streamIn){
  42 + streamIn.write(contentBitmap);
  43 + }
  44 +
  45 + if (Date.now() - start >= duration) {
27 if (streamIn) { 46 if (streamIn) {
28 streamIn.end(); 47 streamIn.end();
29 streamIn = null; 48 streamIn = null;
30 } 49 }
31 - if (Date.now() - lastRenderTime >= 15000) { 50 + if (Date.now() - start >= duration + 10000) {//quit after duration + 10s
32 quit(); 51 quit();
33 } 52 }
34 } 53 }
@@ -73,17 +92,29 @@ if(!argv.h){//width @@ -73,17 +92,29 @@ if(!argv.h){//width
73 argv.h = "600"; 92 argv.h = "600";
74 } 93 }
75 94
  95 +if(!argv.b){//bitrate
  96 + argv.b = "1000k";
  97 +}
  98 +
  99 +if(!argv.o){//offscreen
  100 + argv.o = true;
  101 +}
  102 +
76 function startFFmpeg(videosize) { 103 function startFFmpeg(videosize) {
77 const args = ['-y','-f', 'rawvideo', '-pix_fmt', 'bgra', '-s' ]; 104 const args = ['-y','-f', 'rawvideo', '-pix_fmt', 'bgra', '-s' ];
78 105
79 var size = videosize.width + 'x' + videosize.height 106 var size = videosize.width + 'x' + videosize.height
80 107
81 args.push(size); 108 args.push(size);
  109 + args.push('-r');
  110 + args.push(argv.f);
82 args.push.apply( args, ['-i', 'pipe:0'] ); 111 args.push.apply( args, ['-i', 'pipe:0'] );
  112 + args.push('-vf')
  113 + args.push('fps=fps='+argv.f)
83 args.push('-c:v'); 114 args.push('-c:v');
84 args.push('libx264'); 115 args.push('libx264');
85 args.push('-b:v'); 116 args.push('-b:v');
86 - args.push('1024k'); 117 + args.push(argv.b);
87 args.push('-r:v'); 118 args.push('-r:v');
88 args.push(argv.f); 119 args.push(argv.f);
89 args.push('-an'); 120 args.push('-an');
@@ -92,8 +123,13 @@ function startFFmpeg(videosize) { @@ -92,8 +123,13 @@ function startFFmpeg(videosize) {
92 console.log(args.join` `); 123 console.log(args.join` `);
93 124
94 ffmpeg = spawn('ffmpeg', args); 125 ffmpeg = spawn('ffmpeg', args);
  126 + if (ffmpeg) {
95 ffmpeg.stderr.on('data', chunk => console.log(chunk.toString())); 127 ffmpeg.stderr.on('data', chunk => console.log(chunk.toString()));
96 streamIn = duplexer(ffmpeg.stdin, ffmpeg.stdout); 128 streamIn = duplexer(ffmpeg.stdin, ffmpeg.stdout);
  129 + }
  130 + else {
  131 + console.log("can't start ffmpeg,please make sure ffmpeg is avaiable");
  132 + }
97 } 133 }
98 134
99 app.disableHardwareAcceleration() 135 app.disableHardwareAcceleration()
@@ -104,22 +140,27 @@ app.once('ready', () => { @@ -104,22 +140,27 @@ app.once('ready', () => {
104 width:argv.w, 140 width:argv.w,
105 height:argv.h, 141 height:argv.h,
106 webPreferences: { 142 webPreferences: {
107 - offscreen: true 143 + offscreen: argv.o
108 } 144 }
109 }) 145 })
110 win.loadURL(argv.u) 146 win.loadURL(argv.u)
111 147
112 -win.webContents.executeJavaScript('const ipcToMain = require("electron").ipcRenderer;function timerToMain (){ ipcToMain.send("to-main-timer");}setInterval(timerToMain,10000);'); 148 + var intervalms = 1000 / parseInt(argv.f);
113 149
  150 + var injectScript = 'const ipcToMain = require("electron").ipcRenderer;function timerToMain (){ ipcToMain.send("to-main-timer");}setInterval(timerToMain,' + intervalms + ');';
114 151
115 - var start = Date.now() 152 + win.webContents.executeJavaScript(injectScript);
116 153
117 - var duration = parseInt(argv.d)*1000 154 + duration = parseInt(argv.d)*1000
118 155
119 win.webContents.on("paint", function (event, dirty, image) { 156 win.webContents.on("paint", function (event, dirty, image) {
120 157
121 if (!ffmpeg) { 158 if (!ffmpeg) {
  159 + start = Date.now();
122 startFFmpeg(image.getSize()); 160 startFFmpeg(image.getSize());
  161 + if(!ffmpeg){
  162 + sendQuit();
  163 + }
123 } 164 }
124 lastRenderTime = Date.now(); 165 lastRenderTime = Date.now();
125 var elapsed = lastRenderTime - start 166 var elapsed = lastRenderTime - start
@@ -130,11 +171,12 @@ win.webContents.executeJavaScript('const ipcToMain = require("electron").ipcRend @@ -130,11 +171,12 @@ win.webContents.executeJavaScript('const ipcToMain = require("electron").ipcRend
130 } 171 }
131 console.log("done") 172 console.log("done")
132 if(elapsed > duration + 5000){//delay 5s after closingSgit l pipe ,then close 173 if(elapsed > duration + 5000){//delay 5s after closingSgit l pipe ,then close
133 - win.webContents.executeJavaScript('require("electron").ipcRenderer.send("close-main-window")'); 174 + sendQuit();
134 } 175 }
135 } 176 }
136 else { 177 else {
137 - streamIn.write(image.getBitmap()); 178 + // streamIn.write(image.getBitmap());
  179 + contentBitmap = image.toBitmap();
138 } 180 }
139 181
140 //console.log("painting", elapsed, win.webContents.isOffscreen(), win.webContents.getFrameRate()) 182 //console.log("painting", elapsed, win.webContents.isOffscreen(), win.webContents.getFrameRate())
@@ -142,3 +184,7 @@ win.webContents.executeJavaScript('const ipcToMain = require("electron").ipcRend @@ -142,3 +184,7 @@ win.webContents.executeJavaScript('const ipcToMain = require("electron").ipcRend
142 }) 184 })
143 win.webContents.setFrameRate(parseInt(argv.f)); 185 win.webContents.setFrameRate(parseInt(argv.f));
144 }) 186 })
  187 +
  188 +function sendQuit(){
  189 + win.webContents.executeJavaScript('require("electron").ipcRenderer.send("close-main-window")');
  190 +}