[gnome-shell] Expose screencast functionality via DBus
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] Expose screencast functionality via DBus
- Date: Fri, 10 May 2013 17:51:00 +0000 (UTC)
commit 24c530611f4ece4d74da2f8028c350e34ef011ef
Author: Florian Müllner <fmuellner gnome org>
Date: Mon May 6 18:50:31 2013 +0200
Expose screencast functionality via DBus
Like screenshots, the screen recorder can be a useful tool in other cases
than being triggered by a keyboard shortcut. To account for that, export
a Screencast DBus API similar to the existing Screenshot interface.
https://bugzilla.gnome.org/show_bug.cgi?id=696247
data/Makefile.am | 1 +
data/org.gnome.Shell.Screencast.xml | 96 ++++++++++++++++++++++++
js/Makefile.am | 1 +
js/ui/screencast.js | 138 +++++++++++++++++++++++++++++++++++
js/ui/shellDBus.js | 2 +
5 files changed, 238 insertions(+), 0 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index f555d9a..ece7925 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -15,6 +15,7 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \
+ org.gnome.Shell.Screencast.xml \
org.gnome.Shell.Screenshot.xml \
org.gnome.ShellSearchProvider.xml \
org.gnome.ShellSearchProvider2.xml
diff --git a/data/org.gnome.Shell.Screencast.xml b/data/org.gnome.Shell.Screencast.xml
new file mode 100644
index 0000000..6be4010
--- /dev/null
+++ b/data/org.gnome.Shell.Screencast.xml
@@ -0,0 +1,96 @@
+<!DOCTYPE node PUBLIC
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
+<node>
+
+ <!--
+ org.gnome.Shell.Screencast:
+ @short_description: Screencast interface
+
+ The interface used to record screen contents.
+ -->
+ <interface name="org.gnome.Shell.Screencast">
+
+ <!--
+ Screencast:
+ @file_template: the template for the filename to use
+ @options: a dictionary of optional parameters
+ @success: whether the screencast was started successfully
+ @filename_used: the file where the screencast is being saved
+
+ Records a screencast of the whole screen and saves it
+ (by default) as webm video under a filename derived from
+ @file_template. The template is either a relative or absolute
+ filename which may contain some escape sequences - %d and %t
+ will be replaced by the start date and time of the recording.
+ If a relative name is used, the screencast will be saved in the
+ $XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
+ The actual filename of the saved video is returned in @filename_used.
+ The set of optional parameters in @options currently consists of:
+ 'draw-cursor'(b): whether the cursor should be included in the
+ recording (true)
+ 'framerate'(i): the number of frames per second that should be
+ recorded if possible (30)
+ 'pipeline'(s): the GStreamer pipeline used to encode recordings
+ in gst-launch format; if not specified, the
+ recorder will produce vp8 (webm) video (unset)
+ -->
+ <method name="Screencast">
+ <arg type="s" direction="in" name="file_template"/>
+ <arg type="a{sv}" direction="in" name="options"/>
+ <arg type="b" direction="in" name="flash"/>
+ <arg type="b" direction="out" name="success"/>
+ <arg type="s" direction="out" name="filename_used"/>
+ </method>
+
+ <!--
+ ScreencastArea:
+ @x: the X coordinate of the area to capture
+ @y: the Y coordinate of the area to capture
+ @width: the width of the area to capture
+ @height: the height of the area to capture
+ @file_template: the template for the filename to use
+ @options: a dictionary of optional parameters
+ @success: whether the screencast was started successfully
+ @filename_used: the file where the screencast is being saved
+
+ Records a screencast of the passed in area and saves it
+ (by default) as webm video under a filename derived from
+ @file_template. The template is either a relative or absolute
+ filename which may contain some escape sequences - %d and %t
+ will be replaced by the start date and time of the recording.
+ If a relative name is used, the screencast will be saved in the
+ $XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
+ The actual filename of the saved video is returned in @filename_used.
+ The set of optional parameters in @options currently consists of:
+ 'draw-cursor'(b): whether the cursor should be included in the
+ recording (true)
+ 'framerate'(i): the number of frames per second that should be
+ recorded if possible (30)
+ 'pipeline'(s): the GStreamer pipeline used to encode recordings
+ in gst-launch format; if not specified, the
+ recorder will produce vp8 (webm) video (unset)
+ -->
+ <method name="ScreencastArea">
+ <arg type="i" direction="in" name="x"/>
+ <arg type="i" direction="in" name="y"/>
+ <arg type="i" direction="in" name="width"/>
+ <arg type="i" direction="in" name="height"/>
+ <arg type="s" direction="in" name="file_template"/>
+ <arg type="a{sv}" direction="in" name="options"/>
+ <arg type="b" direction="out" name="success"/>
+ <arg type="s" direction="out" name="filename_used"/>
+ </method>
+
+ <!--
+ StopScreencast:
+ @success: whether stopping the recording was successful
+
+ Stop the recording started by either Screencast or ScreencastArea.
+ -->
+ <method name="StopScreencasta">
+ <arg type="b" direction="out" name="success"/>
+ </method>
+
+ </interface>
+</node>
diff --git a/js/Makefile.am b/js/Makefile.am
index 62c8323..e8dd927 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -78,6 +78,7 @@ nobase_dist_js_DATA = \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/runDialog.js \
+ ui/screencast.js \
ui/screenshot.js \
ui/screenShield.js \
ui/scripting.js \
diff --git a/js/ui/screencast.js b/js/ui/screencast.js
new file mode 100644
index 0000000..642d40a
--- /dev/null
+++ b/js/ui/screencast.js
@@ -0,0 +1,138 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Lang = imports.lang;
+const Shell = imports.gi.Shell;
+
+const Hash = imports.misc.hash;
+const Main = imports.ui.main;
+
+const ScreencastIface = <interface name="org.gnome.Shell.Screencast">
+<method name="Screencast">
+ <arg type="s" direction="in" name="file_template"/>
+ <arg type="a{sv}" direction="in" name="options"/>
+ <arg type="b" direction="out" name="success"/>
+ <arg type="s" direction="out" name="filename_used"/>
+</method>
+<method name="ScreencastArea">
+ <arg type="i" direction="in" name="x"/>
+ <arg type="i" direction="in" name="y"/>
+ <arg type="i" direction="in" name="width"/>
+ <arg type="i" direction="in" name="height"/>
+ <arg type="s" direction="in" name="file_template"/>
+ <arg type="a{sv}" direction="in" name="options"/>
+ <arg type="b" direction="out" name="success"/>
+ <arg type="s" direction="out" name="filename_used"/>
+</method>
+<method name="StopScreencast">
+ <arg type="b" direction="out" name="success"/>
+</method>
+</interface>;
+
+const ScreencastService = new Lang.Class({
+ Name: 'ScreencastService',
+
+ _init: function() {
+ this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
+ this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
+
+ Gio.DBus.session.own_name('org.gnome.Shell.Screencast', Gio.BusNameOwnerFlags.REPLACE, null, null);
+
+ this._recorders = new Hash.Map();
+
+ Main.sessionMode.connect('updated',
+ Lang.bind(this, this._sessionModeChanged));
+ },
+
+ _ensureRecorderForSender: function(sender) {
+ let recorder = this._recorders.get(sender);
+ if (!recorder) {
+ recorder = new Shell.Recorder({ stage: global.stage });
+ recorder._watchNameId =
+ Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
+ Lang.bind(this, this._onNameVanished));
+ this._recorders.set(sender, recorder);
+ }
+ return recorder;
+ },
+
+ _sessionModeChanged: function() {
+ if (Main.sessionMode.allowScreencast)
+ return;
+
+ for (let sender in this._recorders.keys())
+ this._recorders.delete(sender);
+ },
+
+ _onNameVanished: function(connection, name) {
+ this._stopRecordingForSender(name);
+ },
+
+ _stopRecordingForSender: function(sender) {
+ let recorder = this._recorders.get(sender);
+ if (!recorder)
+ return false;
+
+ Gio.bus_unwatch_name(recorder._watchNameId);
+ recorder.close();
+ this._recorders.delete(sender);
+
+ return true;
+ },
+
+ _applyOptionalParameters: function(recorder, options) {
+ for (let option in options)
+ options[option] = options[option].deep_unpack();
+
+ if (options['pipeline'])
+ recorder.set_pipeline(options['pipeline']);
+ if (options['framerate'])
+ recorder.set_framerate(options['framerate']);
+ if (options['draw-cursor'])
+ recorder.set_draw_cursor(options['draw-cursor']);
+ },
+
+ ScreencastAsync: function(params, invocation) {
+ let returnValue = [false, ''];
+ if (!Main.sessionMode.allowScreencast)
+ invocation.return_value(GLib.Variant.new('(bs)', returnValue));
+
+ let sender = invocation.get_sender();
+ let recorder = this._ensureRecorderForSender(sender);
+ if (!recorder.is_recording()) {
+ let [fileTemplate, options] = params;
+
+ recorder.set_file_template(fileTemplate);
+ this._applyOptionalParameters(recorder, options);
+ returnValue = recorder.record();
+ }
+
+ invocation.return_value(GLib.Variant.new('(bs)', returnValue));
+ },
+
+ ScreencastAreaAsync: function(params, invocation) {
+ let returnValue = [false, ''];
+ if (!Main.sessionMode.allowScreencast)
+ invocation.return_value(GLib.Variant.new('(bs)', returnValue));
+
+ let sender = invocation.get_sender();
+ let recorder = this._ensureRecorderForSender(sender);
+
+ if (!recorder.is_recording()) {
+ let [x, y, width, height, fileTemplate, options] = params;
+
+ recorder.set_file_template(fileTemplate);
+ recorder.set_area(x, y, width, height);
+ this._applyOptionalParameters(recorder, options);
+ returnValue = recorder.record();
+ }
+
+ invocation.return_value(GLib.Variant.new('(bs)', returnValue));
+ },
+
+ StopScreencastAsync: function(params, invocation) {
+ let success = this._stopRecordingForSender(invocation.get_sender());
+ invocation.return_value(GLib.Variant.new('(b)', [success]));
+ }
+});
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 12e4b84..952613b 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -12,6 +12,7 @@ const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils;
const Hash = imports.misc.hash;
const Main = imports.ui.main;
+const Screencast = imports.ui.screencast;
const Screenshot = imports.ui.screenshot;
const GnomeShellIface = <interface name="org.gnome.Shell">
@@ -70,6 +71,7 @@ const GnomeShell = new Lang.Class({
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
this._extensionsService = new GnomeShellExtensions();
+ this._screencastService = new Screencast.ScreencastService();
this._screenshotService = new Screenshot.ScreenshotService();
this._grabbedAccelerators = new Hash.Map();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]