胡斌

use ffmpeg to record video ok,need more improvement

  1 +'use strict';
  2 +
1 const {app, BrowserWindow} = require('electron'); 3 const {app, BrowserWindow} = require('electron');
  4 +const ipc = require('electron').ipcMain;
  5 +const duplexer = require('duplexer3');
  6 +const {spawn} = require('child_process');
  7 +
  8 +var streamIn = null;
  9 +var ffmpeg = null;
  10 +
  11 +function quit(){
  12 + if(streamIn){
  13 + streamIn.end();
  14 + streamIn = null;
  15 + }
  16 + app.quit();
  17 +}
  18 +
  19 +ipc.on('close-main-window', function () {
  20 + quit();
  21 +});
  22 +
  23 +var lastRenderTime = 0;
  24 +
  25 +ipc.on('to-main-timer', function () {
  26 + if(Date.now() - lastRenderTime >= 10000){
  27 + quit();
  28 + }
  29 +});
2 30
3 var subarg = require('subarg'); 31 var subarg = require('subarg');
4 32
@@ -17,11 +45,43 @@ if (argv.d) { @@ -17,11 +45,43 @@ if (argv.d) {
17 console.log(args); 45 console.log(args);
18 } 46 }
19 47
20 -if(!argv.u){ 48 +if(!argv.u){//url
21 console.log("you must input the web url to record with : -u "); 49 console.log("you must input the web url to record with : -u ");
22 return app.quit(); 50 return app.quit();
23 } 51 }
24 52
  53 +if(!argv.d){//duration
  54 + console.log("you must set the record duration in seconds with : -d ");
  55 + return app.quit();
  56 +}
  57 +
  58 +if(!argv.f){//framerate
  59 + argv.f = "20";
  60 +}
  61 +
  62 +function startFFmpeg(videosize) {
  63 + const args = ['-y','-f', 'rawvideo', '-pix_fmt', 'bgra', '-s' ];
  64 +
  65 + var size = videosize.width + 'x' + videosize.height
  66 +
  67 + args.push(size);
  68 + args.push.apply( args, ['-i', 'pipe:0'] );
  69 + args.push('-c:v');
  70 + args.push('libx264');
  71 + args.push('-b:v');
  72 + args.push('1024k');
  73 + args.push('-r:v');
  74 + args.push(argv.f);
  75 + args.push('-an');
  76 + args.push(argv._[0]);
  77 +
  78 + console.log(args.join` `);
  79 +
  80 + ffmpeg = spawn('ffmpeg', args);
  81 + ffmpeg.stderr.on('data', chunk => console.log(chunk.toString()));
  82 + streamIn = duplexer(ffmpeg.stdin, ffmpeg.stdout);
  83 +}
  84 +
25 app.disableHardwareAcceleration() 85 app.disableHardwareAcceleration()
26 86
27 let win 87 let win
@@ -33,17 +93,34 @@ app.once('ready', () => { @@ -33,17 +93,34 @@ app.once('ready', () => {
33 }) 93 })
34 win.loadURL(argv.u) 94 win.loadURL(argv.u)
35 95
36 - var now = Date.now() 96 +win.webContents.executeJavaScript('const ipcToMain = require("electron").ipcRenderer;function timerToMain (){ ipcToMain.send("to-main-timer");}setInterval(timerToMain,10000);');
  97 +
  98 +
  99 + var start = Date.now()
  100 +
  101 + var duration = parseInt(argv.d)*1000
  102 +
  103 + win.webContents.on("paint", function (event, dirty, image) {
  104 +
  105 + if (!ffmpeg) {
  106 + startFFmpeg(image.getSize());
  107 + }
  108 + lastRenderTime = Date.now();
  109 + var elapsed = lastRenderTime - start
  110 + if (elapsed > duration) {
  111 + if (streamIn) {
  112 + streamIn.end();
  113 + streamIn = null;
  114 + }
  115 + console.log("done")
  116 + win.webContents.executeJavaScript('require("electron").ipcRenderer.send("close-main-window")');
  117 + }
  118 + else {
  119 + streamIn.write(image.getBitmap());
  120 + }
37 121
38 - win.webContents.on("paint", function(event, dirty, image){  
39 - console.log(  
40 - "painting",  
41 - Date.now() - now,  
42 - win.webContents.isOffscreen(),  
43 - win.webContents.getFrameRate()  
44 - ) 122 + //console.log("painting", elapsed, win.webContents.isOffscreen(), win.webContents.getFrameRate())
45 123
46 - now = Date.now()  
47 }) 124 })
48 - win.webContents.setFrameRate(20) 125 + win.webContents.setFrameRate(parseInt(argv.f));
49 }) 126 })
@@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
14 "author": "hubin", 14 "author": "hubin",
15 "license": "MIT", 15 "license": "MIT",
16 "dependencies": { 16 "dependencies": {
  17 + "child_process": "^1.0.2",
  18 + "duplexer3": "^0.1.4",
17 "electron": "^1.6.11", 19 "electron": "^1.6.11",
18 "subarg": "^1.0.0" 20 "subarg": "^1.0.0"
19 }, 21 },