はじめに
Gifzoでデスクトップを動画でキャプチャーすることに興味を覚えて、あれこれ調べていたら、Chromeで WebRTC関連のAPIでデスクトップキャプチャーできることを思い出して、ちょっとやってみました。
Chormeでデスクトップキャプチャー
制約事項
- about://flagsでの設定が必要
- httpsでアクセスしているページでしかキャプチャー機能は使えない
方針
これらの制約の為、Atom Shell使う意味が益々でてきました。
1. Atom Shellでのデスクトップキャプチャーは諦める
ちょっと試したが、そもそも、オレオレhttpsにAtom Shellのレンダープロセスは上手くアクセスできない模様。
そこで、Chromeを外部プロセスとして起動して、これと連携する。
2. Atom Shell内でkoaをhttpsで動かし、動画ファイルを保存する。
ChromeではHTML5のFile APIは使えるものの、物理ファイルは保存できないので、 Atom Shellで動かしたkoaにファイルアップロードすることで、物理ファイルを作成する。
Atom Shellでkoaを動かすには
素のv0.11系でも--harmonyオプションが必要。
Atom Shellでnode.jsを--harmonyオプション付きで動かすには
Atom Shellでkoaをhttpsで動かすには
オレオレ証明書を作る
オレオレ証明書のkey.pem、cert.pemの2ファイルを用意する。
自分は昔書いたブログ記事を参考したw。
Windowsだとハマるかも
オレオレ証明書の作成をWindowsでやったら、BOM付で作られ、そのままだとエラーで怒られたので、BOMなしにして、ついでに改行コードもLFに変換したら動いた。
koaをhttpsで動かす
var https = require('https'); var options = { key: fs.readFileSync(__dirname +"/key.pem"), cert: fs.readFileSync(__dirname +"/cert.pem") }; https.createServer(options, app.callback()).listen(4430);
Atom ShellからChromeを起動する
- オレオレ証明書の警告を無効化
- デスクトップキャプチャー機能の有効化
が可能となる。
OS毎にChromeの起動を対応
Atom ShellでOSを判定するには
process.platformを使ってみた。
- win32
- darwin
Chromeをオプションを付けて起動する
var chromeRuntimes = {
win32:process.env.LOCALAPPDATA+"\\Google\\Chrome\\Application\\chrome.exe",
darwin:"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
linux:""//頑張ってください
};
var chromeRuntime=chromeRuntimes[process.platform];
var spawn = require('child_process').spawn;
spawn(chromeRuntime,
[
"--app=https://localhost:4430/webrtc.html", // シンプルなウィンドウでURLを開く
"--enable-usermedia-screen-capturing", // デスクトップキャプチャー機能を有効
"--ignore-certificate-errors", // オレオレ証明書の警告を無効
"--window-size='320,240'", // キャプチャーボタンに必要な小さ目のサイズを指定
'--user-data-dir=' + __dirname+"/chromeStuff" //
]);
注意点
Chomeがすでに起動済みの場合、コマンドライン引数が有効にならない模様
キャプチャー画像を動画にする
デスクトップキャプチャーはAPIで出来るが、保存するAPIは用意されておらず、自前で実装する必要がある。
RecordRTC.jsを使わせてもらった
今回はRecordRTC.jsを使わせてもらった。
キャプチャー開始
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'screen',
minWidth: 1280,
maxWidth: 2560,
minHeight: 720,
maxHeight: 1440
}
}
}, function (stream) {
localStream = stream;
window.recordRTC = RecordRTC(localStream, {
type: "video",
video: {
width: 640,
height: 480
},
canvas: {
width: 640,
height: 480
}
});
recordRTC.startRecording();
}, function (error) {});
キャプチャー終了
recordRTC.stopRecording();
動画を物理ファイルに保存
Chrome側のWebアプリからkoaにファイルをアップロードすることで実現する。
var blob = recordRTC.getBlob(); var req = new XMLHttpRequest(); req.open("POST", "https://localhost:4430/", true); req.onreadystatechange = function () { //readyState値は4で受信完了 if (req.readyState == 4) { //コールバック //on_loaded(http); console.log("responseText" + req.responseText); var out = document.getElementById("out"); out.innerHTML = "File Uploaded.!"; } }; var formData = new FormData(); formData.enctype = "multipart/form-data"; formData.append("theFile", blob, "capture.webm"); req.send(formData);
まとめ
Atom Shellで利用しているlibchromiumcontentがデスクトップキャプチャーに対応したら Atom Shellで完結できるのですが、デスクトップキャプチャーがChromeの機能拡張での実装に 一本化されそうな未来なので、期待薄です。
ChromeブラウザからのAtom ShellへのデータはWebSocket使った方が今風だったかも。
今回の作業を通して、
- Atom Shellで内部のnode.jsの力を引き出す方法
- koaをhttpsで動かす事
- koaでのファイルアップロード
- Chromeのコマンドラインオプション
- Chromeのabout://flagsによるデスクトップキャプチャーは廃止予定
等幅広く学ぶことが出来ました。
Link
- 今回の成果物(https://github.com/kjunichi/asDeskCap)
- node-chromeを一日いじくり回してわかったこと Chromeをnode.jsで起動する際に大いに参考になった。
関連記事
- デスクトップキャプチャーをChromeの機能拡張で実現
- gyazo-node-webkitを動かしてみた #OSX
- Atom Shellいじってたが、apmはビルドしないと行けなかった件 #windows