Hatena::ブログ(Diary)

サイト更新停滞ちうっ このページをアンテナに追加 RSSフィード

2017-12-04

[Electron] electron-packagerのignoreオプションが余計なファイルを巻き込みすぎるのを何とかした 04:17  [Electron] electron-packagerのignoreオプションが余計なファイルを巻き込みすぎるのを何とかしたを含むブックマーク  [Electron] electron-packagerのignoreオプションが余計なファイルを巻き込みすぎるのを何とかしたのブックマークコメント

Electronのアプリを作成するelectron-packagerコマンドでは、

ignoreオプションアプリに含めたくないファイルを除外できる。


最初のバージョン

最初はこのような感じでelectron-packagerコマンドを実行していた。

electron-packager . MYukkuriVoice --platform=darwin --arch=x64 --electronVersion=1.7.9 --icon=icns/myukkurivoice.icns \
  --overwrite --asar.unpackDir=vendor \
  --ignore="(\.gitignore|\.gitmodules|bin|docs|icns|test|README.md|vendor/aqk2k_mac|vendor/aqtk1-mac|vendor/aqtk2-mac|vendor/aqtk10-mac)"


でも、これは間違いだった。

ignoreオプションは、Regexpマッチでファイルを拾う。

このコマンド例では、ignoreオプションでbinとかtestとかdocsとかを指定していたので、

ファイルパスの一部にbinやtestやdocsが入っていたら、巻き込まれて作成するアプリから除外されてしまうのだ。

(そして、アプリが動かなくなった…)


どのように直せば良いか

electron-packagerのignoreオプションは複数指定できる。

そして、ignoreオプションのマッチングの仕組みは↓のようになっていて、

file変数にはパッケージのルートからのパス文字列が入っていた。

// node_modules/electron-packager/ignore.js
for (var i = 0; i < ignore.length; i++) {
  if (file.match(ignore[i])) {
    return false
  }
}


よって、次のようにignoreオプションを指定すれば、

余計なファイルを巻き込んで除外せずに済むようになる。

electron-packager . MYukkuriVoice --platform=darwin --arch=x64 --electronVersion=1.7.9 --icon=icns/myukkurivoice.icns \
  --overwrite --asar.unpackDir=vendor \
  --ignore="^/\.gitignore" \
  --ignore="^/\.gitmodules" \
  --ignore="^/bin" \
  --ignore="^/docs" \
  --ignore="^/icns" \
  --ignore="^/test" \
  --ignore="^/README.md" \
  --ignore="^/vendor/aqk2k_mac" \
  --ignore="^/vendor/aqtk1-mac" \
  --ignore="^/vendor/aqtk2-mac" \
  --ignore="^/vendor/aqtk10-mac"


でも、ちょっと待って

よく考えたら、使用しているnode_modulesの中に

テストコードとか、サンプルコードとか、ビルド用のファイルが含まれてる。

それらのファイルはアプリの実行に不要なのだから、除外すべきなのでは?

ドキュメントもasarに固めたら見えないし、要らないよね。


しかし、ignoreオプションで*の指定とかできないらしい(?)。


最終形はこうなりました(^_^;)

