refactor: ginify desktopCapturer (#22746)
This commit is contained in:
parent
9aa27e1709
commit
a824e12275
5 changed files with 54 additions and 28 deletions
|
@ -1,5 +1,3 @@
|
||||||
import { EventEmitter } from 'events'
|
|
||||||
|
|
||||||
const { createDesktopCapturer } = process.electronBinding('desktop_capturer')
|
const { createDesktopCapturer } = process.electronBinding('desktop_capturer')
|
||||||
|
|
||||||
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b)
|
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b)
|
||||||
|
@ -23,21 +21,20 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
|
||||||
|
|
||||||
const stopRunning = () => {
|
const stopRunning = () => {
|
||||||
if (capturer) {
|
if (capturer) {
|
||||||
capturer.emit = null
|
delete capturer._onerror
|
||||||
|
delete capturer._onfinished
|
||||||
capturer = null
|
capturer = null
|
||||||
}
|
}
|
||||||
// Remove from currentlyRunning once we resolve or reject
|
// Remove from currentlyRunning once we resolve or reject
|
||||||
currentlyRunning = currentlyRunning.filter(running => running.options !== options)
|
currentlyRunning = currentlyRunning.filter(running => running.options !== options)
|
||||||
}
|
}
|
||||||
|
|
||||||
const emitter = new EventEmitter()
|
capturer._onerror = (error: string) => {
|
||||||
|
|
||||||
emitter.once('error', (event, error: string) => {
|
|
||||||
stopRunning()
|
stopRunning()
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
}
|
||||||
|
|
||||||
emitter.once('finished', (event, sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => {
|
capturer._onfinished = (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => {
|
||||||
stopRunning()
|
stopRunning()
|
||||||
resolve(sources.map(source => ({
|
resolve(sources.map(source => ({
|
||||||
id: source.id,
|
id: source.id,
|
||||||
|
@ -46,9 +43,8 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
|
||||||
display_id: source.display_id,
|
display_id: source.display_id,
|
||||||
appIcon: (fetchWindowIcons && source.appIcon) ? source.appIcon.toDataURL() : null
|
appIcon: (fetchWindowIcons && source.appIcon) ? source.appIcon.toDataURL() : null
|
||||||
})))
|
})))
|
||||||
})
|
}
|
||||||
|
|
||||||
capturer.emit = emitter.emit.bind(emitter)
|
|
||||||
capturer.startHandling(options.captureWindow, options.captureScreen, options.thumbnailSize, options.fetchWindowIcons)
|
capturer.startHandling(options.captureWindow, options.captureScreen, options.thumbnailSize, options.fetchWindowIcons)
|
||||||
|
|
||||||
// If the WebContents is destroyed before receiving result, just remove the
|
// If the WebContents is destroyed before receiving result, just remove the
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||||
#include "chrome/browser/media/webrtc/window_icon_util.h"
|
#include "chrome/browser/media/webrtc/window_icon_util.h"
|
||||||
#include "content/public/browser/desktop_capture.h"
|
#include "content/public/browser/desktop_capture.h"
|
||||||
|
#include "gin/object_template_builder.h"
|
||||||
#include "shell/common/api/electron_api_native_image.h"
|
#include "shell/common/api/electron_api_native_image.h"
|
||||||
#include "shell/common/gin_converters/gfx_converter.h"
|
#include "shell/common/gin_converters/gfx_converter.h"
|
||||||
#include "shell/common/gin_helper/dictionary.h"
|
#include "shell/common/gin_helper/dictionary.h"
|
||||||
#include "shell/common/gin_helper/object_template_builder.h"
|
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||||
#include "shell/common/node_includes.h"
|
#include "shell/common/node_includes.h"
|
||||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||||
|
@ -59,9 +60,9 @@ namespace electron {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
gin::WrapperInfo DesktopCapturer::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||||
Init(isolate);
|
|
||||||
}
|
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {}
|
||||||
|
|
||||||
DesktopCapturer::~DesktopCapturer() = default;
|
DesktopCapturer::~DesktopCapturer() = default;
|
||||||
|
|
||||||
|
@ -154,7 +155,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||||
// |media_list_sources|.
|
// |media_list_sources|.
|
||||||
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||||
&device_names)) {
|
&device_names)) {
|
||||||
Emit("error", "Failed to get sources.");
|
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +185,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!capture_window_ && !capture_screen_)
|
if (!capture_window_ && !capture_screen_)
|
||||||
Emit("finished", captured_sources_, fetch_window_icons_);
|
gin_helper::CallMethod(this, "_onfinished", captured_sources_,
|
||||||
|
fetch_window_icons_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -192,15 +194,16 @@ gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||||
return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
|
return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
gin::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
|
||||||
void DesktopCapturer::BuildPrototype(
|
v8::Isolate* isolate) {
|
||||||
v8::Isolate* isolate,
|
return gin::Wrappable<DesktopCapturer>::GetObjectTemplateBuilder(isolate)
|
||||||
v8::Local<v8::FunctionTemplate> prototype) {
|
|
||||||
prototype->SetClassName(gin::StringToV8(isolate, "DesktopCapturer"));
|
|
||||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
|
||||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DesktopCapturer::GetTypeName() {
|
||||||
|
return "DesktopCapturer";
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace api
|
} // namespace api
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
|
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
|
||||||
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
|
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
|
||||||
#include "gin/handle.h"
|
#include "gin/handle.h"
|
||||||
#include "shell/common/gin_helper/trackable_object.h"
|
#include "gin/wrappable.h"
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
class DesktopCapturer : public gin_helper::TrackableObject<DesktopCapturer>,
|
class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
|
||||||
public DesktopMediaListObserver {
|
public DesktopMediaListObserver {
|
||||||
public:
|
public:
|
||||||
struct Source {
|
struct Source {
|
||||||
|
@ -32,14 +32,17 @@ class DesktopCapturer : public gin_helper::TrackableObject<DesktopCapturer>,
|
||||||
|
|
||||||
static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
static void BuildPrototype(v8::Isolate* isolate,
|
|
||||||
v8::Local<v8::FunctionTemplate> prototype);
|
|
||||||
|
|
||||||
void StartHandling(bool capture_window,
|
void StartHandling(bool capture_window,
|
||||||
bool capture_screen,
|
bool capture_screen,
|
||||||
const gfx::Size& thumbnail_size,
|
const gfx::Size& thumbnail_size,
|
||||||
bool fetch_window_icons);
|
bool fetch_window_icons);
|
||||||
|
|
||||||
|
// gin::Wrappable
|
||||||
|
static gin::WrapperInfo kWrapperInfo;
|
||||||
|
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||||
|
v8::Isolate* isolate) override;
|
||||||
|
const char* GetTypeName() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||||
~DesktopCapturer() override;
|
~DesktopCapturer() override;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gin/converter.h"
|
#include "gin/converter.h"
|
||||||
|
#include "gin/wrappable.h"
|
||||||
|
|
||||||
namespace gin_helper {
|
namespace gin_helper {
|
||||||
|
|
||||||
|
@ -63,6 +64,28 @@ v8::Local<v8::Value> CustomEmit(v8::Isolate* isolate,
|
||||||
&converted_args);
|
&converted_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
v8::Local<v8::Value> CallMethod(v8::Isolate* isolate,
|
||||||
|
gin::Wrappable<T>* object,
|
||||||
|
const char* method_name,
|
||||||
|
Args&&... args) {
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
v8::Local<v8::Object> v8_object;
|
||||||
|
if (object->GetWrapper(isolate).ToLocal(&v8_object))
|
||||||
|
return CustomEmit(isolate, v8_object, method_name,
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
else
|
||||||
|
return v8::Local<v8::Value>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
v8::Local<v8::Value> CallMethod(gin::Wrappable<T>* object,
|
||||||
|
const char* method_name,
|
||||||
|
Args&&... args) {
|
||||||
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
|
return CallMethod(isolate, object, method_name, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gin_helper
|
} // namespace gin_helper
|
||||||
|
|
||||||
#endif // SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_CALLER_H_
|
#endif // SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_CALLER_H_
|
||||||
|
|
3
typings/internal-electron.d.ts
vendored
3
typings/internal-electron.d.ts
vendored
|
@ -94,7 +94,8 @@ declare namespace ElectronInternal {
|
||||||
|
|
||||||
interface DesktopCapturer {
|
interface DesktopCapturer {
|
||||||
startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean): void;
|
startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean): void;
|
||||||
emit: typeof NodeJS.EventEmitter.prototype.emit | null;
|
_onerror: (error: string) => void;
|
||||||
|
_onfinished: (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetSourcesOptions {
|
interface GetSourcesOptions {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue