Electron呼び出し元モジュール-スクリーンショットスキーム最適化
8901 ワード
スクリーンショット機能は,最初はelectronが提供するAPI:desktopCaptureを自然に用いた.しかし、実際には、このAPIはスクリーンショットに特化しているわけではなく、最終的な実現効果もあまりよくありません.ここではdesktopCapturerベースのスクリーンショットスキームと、macとwindows専用に設計された最適化スキームについて説明します.
構想 BrowserWindowを新規作成します. ウィンドウのロードが完了すると、desktopCapturerを呼び出して現在のデスクトップスクリーンのフレームを取得するとともに、現在のウィンドウサイズをフルスクリーン に変更する.ウィンドウに2つのcanvasを描画し、1つはマスク、1つは裁断領域 を表示する.
次のdesktopCapturerの使用を添付します.
macの最適化スキームは簡単で、macが持参したコマンド
screencaptureはmacが持参したスクリーンショットコマンドで、
Windowsのスクリーンショットのスキームは、Windows自体がmacのようなスクリーンショットコマンドを提供していないため、長い間検討されてきた.調査研究によると、ネット上でwindowsのスクリーンショットに対して主にいくつかの方法があることが分かった. Nircmdコマンドラインツール(http://www.nirsoft.net/utils/nircmd.html)、サードパーティのwindowsコマンドラインツール、 に保存します. Nodejsライブラリ:screenshot-desktop,node-desktop-screenshot,このようなNodejsライブラリは少なくありませんが、実際の実現原理はそれほど悪くなく、execを通じて自身が含むbatまたはcmdツールを呼び出します.また、指定した領域を切り取るには、フルスクリーンショットまたはパラメータを転送するしかありません. は、Electronプロジェクトでネイティブモジュールを呼び出す.研究したElectron成熟製品の多くは,eagle,bearychatなどのこの方法を採用している.この方法は3つに細分化することもできます. nativeコードコンパイルを呼び出す.Nodeファイル node-ffi、edge-atom-shellなどのモジュールを介してnodejsにC++コード呼び出しdll を直接書く.は、コマンドラインにより実行する.exeファイルdll を呼び出す
3つのシナリオでは、前の2つは簡単なフルスクリーンショットであり、裁断、編集などの機能は提供できません.次に、第3のスキームの具体的な実装を分析する.
これはプロジェクトが現在採用しているスキームで、nodejsでは
exeとdllファイルを
問題はdllの一部が適用されない点で、修正が必要で、これはdllファイルの反コンパイルと再コンパイルの問題に関連していますが、私はすでに大学の先生に完全に返して、環境とコンパイルツールさえ一時的に思い出せなくて、長い間振り回されていました.その後、コンパイルされたDLLファイルの変更方法を参照します.
キーツール:
逆コンパイルツールILSpy
WindowsにはILコンパイルツールilasmとildasmが付属しています.https://docs.microsoft.com/en-us/dotnet/framework/tools/ilasm-exe-il-assembler
手順: dllファイルをILSpyにドラッグし、C++ソースコードを表示し、修正が必要な部分を見つけます. ildasmツールを使用してdllを開き、ILファイルにダンプします. は大体IL文法を熟知して、ソースコードを比較して、修正を行います; ilasmコマンドを実行し、ILをdllに再コンパイルします.
Electronはプラットフォーム間PC開発の枠組みとして、多くのオリジナルAPIを提供していますが、需要が異なり、多くの場合、Cベースの下位業務を実現する必要があります.Electronはnodejsがオリジナルモジュールを呼び出すソリューションを提供します:Nodeオリジナルモジュールを使用
DeadlineとC++に対する弱い鶏を考慮すると、この案はほとんど考慮されていない.しかし、既存のプロジェクトのaddonモジュールも発見され、
エラーログは明確ですscreenshot.Nodeコンパイルで使用されるelectronバージョンは、現在のプロジェクトと一致しません.53はelectron 1.6に対応する.xバージョン、54は1.7に対応する.xバージョン、具体的な対応関係は表示できますhttps://github.com/lgeiger/electron-abi
electronの更新ログは1.6に言及されているからです.xバージョンにセキュリティ・ホールがあれば、ダウングレードして解決しようとしません.また、大きなバージョンを変更すると、プロジェクト内の他のオリジナルモジュールもrebuildを必要とします.
Windowsのスクリーンショットを実現できるNodeオリジナルモジュールが見つからないため,node-ffiとedge-atom-shellというNodeオリジナルモジュールを研究し,両者ともnodejsとCの通信を実現できる.
もちろん、installの前に、install後のffiモジュールが現在の環境で使用できるように、後node-gypの環境を構成する必要があります.
e.g
画像管理アプリケーションeagleではedge-atom-shellが大量に運用されています.
最終的にはexeを使用してdllを実行するスキームが使用されるが、exeの開閉にも一定の遅延が必要であるため、スクリーンショット機能の応答が速くない.
ソリューションを探している間、他にも良いオープンソースプロジェクトがありましたが、どのように利用するかは考えられませんでした.
screenshot、微信スクリーンショットdllを利用したC#とpythonツール
参考:electronはNodeを使用する.js原生モジュール
DesktopCapturer
構想
次のdesktopCapturerの使用を添付します.
onCapture: function() {
const self = this;
const desktopCapturer = Electron.desktopCapturer;
const display = Electron.screen.getPrimaryDisplay();
const size = display.size;
desktopCapturer.getSources({types: ['screen']}, function(error, sources) {
if (error) throw error;
const sourceId = sources[0].id;
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sourceId,
minWidth: size.width,
maxWidth: size.width,
minHeight: size.height,
maxHeight: size.height,
},
},
}, function(stream) {
const video = ReactDOM.findDOMNode(self.refs.captureVideo);
const canvas = ReactDOM.findDOMNode(self.refs.captureCanvas);
const context = canvas.getContext('2d');
video.addEventListener('play', function() {
video.pause();
canvas.setAttribute('width', size.width);
canvas.setAttribute('height', size.height);
context.drawImage(video, 0, 0, size.width, size.height);
self.executeAction(windowAction.windowResize, {
window: cfg.GLB.CAPTURE_WINDOW,
width: size.width,
height: size.height + 85,
onTop: true,
fullscreen: true,
});
});
video.addEventListener('canplay', function() {
video.play();
});
video.setAttribute('src', URL.createObjectURL(stream));
/*
setTimeout(function() {
video.play()
}, 500);*/
}, function(e) {
console.error('getUserMediaError');
});
});
},
Macスクリーンショット
macの最適化スキームは簡単で、macが持参したコマンド
screencapture -i
を使用します.screencaptureはmacが持参したスクリーンショットコマンドで、
-i
と-w
の2つのモードがあり、それぞれ自由スクリーンショットとウィンドウスクリーンショットである.screencapture -i filePath
保存するパスを指定screencapture -i -x filePath
、スクリーンショット完了後のプロンプト音を閉じますWindowsスクリーンショット
Windowsのスクリーンショットのスキームは、Windows自体がmacのようなスクリーンショットコマンドを提供していないため、長い間検討されてきた.調査研究によると、ネット上でwindowsのスクリーンショットに対して主にいくつかの方法があることが分かった.
nircmd.exe savescreenshot "f:\temp\shot.png"
は現在のデスクトップを指定ファイル3つのシナリオでは、前の2つは簡単なフルスクリーンショットであり、裁断、編集などの機能は提供できません.次に、第3のスキームの具体的な実装を分析する.
exeでdllを呼び出す
これはプロジェクトが現在採用しているスキームで、nodejsでは
child_process
のexecFileメソッドでexeファイルを実行し、exeは同級ディレクトリの下のdllを呼び出し、スクリーンショットツールを呼び出す.const libPath = path.join(__dirname, 'capture.exe').replace('app.asar', 'app.asar.unpacked');
clipboard.clear();
const exec = require('child_process').execFile;
exec(libPath, (err, stdout, stderr) => {
if (err) log.error('capture error', err);
log.info('capture finished', clipboard.readImage().isEmpty());
const image = clipboard.readImage();
if (!image.isEmpty()) {
// UI
}
})
},
exeとdllファイルを
app.asar.unpacked
ディレクトリにパッケージし、絶対パスで実行します.exeとdllはネットで探したもので、呼び出しは複雑ではありません.問題はdllの一部が適用されない点で、修正が必要で、これはdllファイルの反コンパイルと再コンパイルの問題に関連していますが、私はすでに大学の先生に完全に返して、環境とコンパイルツールさえ一時的に思い出せなくて、長い間振り回されていました.その後、コンパイルされたDLLファイルの変更方法を参照します.
キーツール:
逆コンパイルツールILSpy
WindowsにはILコンパイルツールilasmとildasmが付属しています.https://docs.microsoft.com/en-us/dotnet/framework/tools/ilasm-exe-il-assembler
手順:
パッケージングaddon
Electronはプラットフォーム間PC開発の枠組みとして、多くのオリジナルAPIを提供していますが、需要が異なり、多くの場合、Cベースの下位業務を実現する必要があります.Electronはnodejsがオリジナルモジュールを呼び出すソリューションを提供します:Nodeオリジナルモジュールを使用
node-gyp
の環境を構成する後、c++コードをnode呼び出し用のインタフェースに露出しbidingを修正する.gyp.現在のelectron環境を生成するaddonモジュールをコンパイルする、すなわち.nodeファイル.node-gyp rebuild --runtime=electron --target_arch=ia32 --target=1.7.11 --disturl=https://atom.io/download/atom-shell
DeadlineとC++に対する弱い鶏を考慮すると、この案はほとんど考慮されていない.しかし、既存のプロジェクトのaddonモジュールも発見され、
screenshot.node
を直接呼び出してみました.パッケージが実行された後、エラーを報告しました.'xxx/screenshot.node' was compiled against a different Node.js version using
NODE_MODULE_VERSION 53. This version of Node.js requires
NODE_MODULE_VERSION 54. Please try re-compiling or re-installing
...
エラーログは明確ですscreenshot.Nodeコンパイルで使用されるelectronバージョンは、現在のプロジェクトと一致しません.53はelectron 1.6に対応する.xバージョン、54は1.7に対応する.xバージョン、具体的な対応関係は表示できますhttps://github.com/lgeiger/electron-abi
electronの更新ログは1.6に言及されているからです.xバージョンにセキュリティ・ホールがあれば、ダウングレードして解決しようとしません.また、大きなバージョンを変更すると、プロジェクト内の他のオリジナルモジュールもrebuildを必要とします.
Nodejs呼び出しdll
Windowsのスクリーンショットを実現できるNodeオリジナルモジュールが見つからないため,node-ffiとedge-atom-shellというNodeオリジナルモジュールを研究し,両者ともnodejsとCの通信を実現できる.
もちろん、installの前に、install後のffiモジュールが現在の環境で使用できるように、後node-gypの環境を構成する必要があります.
e.g
画像管理アプリケーションeagleではedge-atom-shellが大量に運用されています.
edge = require('edge-atom-shell');
NiuNiuCaptureInit = edge.func(function () {
/*#r "mscorlib.dll"
using System.Threading.Tasks;
using System;
using System.Text;
using System.Runtime.InteropServices;
public class Startup
{
public delegate void Callback();
public Callback callbackInstance;
[DllImport("NiuniuCapturex64.dll", EntryPoint = "StartScreenCapture")]
static extern IntPtr StartScreenCapture(StringBuilder fileName, Callback callback);
[DllImport("NiuniuCapturex64.dll", EntryPoint = "InitScreenCapture")]
static extern IntPtr InitScreenCapture(string auth);
public async Task
その他
最終的にはexeを使用してdllを実行するスキームが使用されるが、exeの開閉にも一定の遅延が必要であるため、スクリーンショット機能の応答が速くない.
ソリューションを探している間、他にも良いオープンソースプロジェクトがありましたが、どのように利用するかは考えられませんでした.
screenshot、微信スクリーンショットdllを利用したC#とpythonツール
参考:electronはNodeを使用する.js原生モジュール