--- /dev/null
+#include <unistd.h>
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_Input.h>
+#include <streamrecorder.h>
+#include "e_info_client_screen_recorder.h"
+
+int _log_dom = -1;
+
+#define CRT(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
+
+typedef struct
+{
+ char filename[PATH_MAX];
+ int framerate;
+ struct
+ {
+ int w, h;
+ } resolution;
+} Screen_Recorder_Args;
+
+streamrecorder_h _stream_recorder;
+
+static Eina_Bool _screen_recorder_efl_init(void);
+static void _screen_recorder_efl_shutdown(void);
+static Eina_Bool _screen_recorder_parse_args(int argc, char **argv, Screen_Recorder_Args *args);
+static Eina_Bool _stream_recorder_run(const char *filename, int framerate, int w, int h);
+
+static void
+_usage(void)
+{
+ fprintf(stderr, SCREEN_RECORDER_USAGE);
+}
+
+static Eina_Bool
+_screen_recorder_cb_handle_stdin(void *data, Ecore_Fd_Handler *handler EINA_UNUSED)
+{
+ Screen_Recorder_Args *args = data;
+ char c;
+ int ret;
+
+ ret = scanf("%c", &c);
+ if (ret < 1)
+ return ECORE_CALLBACK_RENEW;
+
+ streamrecorder_commit(_stream_recorder);
+ streamrecorder_destroy(_stream_recorder);
+ _stream_recorder = NULL;
+
+ fprintf(stdout, "Finish recording screen: %s\n", args->filename);
+
+ ecore_main_loop_quit();
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+int
+e_info_client_screen_recorder_run(int argc, char **argv)
+{
+ Screen_Recorder_Args args =
+ { {0, }, /* filename */
+ 60, /* framerate */
+ {360, 360} /* widthxheight resolution */
+ };
+ Eina_Bool res;
+ char *val;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(_screen_recorder_efl_init(), -1);
+
+ val = getenv("XDG_RUNTIME_DIR");
+ if (!val)
+ {
+ WRN("Not found \"XDG_RUNTIME_DIR\", Set \"/run\" on its value "
+ "for run screen recording anyway.");
+ setenv("XDG_RUNTIME_DIR", "/run", 1);
+ }
+
+ res = _screen_recorder_parse_args(argc, argv, &args);
+ if (!res)
+ {
+ _usage();
+ goto end;
+ }
+
+ res = _stream_recorder_run(args.filename,
+ args.framerate,
+ args.resolution.w,
+ args.resolution.h);
+ if (!res)
+ {
+ ERR("Could not initialize the streamrecorder");
+ goto end;
+ }
+
+ fprintf(stdout, "Press any key to finish recording");
+ fflush(stdout);
+
+ ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ,
+ _screen_recorder_cb_handle_stdin,
+ &args, NULL, NULL);
+
+ ecore_main_loop_begin();
+
+end:
+ _screen_recorder_efl_shutdown();
+
+ return (res == EINA_TRUE) ? 0 : -1;
+}
+
+static Eina_Bool
+_screen_recorder_efl_init(void)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_init(), EINA_FALSE);
+
+ _log_dom = eina_log_domain_register("screen_recorder", NULL);
+ if (_log_dom < 0)
+ {
+ EINA_LOG_CRIT("Could not create logging domain '%s'.", "screen_recorder");
+ goto fail_log_dom;
+ }
+
+ EINA_SAFETY_ON_FALSE_GOTO(ecore_init(), fail_ecore);
+
+ DBG("Done efl init");
+
+ return EINA_TRUE;
+
+fail_ecore:
+ eina_log_domain_unregister(_log_dom);
+ _log_dom = -1;
+fail_log_dom:
+ eina_shutdown();
+
+ return EINA_FALSE;
+}
+
+static void
+_screen_recorder_efl_shutdown(void)
+{
+ ecore_shutdown();
+ eina_log_domain_unregister(_log_dom);
+ _log_dom = -1;
+ eina_shutdown();
+}
+
+static Eina_Bool
+_screen_recorder_fullpath_make_with_ext(char *out, const char *filename)
+{
+ char cwd[PATH_MAX], fname_with_ext[PATH_MAX] = {0,};
+ char *dot;
+ const char *ext = ".mp4";
+ const char *prefix = "e-screen-record";
+ int len;
+
+ if (filename)
+ {
+ dot = strrchr(filename, '.');
+ if ((!dot) || (strlen(dot + 1) !=3) || (strncmp(dot, ext, strlen(ext)) != 0))
+ {
+ /* concatenate file extention. */
+ len = strnlen(filename, PATH_MAX - 4);
+ strncat(fname_with_ext, filename, len);
+ strncat(fname_with_ext, ext, 4);
+ }
+ else
+ {
+ strncat(fname_with_ext, filename, (PATH_MAX - 1));
+ fname_with_ext[PATH_MAX - 1] = '\0';
+ }
+
+ if (fname_with_ext[0] != '/')
+ {
+ /* concatenate current working directory or '/tmp'. */
+ if (!getcwd(cwd, sizeof(cwd)))
+ snprintf(cwd, sizeof(cwd), "/tmp");
+ snprintf(out, PATH_MAX, "%s/%s", cwd, fname_with_ext);
+ }
+ else
+ strncpy(out, fname_with_ext, PATH_MAX);
+ }
+ else
+ {
+ time_t timer;
+ struct tm *t, buf;
+
+ timer = time(NULL);
+ t = localtime_r(&timer, &buf);
+ if (!t)
+ return EINA_FALSE;
+
+ if (!getcwd(cwd, sizeof(cwd)))
+ snprintf(cwd, sizeof(cwd), "/tmp");
+
+ snprintf(out, PATH_MAX, "%s/%s-%04d%02d%02d.%02d%02d%02d%s",
+ cwd, prefix,
+ t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour,
+ t->tm_min, t->tm_sec,
+ ext);
+ out[PATH_MAX - 1] = '\0';
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_screen_recorder_parse_args(int argc, char **argv, Screen_Recorder_Args *args)
+{
+ char *filename = NULL;
+ int i;
+ Eina_Bool res;
+
+ DBG("Begin Parse Arguments");
+
+ for (i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-dump_video") == 0)
+ continue;
+ else if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0))
+ return EINA_FALSE;
+ else if (sscanf(argv[i], "--rate=%d", &args->framerate) == 1)
+ {
+ if (args->framerate < 1)
+ {
+ fprintf(stderr, "ERROR: invalid framerate, "
+ "it should be greater than 0: %d\n",
+ args->framerate);
+ return EINA_FALSE;
+ }
+ }
+ else if (sscanf(argv[i], "--resolution=%dx%d", &args->resolution.w, &args->resolution.h) == 2)
+ {
+ if ((args->resolution.w < 1) || (args->resolution.h < 1))
+ {
+ fprintf(stderr, "ERROR: invalid resolution, "
+ "resolution value should be greater than 0: %dx%d\n",
+ args->resolution.w, args->resolution.h);
+ return EINA_FALSE;
+ }
+ }
+ else if ((strcmp(argv[i], "--") == 0) || (argv[i][0] == '-'))
+ {
+ fprintf(stderr, "ERROR: unkown parameter, %s\n", argv[i]);
+ return EINA_FALSE;
+ }
+ else if (i == (argc - 1))
+ filename = argv[i];
+ }
+
+ res = _screen_recorder_fullpath_make_with_ext(args->filename, filename);
+ if (!res)
+ {
+ ERR("invalid file path: %s", args->filename);
+ return EINA_FALSE;
+ }
+
+ DBG("Done Parse Arguments");
+ INF("Arguments: framerate(%d) resolution(%dx%d) filename(%s)",
+ args->framerate, args->resolution.w, args->resolution.h, args->filename);
+
+ return EINA_TRUE;
+}
+
+static void
+_cb_stream_recorder_status(unsigned long long elapsed_time, unsigned long long file_size, void *user_data)
+{
+ DBG("Recording Status: time(%.5f s) size(%lld KB)",
+ (double)elapsed_time / (double)1000, file_size);
+}
+
+static Eina_Bool
+_stream_recorder_run(const char *filename, int framerate, int w, int h)
+{
+ streamrecorder_state_e state;
+ int err;
+
+ DBG("Begin Initializing Streamrecorder");
+
+ err = streamrecorder_create(&_stream_recorder);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to create streamrecorder: %d", err);
+ return EINA_FALSE;
+ }
+
+ err = streamrecorder_get_state(_stream_recorder, &state);
+ if (err == STREAMRECORDER_ERROR_NONE)
+ {
+ if (state == STREAMRECORDER_STATE_CREATED)
+ INF("StreamRecorder State: 'Created'");
+ else
+ INF("StreamRecorder State: %d", state);
+ }
+
+ err = streamrecorder_set_video_resolution(_stream_recorder, w, h);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to set video resolution: %dx%d", w, h);
+ goto fail;
+ }
+
+ err = streamrecorder_set_video_framerate(_stream_recorder, framerate);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to set video framerate: %d", 30);
+ goto fail;
+ }
+
+ err = streamrecorder_set_filename(_stream_recorder, filename);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to set filename for streamrecorder: %s", filename);
+ goto fail;
+ }
+
+ err = streamrecorder_set_mode(_stream_recorder,
+ STREAMRECORDER_MODE_DEVICE_LOOPBACK);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to set mode of streamrecorder: %d", err);
+ goto fail;
+ }
+
+ err = streamrecorder_set_recording_status_cb(_stream_recorder,
+ _cb_stream_recorder_status,
+ NULL);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to set callback for recording status");
+ goto fail;
+ }
+
+ err = streamrecorder_prepare(_stream_recorder);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to prepare streamrecorder: %d", err);
+ goto fail;
+ }
+
+ err = streamrecorder_start(_stream_recorder);
+ if (err != STREAMRECORDER_ERROR_NONE)
+ {
+ ERR("failed to start streamrecorder");
+ goto fail;
+ }
+
+ DBG("Done Initializing Streamrecorder");
+
+ return EINA_TRUE;
+fail:
+ streamrecorder_destroy(_stream_recorder);
+ _stream_recorder = NULL;
+
+ return EINA_FALSE;
+}