DVD イメージの main-feature タイトルを チャプター毎の動画ファイルに切り出す方法

下記の2つのソースを用意して、

```
node run.js -i "hoge.iso" -o "/path/to/"
```

と実行すれば、/path/to に動画ファイルが出力される。

HandbrakeCLI( https://handbrake.fr/downloads2.php ) は予めインストールしておくこと。 

## package.json

```json
{
  "name": "dvd2mp4",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "command-line-args": "^3.0.0",
    "moment": "^2.13.0",
    "async": "^2.0.0-rc.5",
    "q": "^1.4.1",
    "qlimit": "^0.1.1",
    "sleep": "^3.0.1",
    "lodash": "^4.13.1",
    "here": "^0.0.2",
    "argparse": "^1.0.7",
    "uuid": "^2.0.2",
    "sleep-async": "^1.0.1"
  }
}
```

## run.js

```js
var ArgumentParser = require('argparse').ArgumentParser;
const commandLineArgs = require('command-line-args')
const execSync = require('child_process').execSync;
const exec = require('child_process').exec;
const spawnSync = require('child_process').spawnSync;
var fs = require('fs');
var path = require('path');
var uuid = require('uuid');

var moment = require('moment');
var Q = require('q');
var _ = require('lodash');
var here = require('here').here;
var qlimit = require('qlimit');
var asleep = require('sleep-async')();
var limit = qlimit(2);

var resdict = {};

const optionDefinitions = [
  { name: 'input', alias: 'i', type: String},
  { name: 'output', alias: 'o', type: String}
]

const options = commandLineArgs(optionDefinitions)
console.log(options);

var inputpath = options["input"];
var outputdir = options["output"];
var title_id = 0;
var max_cell_id = 0;

Q.when(1).
then(function(){
    var d = Q.defer();
    var output_file = "./temp/output_" + uuid.v4() + ".log";
    var command = "HandBrakeCLI -i '" + inputpath + "' -t 0 --main-feature &> " + output_file;
    console.log(command);

    console.log("=== before execSync =======");
    var ret = "";
    try{
       ret = execSync(command, {stdio: ['pipe', 'pipe', 'pipe']});
    } catch( error ){
    }
    console.log("=== after execSync =======");

    var rs = fs.createReadStream(output_file);
    var readline = require('readline');

    var rl = readline.createInterface(rs, {});

    var result_dics = {};
    rl.on('line', function(line) {
        var matches = line.match(/^(\s*)\+(.*)$/);
        if(_.size(matches) > 0){
            var body = matches[2];
            var matches_title_id = body.match(/^\s*title (.*):$/);
            var matches_cells = body.match(/^\s*(\d*): cells.*$/);
            console.log(body);
            console.log(matches_title_id);
            console.log(matches_cells);
            if(_.size(matches_title_id) > 0){
                title_id = matches_title_id[1];
            }
            if(_.size(matches_cells) > 0){
                var now_cell_id = _.toNumber(matches_cells[1]);
                if(now_cell_id > max_cell_id){
                    max_cell_id = now_cell_id;
                }
            }
        }
    });
    rl.on('close', function(line){
        console.log("title_id:" + title_id);
        console.log("max_cell_id:" + max_cell_id);
        d.resolve();
    });
    return d.promise;
}).then(function(){
    var d = Q.defer();
    var path_dict = path.parse(inputpath);

    var mp4name_base = path_dict["name"];
    var commands = [];
    for(var i = 1; i <= max_cell_id; i++){
        var padding_i = ( '0'  + i ).slice( -2 );
        var mp4name = outputdir + "/" + mp4name_base + "_" + padding_i + ".mp4";
        command = "HandBrakeCLI -i '" + inputpath + "' -o '" + mp4name + "' -t " + title_id + " -c " + i + " -a 1 -s 1 -e x264 -b 4000 -r 29.97 -q 20.0 -X 960";
        console.log(command);
        commands.push(command);
    }
    console.log("===============");
    console.log("title_id:" + title_id);
    console.log("max_cell_id:" + max_cell_id);

    Q.all(commands.map(limit(function(command) {
        var _d = Q.defer();
        console.log(command);
        try{
            exec(command, (error, stdout, stderr) => {
              _d.resolve();
            });
        } catch( error ){
             console.log(error);
        }
        return _d.promise;
    })));
    return d.promise;
}).then(function(){
}).catch(function(error){
    console.log(error);
}).done(function(){
    console.log("done");
});
```