electron-packager . MYukkuriVoice --platform=darwin --arch=x64 --electronVersion=1.7.9 --icon=icns/myukkurivoice.icns \
  --overwrite --asar.unpackDir=vendor \
  --ignore="^/MYukkuriVoice-darwin-x64" \
  --ignore="^/README.md" \
  --ignore="^/.git" \
  --ignore="^/.gitignore" \
  --ignore="^/.gitmodules" \
  --ignore="^/bin" \
  --ignore="^/docs" \
  --ignore="^/icns" \
  --ignore="^/test" \
  --ignore="^/vendor/.gitignore" \
  --ignore="^/vendor/aqk2k_mac" \
  --ignore="^/vendor/aqtk1-mac" \
  --ignore="^/vendor/aqtk10-mac" \
  --ignore="^/vendor/aqtk2-mac" \
  --ignore=".DS_Store" \
  --ignore=".babelrc" \
  --ignore=".editorconfig" \
  --ignore=".eslintrc" \
  --ignore=".eslintrc.json" \
  --ignore=".jshintrc" \
  --ignore=".npmignore" \
  --ignore=".npmignore" \
  --ignore=".stylelintrc.json" \
  --ignore=".travis.yml" \
  --ignore="^/node_modules/about-window/LICENSE.txt" \
  --ignore="^/node_modules/about-window/README.md" \
  --ignore="^/node_modules/angular-input-highlight/README.md" \
  --ignore="^/node_modules/angular-input-highlight/test" \
  --ignore="^/node_modules/angular/LICENSE.md" \
  --ignore="^/node_modules/angular/README.md" \
  --ignore="^/node_modules/async/CHANGELOG.md" \
  --ignore="^/node_modules/async/LICENSE" \
  --ignore="^/node_modules/async/README.md" \
  --ignore="^/node_modules/audio-buffer-stream/README.md" \
  --ignore="^/node_modules/audio-buffer-stream/test" \
  --ignore="^/node_modules/balanced-match/LICENSE.md" \
  --ignore="^/node_modules/balanced-match/README.md" \
  --ignore="^/node_modules/bindings/README.md" \
  --ignore="^/node_modules/brace-expansion/README.md" \
  --ignore="^/node_modules/concat-map/LICENSE" \
  --ignore="^/node_modules/concat-map/README.markdown" \
  --ignore="^/node_modules/concat-map/example" \
  --ignore="^/node_modules/concat-map/test" \
  --ignore="^/node_modules/conf/license" \
  --ignore="^/node_modules/conf/readme.md" \
  --ignore="^/node_modules/core-util-is/LICENSE" \
  --ignore="^/node_modules/core-util-is/README.md" \
  --ignore="^/node_modules/core-util-is/test.js" \
  --ignore="^/node_modules/cryptico.js/README.md" \
  --ignore="^/node_modules/cryptico.js/sample" \
  --ignore="^/node_modules/debug/CHANGELOG.md" \
  --ignore="^/node_modules/debug/LICENSE" \
  --ignore="^/node_modules/debug/Makefile" \
  --ignore="^/node_modules/debug/README.md" \
  --ignore="^/node_modules/dot-prop/license" \
  --ignore="^/node_modules/dot-prop/readme.md" \
  --ignore="^/node_modules/electron-config/license" \
  --ignore="^/node_modules/electron-config/readme.md" \
  --ignore="^/node_modules/electron-is-accelerator/LICENSE" \
  --ignore="^/node_modules/electron-is-accelerator/README.md" \
  --ignore="^/node_modules/electron-is-accelerator/test.js" \
  --ignore="^/node_modules/electron-json-storage/CHANGELOG.md" \
  --ignore="^/node_modules/electron-json-storage/README.md" \
  --ignore="^/node_modules/electron-json-storage/doc" \
  --ignore="^/node_modules/electron-json-storage/tests" \
  --ignore="^/node_modules/electron-localshortcut/license" \
  --ignore="^/node_modules/electron-localshortcut/readme.md" \
  --ignore="^/node_modules/electron-log/LICENSE" \
  --ignore="^/node_modules/electron-log/README.md" \
  --ignore="^/node_modules/env-paths/license" \
  --ignore="^/node_modules/env-paths/readme.md" \
  --ignore="^/node_modules/exists-file/CHANGELOG.md" \
  --ignore="^/node_modules/exists-file/LICENSE.md" \
  --ignore="^/node_modules/ffi/CHANGELOG.md" \
  --ignore="^/node_modules/ffi/LICENSE" \
  --ignore="^/node_modules/ffi/README.md" \
  --ignore="^/node_modules/ffi/deps" \
  --ignore="^/node_modules/ffi/example" \
  --ignore="^/node_modules/ffi/src" \
  --ignore="^/node_modules/ffi/test" \
  --ignore="^/node_modules/find-up/license" \
  --ignore="^/node_modules/find-up/readme.md" \
  --ignore="^/node_modules/fs.realpath/LICENSE" \
  --ignore="^/node_modules/fs.realpath/README.md" \
  --ignore="^/node_modules/glob/LICENSE" \
  --ignore="^/node_modules/glob/README.md" \
  --ignore="^/node_modules/glob/changelog.md" \
  --ignore="^/node_modules/inflight/LICENSE" \
  --ignore="^/node_modules/inflight/README.md" \
  --ignore="^/node_modules/inherits/LICENSE" \
  --ignore="^/node_modules/inherits/README.md" \
  --ignore="^/node_modules/intro.js/CODE_OF_CONDUCT.md" \
  --ignore="^/node_modules/intro.js/CONTRIBUTING.md" \
  --ignore="^/node_modules/intro.js/Makefile" \
  --ignore="^/node_modules/intro.js/README.md" \
  --ignore="^/node_modules/intro.js/changelog.md" \
  --ignore="^/node_modules/intro.js/docs" \
  --ignore="^/node_modules/intro.js/example" \
  --ignore="^/node_modules/intro.js/license.md" \
  --ignore="^/node_modules/is-obj/license" \
  --ignore="^/node_modules/is-obj/readme.md" \
  --ignore="^/node_modules/isarray/README.md" \
  --ignore="^/node_modules/lodash/LICENSE" \
  --ignore="^/node_modules/lodash/README.md" \
  --ignore="^/node_modules/minimatch/LICENSE" \
  --ignore="^/node_modules/minimatch/README.md" \
  --ignore="^/node_modules/minimist/LICENSE" \
  --ignore="^/node_modules/minimist/example" \
  --ignore="^/node_modules/minimist/readme.markdown" \
  --ignore="^/node_modules/minimist/test" \
  --ignore="^/node_modules/mkdirp/LICENSE" \
  --ignore="^/node_modules/mkdirp/bin/usage.txt" \
  --ignore="^/node_modules/mkdirp/examples" \
  --ignore="^/node_modules/mkdirp/readme.markdown" \
  --ignore="^/node_modules/mkdirp/test" \
  --ignore="^/node_modules/ms/LICENSE.md" \
  --ignore="^/node_modules/ms/README.md" \
  --ignore="^/node_modules/nan/CHANGELOG.md" \
  --ignore="^/node_modules/nan/LICENSE.md" \
  --ignore="^/node_modules/nan/README.md" \
  --ignore="^/node_modules/nan/doc" \
  --ignore="^/node_modules/nan/nan.h" \
  --ignore="^/node_modules/nan/nan_callbacks.h" \
  --ignore="^/node_modules/nan/nan_callbacks_12_inl.h" \
  --ignore="^/node_modules/nan/nan_callbacks_pre_12_inl.h" \
  --ignore="^/node_modules/nan/nan_converters.h" \
  --ignore="^/node_modules/nan/nan_converters_43_inl.h" \
  --ignore="^/node_modules/nan/nan_converters_pre_43_inl.h" \
  --ignore="^/node_modules/nan/nan_implementation_12_inl.h" \
  --ignore="^/node_modules/nan/nan_implementation_pre_12_inl.h" \
  --ignore="^/node_modules/nan/nan_maybe_43_inl.h" \
  --ignore="^/node_modules/nan/nan_maybe_pre_43_inl.h" \
  --ignore="^/node_modules/nan/nan_new.h" \
  --ignore="^/node_modules/nan/nan_object_wrap.h" \
  --ignore="^/node_modules/nan/nan_persistent_12_inl.h" \
  --ignore="^/node_modules/nan/nan_persistent_pre_12_inl.h" \
  --ignore="^/node_modules/nan/nan_string_bytes.h" \
  --ignore="^/node_modules/nan/nan_typedarray_contents.h" \
  --ignore="^/node_modules/nan/nan_weak.h" \
  --ignore="^/node_modules/nan/tools/README.md" \
  --ignore="^/node_modules/once/LICENSE" \
  --ignore="^/node_modules/once/README.md" \
  --ignore="^/node_modules/os-tmpdir/license" \
  --ignore="^/node_modules/os-tmpdir/readme.md" \
  --ignore="^/node_modules/path-exists/license" \
  --ignore="^/node_modules/path-exists/readme.md" \
  --ignore="^/node_modules/path-is-absolute/license" \
  --ignore="^/node_modules/path-is-absolute/readme.md" \
  --ignore="^/node_modules/photon/CNAME" \
  --ignore="^/node_modules/photon/CONTRIBUTING.md" \
  --ignore="^/node_modules/photon/LICENSE" \
  --ignore="^/node_modules/photon/README.md" \
  --ignore="^/node_modules/photon/docs" \
  --ignore="^/node_modules/photon/sass" \
  --ignore="^/node_modules/pinkie-promise/license" \
  --ignore="^/node_modules/pinkie-promise/readme.md" \
  --ignore="^/node_modules/pinkie/license" \
  --ignore="^/node_modules/pinkie/readme.md" \
  --ignore="^/node_modules/pkg-up/license" \
  --ignore="^/node_modules/pkg-up/readme.md" \
  --ignore="^/node_modules/readable-stream/LICENSE" \
  --ignore="^/node_modules/readable-stream/README.md" \
  --ignore="^/node_modules/ref-struct/History.md" \
  --ignore="^/node_modules/ref-struct/README.md" \
  --ignore="^/node_modules/ref/CHANGELOG.md" \
  --ignore="^/node_modules/ref/README.md" \
  --ignore="^/node_modules/ref/build/Makefile" \
  --ignore="^/node_modules/ref/build/Release/.deps/Release/obj.target/binding/src" \
  --ignore="^/node_modules/ref/build/Release/obj.target/binding/src" \
  --ignore="^/node_modules/ref/build/binding.Makefile" \
  --ignore="^/node_modules/ref/build/binding.target.mk" \
  --ignore="^/node_modules/ref/docs" \
  --ignore="^/node_modules/ref/src" \
  --ignore="^/node_modules/ref/test" \
  --ignore="^/node_modules/rimraf/LICENSE" \
  --ignore="^/node_modules/rimraf/README.md" \
  --ignore="^/node_modules/stream-parser/History.md" \
  --ignore="^/node_modules/stream-parser/LICENSE" \
  --ignore="^/node_modules/stream-parser/README.md" \
  --ignore="^/node_modules/stream-parser/node_modules/debug/.npmignore" \
  --ignore="^/node_modules/stream-parser/node_modules/debug/History.md" \
  --ignore="^/node_modules/stream-parser/node_modules/debug/Makefile" \
  --ignore="^/node_modules/stream-parser/node_modules/debug/Readme.md" \
  --ignore="^/node_modules/stream-parser/node_modules/ms/license.md" \
  --ignore="^/node_modules/stream-parser/node_modules/ms/README.md" \
  --ignore="^/node_modules/stream-parser/test" \
  --ignore="^/node_modules/string_decoder/LICENSE" \
  --ignore="^/node_modules/string_decoder/README.md" \
  --ignore="^/node_modules/temp/LICENSE" \
  --ignore="^/node_modules/temp/README.md" \
  --ignore="^/node_modules/temp/examples" \
  --ignore="^/node_modules/temp/node_modules/rimraf/AUTHORS" \
  --ignore="^/node_modules/temp/node_modules/rimraf/LICENSE" \
  --ignore="^/node_modules/temp/node_modules/rimraf/README.md" \
  --ignore="^/node_modules/temp/node_modules/rimraf/test" \
  --ignore="^/node_modules/temp/test" \
  --ignore="^/node_modules/tunajs/CONTRIBUTE.md" \
  --ignore="^/node_modules/tunajs/README.md" \
  --ignore="^/node_modules/tunajs/tests" \
  --ignore="^/node_modules/wav/History.md" \
  --ignore="^/node_modules/wav/README.md" \
  --ignore="^/node_modules/wav/examples" \
  --ignore="^/node_modules/wav/test" \
  --ignore="^/node_modules/wave-recorder/README.md" \
  --ignore="^/node_modules/wave-recorder/example.js" \
  --ignore="^/node_modules/wrappy/LICENSE" \
  --ignore="^/node_modules/wrappy/README.md" \
  --ignore="^/node_modules/xtend/LICENCE" \
  --ignore="^/node_modules/xtend/Makefile" \
  --ignore="^/node_modules/xtend/README.md" \
  --ignore="^/node_modules/xtend/test.js"


ち・か・ら・お・し!


これ、絶対、保守性悪いわ…

もうやっちゃったから、このまま残すけど…

たいしたアプリサイズの削減にもならないし、皆は、ここまではやらない方が良いぞ(^_^;)

2017-11-21

[Electron][javascript] Electronアプリから、別のアプリへファイルのドラッグアンドドロップによる受け渡しを実現する 03:33  [Electron][javascript] Electronアプリから、別のアプリへファイルのドラッグアンドドロップによる受け渡しを実現するを含むブックマーク  [Electron][javascript] Electronアプリから、別のアプリへファイルのドラッグアンドドロップによる受け渡しを実現するのブックマークコメント

経緯

Electronのアプリで音声ファイルを生成したら、その音声ファイルを直接、動画編集ソフトにドロップしたかった。

これが出来ると、音声録音→動画編集ソフトに突っ込み、の作業をポイポイできるようになる。


ファーストトライ

駄目だったパターン。これ(↓)を参考に、Electronのアプリに組み込んでみた。

Drag out files like Gmail

https://www.thecssninja.com/javascript/gmail-dragout


この方法では、ファインダードラッグアンドドロップする分にはファイルを渡せるのだけれど、

動画編集ソフトにリンクをドロップしようとしても反応してくれなかった。

<html>
<head>
</head>
<body>
<a id="dragout" draggable="true"
    data-downloadurl="application/octet-stream:photo-image.png:file:///Users/taku-o/Desktop/photo-image.png">
    これをドラッグアンドドロップ</a>

