Refine more about desktop capturer API.

* Simplify the coffeescript code.
* Add more options in desktopCapturer.startUpdating.
This commit is contained in:
Haojian Wu 2015-10-05 11:32:12 +08:00
parent 1e69ef79de
commit 36c0ad7fda
8 changed files with 104 additions and 84 deletions

View file

@ -14,30 +14,13 @@
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
namespace mate {
template<>
struct Converter<DesktopMediaList::Source> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const DesktopMediaList::Source& source) {
mate::Dictionary dict(isolate, v8::Object::New(isolate));
content::DesktopMediaID id = source.id;
dict.Set("name", base::UTF16ToUTF8(source.name));
dict.Set("id", id.ToString());
dict.Set(
"thumbnail",
atom::api::NativeImage::Create(isolate, gfx::Image(source.thumbnail)));
return ConvertToV8(isolate, dict);
}
};
} // namespace mate
namespace atom {
namespace api {
namespace {
// Refresh every second.
const int kUpdatePeriod = 1000;
const int kThumbnailWidth = 150;
const int kThumbnailHeight = 150;
} // namespace
@ -48,7 +31,11 @@ DesktopCapturer::DesktopCapturer() {
DesktopCapturer::~DesktopCapturer() {
}
void DesktopCapturer::StartUpdating(const std::vector<std::string>& sources) {
void DesktopCapturer::StartUpdating(const mate::Dictionary& args) {
std::vector<std::string> sources;
if (!args.Get("types", &sources))
return;
bool show_screens = false;
bool show_windows = false;
for (const auto& source_type : sources) {
@ -80,7 +67,16 @@ void DesktopCapturer::StartUpdating(const std::vector<std::string>& sources) {
show_windows ? webrtc::WindowCapturer::Create(options) : nullptr);
media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(),
window_capturer.Pass()));
media_list_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight));
int update_period = kUpdatePeriod;
int thumbnail_width = kThumbnailWidth, thumbnail_height = kThumbnailHeight;
args.Get("updatePeriod", &update_period);
args.Get("thumbnailWidth", &thumbnail_width);
args.Get("thumbnailHeight", &thumbnail_height);
media_list_->SetUpdatePeriod(base::TimeDelta::FromMilliseconds(
update_period));
media_list_->SetThumbnailSize(gfx::Size(thumbnail_width, thumbnail_height));
media_list_->StartUpdating(this);
}
@ -89,22 +85,40 @@ void DesktopCapturer::StopUpdating() {
}
void DesktopCapturer::OnSourceAdded(int index) {
Emit("source-added", media_list_->GetSource(index));
EmitDesktopCapturerEvent("source-added", index, false);
}
void DesktopCapturer::OnSourceRemoved(int index) {
Emit("source-removed", media_list_->GetSource(index));
EmitDesktopCapturerEvent("source-removed", index, false);
}
// Ignore this event.
void DesktopCapturer::OnSourceMoved(int old_index, int new_index) {
}
void DesktopCapturer::OnSourceNameChanged(int index) {
Emit("source-name-changed", media_list_->GetSource(index));
EmitDesktopCapturerEvent("source-removed", index, false);
}
void DesktopCapturer::OnSourceThumbnailChanged(int index) {
Emit("source-thumbnail-changed", media_list_->GetSource(index));
EmitDesktopCapturerEvent("source-thumbnail-changed", index, true);
}
void DesktopCapturer::OnRefreshFinished() {
Emit("refresh-finished");
}
void DesktopCapturer::EmitDesktopCapturerEvent(
const std::string& event_name, int index, bool with_thumbnail) {
const DesktopMediaList::Source& source = media_list_->GetSource(index);
content::DesktopMediaID id = source.id;
if (!with_thumbnail)
Emit(event_name, id.ToString(), base::UTF16ToUTF8(source.name));
else {
Emit(event_name, id.ToString(), base::UTF16ToUTF8(source.name),
atom::api::NativeImage::Create(isolate(),
gfx::Image(source.thumbnail)));
}
}
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(

View file

@ -14,6 +14,10 @@
#include "chrome/browser/media/native_desktop_media_list.h"
#include "native_mate/handle.h"
namespace mate {
class Dictionary;
}
namespace atom {
namespace api {
@ -23,7 +27,8 @@ class DesktopCapturer: public mate::EventEmitter,
public:
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
void StartUpdating(const std::vector<std::string>& sources);
void StartUpdating(const mate::Dictionary& args);
void StopUpdating();
protected:
@ -36,8 +41,11 @@ class DesktopCapturer: public mate::EventEmitter,
void OnSourceMoved(int old_index, int new_index) override;
void OnSourceNameChanged(int index) override;
void OnSourceThumbnailChanged(int index) override;
void OnRefreshFinished() override;
private:
void EmitDesktopCapturerEvent(
const std::string& event_name, int index, bool with_thumbnail);
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;

View file

@ -1,10 +1,8 @@
ipc = require 'ipc'
BrowserWindow = require 'browser-window'
EventEmitter = require('events').EventEmitter
# The browser module manages all desktop-capturer moduels in renderer process.
desktopCapturer = process.atomBinding('desktop_capturer').desktopCapturer
desktopCapturer.__proto__ = EventEmitter.prototype
getWebContentsFromId = (id) ->
windows = BrowserWindow.getAllWindows()
@ -15,28 +13,26 @@ webContentsIds = new Set
stopDesktopCapture = (id) ->
webContentsIds.delete id
# Stop updating if no renderer process listens the desktop capturer.
if webContentsIds.size is 0
desktopCapturer.stopUpdating()
ipc.on 'ATOM_BROWSER_DESKTOP_CAPTURER_REQUIRED', (event) ->
id = event.sender.getId()
# Remove the tracked webContents when it is destroyed.
getWebContentsFromId(id).on 'destroyed', ()->
stopDesktopCapture id
event.returnValue = 'done'
# Handle `desktopCapturer.startUpdating` API.
ipc.on 'ATOM_BROWSER_DESKTOP_CAPTURER_START_UPDATING', (event, args) ->
id = event.sender.getId()
if not webContentsIds.has id
# Stop sending desktop capturer events to the destroyed webContents.
event.sender.on 'destroyed', ()->
stopDesktopCapture id
# Start updating the desktopCapturer if it doesn't.
if webContentsIds.size is 0
desktopCapturer.startUpdating args
webContentsIds.add id
desktopCapturer.startUpdating args
# Handle `desktopCapturer.stopUpdating` API.
ipc.on 'ATOM_BROWSER_DESKTOP_CAPTURER_STOP_UPDATING', (event) ->
stopDesktopCapture event.sender.getId()
for event_name in ['source-added', 'source-removed', 'source-name-changed', "source-thumbnail-changed"]
do (event_name) ->
desktopCapturer.on event_name, (event, source) ->
webContentsIds.forEach (id) ->
getWebContentsFromId(id).send event_name, { id: source.id, name: source.name, dataUrl: source.thumbnail.toDataUrl() }
desktopCapturer.emit = (event_name, event, desktopId, name, thumbnail) ->
webContentsIds.forEach (id) ->
getWebContentsFromId(id).send 'ATOM_RENDERER_DESKTOP_CAPTURER', event_name, desktopId, name, thumbnail?.toDataUrl()