-1

I am in way over my head here. I am normally a coldfusion/javascript/jquery developer but now have taken on a task that assumes I know more than I do.

I am trying to write an application in electron that will allow me to select a group of video files and convert them to mp4 files while also compressing them. The files are football plays and a normal game consists of about 160 plays and 18gb. We need to compress these down to about 4gb. I have used programs like Prism to do this, but the intended users are not technically savvy nor do they all have windows - some have Macs.

I have an electron project that I have started and got the first part to work. I can start the app and select the input files. But I have tried all kinds of different solutions found online to call ffmpeg and pass it the parms to convert a file. Is there an easy way to call ffmpeg with parms and then wait for it to finish before continuing?

I am on Windows 10 but will also need to run on Apple OS. Please, if you have a simple example of how to do this, I would appreciate it.

Thanks! Dave

Raider Dave
  • 1
  • 1
  • 1
  • Welcome to Stack Overflow, it is always beneficial to you and readers of your post years later, to post some code of what you have tried thus far. For some guidance, you can look at these guidelines: https://stackoverflow.com/help/how-to-ask – Daniel Nov 11 '18 at 12:36

1 Answers1

1

First you'll need to figure out how to bundle ffmpeg with your app. Here's a thread I started on that front for an OSX app. To bundle for Windows distribution you need to follow a different procedure:

  1. Open your electron base folder (electron-quick-start is the default name), then go into the node_modules folder. Create a folder there called ffmpeg, and copy your static binary into this directory. Note: it must be the static version, grab the latest Windows build here.
  2. Within your node_modules folder, navigate to the .bin subfolder. You need to create a couple of text files here to tell node to include the binary exe file you just copied. Use your favorite text editor and create two files, one named ffmpeg with the following contents:

    #!/bin/sh
    basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
    
    case `uname` in
        *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
    esac
    
    if [ -x "$basedir/node" ]; then
      "$basedir/node"  "$basedir/../ffmpeg/ffmpeg" "$@"
      ret=$?
    else
      node  "$basedir/../ffmpeg/ffmpeg" "$@"
      ret=$?
    fi
    exit $ret
    

    And the the second text file, named ffmpeg.cmd:

    @IF EXIST "%~dp0\node.exe" (
     "%~dp0\node.exe"  "%~dp0\..\ffmpeg\ffmpeg" %*
    ) ELSE (
       @SETLOCAL
     @SET PATHEXT=%PATHEXT:;.JS;=;%
     node  "%~dp0\..\ffmpeg\ffmpeg" %*
    )
    

Next you can run ffmpeg in your Windows electron distribution (in renderer.js) as follows (I'm using the app-root-dir node module as well):

var appRootDir = require('app-root-dir').get();
var ffmpegpath = appRootDir + '\\node_modules\\ffmpeg\\ffmpeg';

//filelist[] has already been populated
const
    spawn = require( 'child_process' ).spawnSync;
    for (var i = 0; i < filelist.length; i++) { 
         var outfile = filelist[i] + '.mp4';
         var ffmpeg = spawn( 'cmd.exe', ['/c',  '"'+ffmpegpath+ '"', '-i', filelist[i], '-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-y', outfile]));
         //add whatever switches you need here, test command line first
         ffmpeg.stdout.on( 'data', data => {
             console.log( `stdout: ${data}` );
         });
         ffmpeg.stderr.on( 'data', data => {
             console.log( `stderr: ${data}` );
         });
      }
Community
  • 1
  • 1
UltrasoundJelly
  • 1,845
  • 2
  • 18
  • 32
  • I did see your thread on bundling it, but the commands didn't work on Windows. the "cp" and "ln" were rejected. Are they for a different OS? -Thanks! – Raider Dave Apr 24 '17 at 21:34
  • Note that I'm using `spawnSync` here instead of `spawn`, effectively making this code blocking / synchronous. You won't be able to update the UI until this entire loop completes. If you want to set up some sort of UI progress bar then you'll need to use the asynchronous `spawn` command with a promise queue. – UltrasoundJelly Apr 27 '17 at 01:11