<script>
var file = document.getElementById("dragout");

var fileDetails;

if(typeof file.dataset === "undefined") {
  fileDetails = file.getAttribute("data-downloadurl");
} else {
  fileDetails = file.dataset.downloadurl;
}

file.addEventListener("dragstart",function(evt){
  evt.dataTransfer.setData("DownloadURL", fileDetails);
},false);
</script>

</body>
</html>


これで出来たぞ!

Electronのrendererプロセスでdragstartイベントリスナーを設定。

dragstartイベントを補足したら、mainプロセスに通知。

mainプロセス側で処理すれば、動画編集ソフトへの直接ドラッグアンドドロップを実現できた。

// rendererプロセス
.directive('wavDraggable', function($parse) {
  return function(scope, element, attr) {

    scope.$watch('last_wav_file', function(value) {
      var message = value;
      var wav_file_path = message.wav_file_path;

      var el = element[0];
      el.draggable = true;
      el.addEventListener(
        'dragstart',
        function(e) {
          e.preventDefault();
          ipcRenderer.send('ondragstartwav', wav_file_path)
          return false;
        },
        false
      );
    };
  }
})
// mainプロセス
ipcMain.on('ondragstartwav', function (event, filePath) {
  var imgPath = path.join(__dirname, '/img/ic_music_video_black_24dp_1x.png');
  event.sender.startDrag({
    file: filePath,
    icon: imgPath
  })
});

https://raw.githubusercontent.com/taku-o/myukkurivoice/master/docs/images/readme-dnd.gif


まとめ

これは、Electron特有の事情、ということで良いのかな?

nw.jsのissue経由で対応方法を発見した。

ありがとうnw.jsコミュニティ


https://github.com/nwjs/nw.js/issues/5256

https://github.com/nwjs/nw.js/issues/2200

https://github.com/electron/electron/pull/6333



2017-11-15

[AquesTalk][Electron] Macで動作するゆっくり系ボイス再生アプリMYukkuriVoiceでAquesTalk10に対応した 00:42  [AquesTalk][Electron] Macで動作するゆっくり系ボイス再生アプリMYukkuriVoiceでAquesTalk10に対応したを含むブックマーク  [AquesTalk][Electron] Macで動作するゆっくり系ボイス再生アプリMYukkuriVoiceでAquesTalk10に対応したのブックマークコメント

いや、正確には、既に作ってあって、

そのアプリでAquesTalk10(https://www.a-quest.com/products/aquestalk.html)の音声再生・音声録画を使えるようにした。


https://github.com/taku-o/myukkurivoice

D



AquesTalkは、動画などで"ゆっくり"と呼ばれているキャラの声などを出せるライブラリです。

AquesTalk10は、その最新バージョン。

バージョンは上だが、下位のバージョンの機能を全て持っているわけではない。

むしろ、声が違うので、違うライブラリと見た方が自然か。


試しに使ってみたが、AquesTalk10の声は、なんか舌ったらずな感触がある。

自分の調音がイケてないせいだろうか。

少なくとも今までの"ゆっくり"の調音だと不自然感があるかも?

ただ、慣れると気にならなくなる、という話も。



動画で使うようなアプリなので、宣伝には動画が必要になった(断言)


2017-11-10

[node.js][javascript] node ffiで構造体を扱う 00:30  [node.js][javascript] node ffiで構造体を扱うを含むブックマーク  [node.js][javascript] node ffiで構造体を扱うのブックマークコメント

node ffiで構造体を扱うなら、ref-structを使用する

npm install --save ffi
npm install --save ref
npm install --save ref-struct
var StructType = require('ref-struct');

// 型を定義
var AQTK_VOICE = StructType({
  bas: ref.types.int,
  spd: ref.types.int,
  vol: ref.types.int,
  pit: ref.types.int,
  acc: ref.types.int,
  lmd: ref.types.int,
  fsc: ref.types.int
});
// ポインタ
var ptr_AQTK_VOICE = ref.refType(AQTK_VOICE);

// 構造体作る
var aqtk_voice_val = new AQTK_VOICE;
aqtk_voice_val.bas = bas;
aqtk_voice_val.spd = spd;
aqtk_voice_val.vol = vol;
aqtk_voice_val.pit = pit;
aqtk_voice_val.acc = acc;
aqtk_voice_val.lmd = lmd;
aqtk_voice_val.fsc = fsc;
// ポインタ
ptr_aqtk_voice_val = aqtk_voice_val.ref();

あとはこいつを使って、色々やりとりすれば良い。

var ptr_int   = ref.refType(ref.types.int);
var ptr_uchar = ref.refType(ref.types.uchar);

// AquesTalk10
// unsigned char * AquesTalk_Synthe_Utf8(const AQTK_VOICE *pParam, const char *koe, int *size)
var framework_path = 'path/AquesTalk.framework/Versions/A/AquesTalk';
var ptr_AquesTalk10_Synthe_Utf8 = ffi.DynamicLibrary(framework_path).get('AquesTalk_Synthe_Utf8');
var fn_AquesTalk10_Synthe_Utf8  = ffi.ForeignFunction(ptr_AquesTalk10_Synthe_Utf8, ptr_uchar, [ ptr_AQTK_VOICE, 'string', ptr_int ]);

// AquesTalk_Synthe_Utf8の呼び出し
var alloc_int = ref.alloc('int');
var r = fn_AquesTalk10_Synthe_Utf8(ptr_aqtk_voice_val, text, alloc_int);
var buf_wav = ref.reinterpret(r, alloc_int.deref(), 0);

おわり

2017-11-09

Capfile locked at 3.8.1, but 3.7.1 is loaded 09:44  Capfile locked at 3.8.1, but 3.7.1 is loadedを含むブックマーク  Capfile locked at 3.8.1, but 3.7.1 is loadedのブックマークコメント

Capfile locked at 3.8.1, but 3.7.1 is loadedと表示された時の対処。

gem list cap
> *** LOCAL GEMS ***
>
> capistrano (3.7.1)
gem install capistrano -v 3.8.1

[] Finderからzip圧縮したファイルと、コマンドからzip圧縮したファイルでサイズが違う 01:31  Finderからzip圧縮したファイルと、コマンドからzip圧縮したファイルでサイズが違うを含むブックマーク  Finderからzip圧縮したファイルと、コマンドからzip圧縮したファイルでサイズが違うのブックマークコメント

調べると、別のアルゴリズムが使われているらしい。

Finderからzip圧縮したファイルの方がサイズが小さくなる。

試したら倍くらい違う。

で、実際、Finderからの圧縮と同じzipファイルを作るには、

dittoコマンドを使えば良いそう。

ditto -c -k --sequesterRsrc --keepParent release release.zip

dittoはmac独自のコマンドらしい。