diff --git a/data/gnome-shell.schemas b/data/gnome-shell.schemas index 6da8e3231..462a62e95 100644 --- a/data/gnome-shell.schemas +++ b/data/gnome-shell.schemas @@ -117,6 +117,53 @@ + + /schemas/desktop/gnome/shell/recorder/framerate + /desktop/gnome/shell/recorder/framerate + gnome-shell + int + 15 + + Framerate used for recording screencasts. + + The framerate of the resulting screencast recordered by GNOME Shell's screencast recorder in frames-per-second. + + + + + + /schemas/desktop/gnome/shell/recorder/pipeline + /desktop/gnome/shell/recorder/pipeline + gnome-shell + string + + + The gstreamer pipeline used to encode the screencast + + Sets the GStreamer pipeline used to encode recordings. It follows the syntax used for gst-launch. + The pipeline should have an unconnected sink pad where the recorded video is recorded. It will + normally have a unconnected source pad; output from that pad will be written into the output file. + However the pipeline can also take care of its own output - this might be used to send the output to an icecast server via shout2send or similar. + When unset or set to an empty value, the default pipeline will be used. This is currently 'videorate ! theoraenc ! oggmux' and records to Ogg Theora. + + + + + + /schemas/desktop/gnome/shell/recorder/file_extension + /desktop/gnome/shell/recorder/file_extension + gnome-shell + string + ogg + + File extension used for storing the screencast + + The filename for recorded screencasts will be a unique filename based on the current date, and use this extension. + It should be changed when recording to a different container format. + + + + diff --git a/js/ui/main.js b/js/ui/main.js index 4a7fe32c3..47c7548f9 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -134,6 +134,16 @@ function start() { if (recorder.is_recording()) { recorder.pause(); } else { + //read the parameters from GConf always in case they have changed + let gconf = Shell.GConf.get_default(); + recorder.set_framerate(gconf.get_int("recorder/framerate")); + recorder.set_filename("shell-%d%u-%c." + gconf.get_string("recorder/file_extension")); + let pipeline = gconf.get_string("recorder/pipeline"); + if (!pipeline.match(/^\s*$/)) + recorder.set_pipeline(pipeline); + else + recorder.set_pipeline(null); + recorder.record(); } }); diff --git a/src/shell-recorder.c b/src/shell-recorder.c index 1a31b4dbd..224799231 100644 --- a/src/shell-recorder.c +++ b/src/shell-recorder.c @@ -63,6 +63,7 @@ struct _ShellRecorder { gboolean have_pack_invert; /* True when GL_MESA_pack_invert is available */ + int framerate; char *pipeline_description; char *filename; gboolean filename_has_count; /* %c used: handle pausing differently */ @@ -93,6 +94,8 @@ struct _RecorderPipeline static void recorder_set_stage (ShellRecorder *recorder, ClutterStage *stage); +static void recorder_set_framerate (ShellRecorder *recorder, + int framerate); static void recorder_set_pipeline (ShellRecorder *recorder, const char *pipeline); static void recorder_set_filename (ShellRecorder *recorder, @@ -104,6 +107,7 @@ static void recorder_pipeline_closed (RecorderPipeline *pipeline); enum { PROP_0, PROP_STAGE, + PROP_FRAMERATE, PROP_PIPELINE, PROP_FILENAME }; @@ -117,7 +121,7 @@ G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT); * as theora for a minimal size increase. This may be an artifact of the * encoding process. */ -#define FRAMES_PER_SECOND 15 +#define DEFAULT_FRAMES_PER_SECOND 15 /* The time (in milliseconds) between querying the server for the cursor * position. @@ -246,6 +250,7 @@ shell_recorder_init (ShellRecorder *recorder) recorder->memory_target = get_memory_target(); recorder->state = RECORDER_STATE_CLOSED; + recorder->framerate = DEFAULT_FRAMES_PER_SECOND; } static void @@ -873,6 +878,21 @@ recorder_set_stage (ShellRecorder *recorder, } } +static void +recorder_set_framerate (ShellRecorder *recorder, + int framerate) +{ + if (framerate == recorder->framerate) + return; + + if (recorder->current_pipeline) + shell_recorder_close (recorder); + + recorder->framerate = framerate; + + g_object_notify (G_OBJECT (recorder), "framerate"); +} + static void recorder_set_pipeline (ShellRecorder *recorder, const char *pipeline) @@ -924,6 +944,9 @@ shell_recorder_set_property (GObject *object, case PROP_STAGE: recorder_set_stage (recorder, g_value_get_object (value)); break; + case PROP_FRAMERATE: + recorder_set_framerate (recorder, g_value_get_int (value)); + break; case PROP_PIPELINE: recorder_set_pipeline (recorder, g_value_get_string (value)); break; @@ -949,6 +972,9 @@ shell_recorder_get_property (GObject *object, case PROP_STAGE: g_value_set_object (value, G_OBJECT (recorder->stage)); break; + case PROP_FRAMERATE: + g_value_set_int (value, recorder->framerate); + break; case PROP_PIPELINE: g_value_set_string (value, recorder->pipeline_description); break; @@ -977,6 +1003,17 @@ shell_recorder_class_init (ShellRecorderClass *klass) "Stage to record", CLUTTER_TYPE_STAGE, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, + PROP_FRAMERATE, + g_param_spec_int ("framerate", + "Framerate", + "Framerate used for resulting video in frames-per-second", + 0, + G_MAXINT, + DEFAULT_FRAMES_PER_SECOND, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_PIPELINE, g_param_spec_string ("pipeline", @@ -1018,7 +1055,7 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline) "blue_mask", G_TYPE_INT, 0x0000ff, #endif "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "framerate", GST_TYPE_FRACTION, FRAMES_PER_SECOND, 1, + "framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1, "width", G_TYPE_INT, pipeline->recorder->stage_width, "height", G_TYPE_INT, pipeline->recorder->stage_height, NULL); @@ -1523,6 +1560,24 @@ shell_recorder_new (ClutterStage *stage) NULL); } +/** + * shell_recorder_set_framerate: + * @recorder: the #ShellRecorder + * @framerate: Framerate used for resulting video in frames-per-second. + * + * Sets the number of frames per second we configure for the GStreamer pipeline. + * + * The default value is 15. + */ +void +shell_recorder_set_framerate (ShellRecorder *recorder, + int framerate) +{ + g_return_if_fail (SHELL_IS_RECORDER (recorder)); + + recorder_set_framerate (recorder, framerate); +} + /** * shell_recorder_set_filename: * @recorder: the #ShellRecorder diff --git a/src/shell-recorder.h b/src/shell-recorder.h index 26b76ec04..fe96c5b5b 100644 --- a/src/shell-recorder.h +++ b/src/shell-recorder.h @@ -30,6 +30,8 @@ GType shell_recorder_get_type (void) G_GNUC_CONST; ShellRecorder *shell_recorder_new (ClutterStage *stage); +void shell_recorder_set_framerate (ShellRecorder *recorder, + int framerate); void shell_recorder_set_filename (ShellRecorder *recorder, const char *filename); void shell_recorder_set_pipeline (ShellRecorder *recorder,