Esempio n. 1
0
int
main(int argc, char** argv)
{
	const char* command = "list";
	bool verbose = false;

	int c;
	while ((c = getopt_long(argc, argv, "+hv", kLongOptions, NULL)) != -1) {
		switch (c) {
			case 0:
				break;
			case 'h':
				usage(0);
				break;
			case 'v':
				verbose = true;
				break;
			default:
				usage(1);
				break;
		}
	}

	if (argc - optind >= 1)
		command = argv[optind];

	if (strcmp(command, "list") == 0) {
		list_jobs(verbose);
	} else if (strcmp(command, "list-targets") == 0) {
		list_targets(verbose);
	} else if (strcmp(command, "log") == 0) {
		get_log(argc - optind, &argv[optind]);
	} else if (argc == optind + 1) {
		// For convenience (the "info" command can be omitted)
		get_info(command);
	} else {
		// All commands that need a name following

		const char* name = argv[argc - 1];

		if (strcmp(command, "info") == 0) {
			get_info(name);
		} else if (strcmp(command, "start") == 0) {
			start_job(name);
		} else if (strcmp(command, "stop") == 0) {
			stop_job(name);
		} else if (strcmp(command, "restart") == 0) {
			restart_job(name);
		} else if (strcmp(command, "enable") == 0) {
			enable_job(name, true);
		} else if (strcmp(command, "disable") == 0) {
			enable_job(name, false);
		} else {
			fprintf(stderr, "%s: Unknown command \"%s\".\n", kProgramName,
				command);
		}
	}
	return 0;
}
Esempio n. 2
0
/**
 * gstreamill_job_stop:
 * @name: (in): job name to be stoped
 *
 * Returns: plain text.
 */
gchar * gstreamill_job_stop (Gstreamill *gstreamill, gchar *name)
{
        Job *job;

        job = get_job (gstreamill, name);
        if (job != NULL) {
                stop_job (job, SIGTERM);
                return g_strdup_printf ("{\n    \"name\": \"%s\",\n    \"result\": \"success\"\n}", name);

        } else {
                return g_strdup ("{\n    \"result\": \"failure\",\n    \"reason\": \"job not found\"\n}");
        }
}
Esempio n. 3
0
/**
 * gstreamill_job_stop:
 * @name: (in): job name to be stoped
 *
 * Returns: plain text.
 */
gchar * gstreamill_job_stop (Gstreamill *gstreamill, gchar *name)
{
        Job *job;

        job = get_job (gstreamill, name);
        if (job != NULL) {
                stop_job (job, SIGUSR2);
                return g_strdup ("ok");

        } else {
                return g_strdup ("job not found");
        }
}
Esempio n. 4
0
/**
 * gstreamill_stop:
 * @gstreamill: (in): gstreamill to be stop
 *
 * stop gstreamill, stop job first before stop gstreamill.
 *
 * Returns: none
 */
void gstreamill_stop (Gstreamill *gstreamill)
{
        Job *job;
        GSList *list;

        gstreamill->stop = TRUE;
        g_mutex_lock (&(gstreamill->job_list_mutex));
        list = gstreamill->job_list;
        while (list != NULL) {
                job = list->data;
                stop_job (job, SIGUSR2);
                list = list->next;
        }
        g_mutex_unlock (&(gstreamill->job_list_mutex));

        return;
}
Esempio n. 5
0
static void source_check (Gstreamill *gstreamill, Job *job)
{
        gint i;
        GstClockTimeDiff time_diff;
        GstClockTime now;

        /* log source timestamp. */
        for (i = 0; i < job->output->source.stream_count; i++) {
                GST_INFO ("%s.source.%s timestamp %" GST_TIME_FORMAT,
                                job->name,
                                job->output->source.streams[i].name,
                                GST_TIME_ARGS (job->output->source.streams[i].current_timestamp));
        }

        /* non live job, don't check heartbeat */
        if (!job->is_live) {
                return;
        }

        /* source heartbeat check */
        for (i = 0; i < job->output->source.stream_count; i++) {
                /* check video and audio */
                if (!g_str_has_prefix (job->output->source.streams[i].name, "video") &&
                    !g_str_has_prefix (job->output->source.streams[i].name, "audio")) {
                        continue;
                }

                now = gst_clock_get_time (gstreamill->system_clock);
                time_diff = GST_CLOCK_DIFF (job->output->source.streams[i].last_heartbeat, now);
                if ((time_diff > HEARTBEAT_THRESHHOLD) && gstreamill->daemon) {
                        GST_ERROR ("%s.source.%s heart beat error %lu, restart job.",
                                        job->name,
                                        job->output->source.streams[i].name,
                                        time_diff);
                        /* restart job. */
                        stop_job (job, SIGKILL);
                        return;

                } else {
                        GST_INFO ("%s.source.%s heartbeat %" GST_TIME_FORMAT,
                                        job->name,
                                        job->output->source.streams[i].name,
                                        GST_TIME_ARGS (job->output->source.streams[i].last_heartbeat));
                }
        }
}
Esempio n. 6
0
/**
 * gstreamill_stop:
 * @gstreamill: (in): gstreamill to be stop
 *
 * stop gstreamill, stop job first before stop gstreamill.
 *
 * Returns: none
 */
void gstreamill_stop (Gstreamill *gstreamill)
{
        Job *job;
        GSList *list;

        GST_WARNING ("Stop gstreamill ...");
        gstreamill->stop = TRUE;
        g_mutex_lock (&(gstreamill->job_list_mutex));
        list = gstreamill->job_list;
        while (list != NULL) {
                job = list->data;
                if (gstreamill->daemon) {
                        stop_job (job, SIGTERM);

                } else {
                        *(job->output->state) = JOB_STATE_NULL;
                }
                list = list->next;
        }
        g_mutex_unlock (&(gstreamill->job_list_mutex));

        return;
}
Esempio n. 7
0
static void sync_check (Gstreamill *gstreamill, Job *job)
{
        gint j;
        GstClockTimeDiff time_diff;
        GstClockTime min, max;

        min = GST_CLOCK_TIME_NONE;
        max = 0;
        for (j = 0; j < job->output->source.stream_count; j++) {
                if (!g_str_has_prefix (job->output->source.streams[j].name, "video") &&
                    !g_str_has_prefix (job->output->source.streams[j].name, "audio")) {
                        continue;
                }

                if (min > job->output->source.streams[j].current_timestamp) {
                        min = job->output->source.streams[j].current_timestamp;
                }

                if (max < job->output->source.streams[j].current_timestamp) {
                        max = job->output->source.streams[j].current_timestamp;
                }
        }
        time_diff = GST_CLOCK_DIFF (min, max);
        if ((time_diff > SYNC_THRESHHOLD) && gstreamill->daemon){
                GST_ERROR ("%s sync error %lu", job->name, time_diff);
                job->output->source.sync_error_times += 1;
                if (job->output->source.sync_error_times == 3) {
                        GST_ERROR ("sync error times %ld, restart %s", job->output->source.sync_error_times, job->name);
                        /* restart job. */
                        stop_job (job, SIGKILL);
                        return;
                }

        } else {
                job->output->source.sync_error_times = 0;
        }
}
Esempio n. 8
0
static void job_check_func (gpointer data, gpointer user_data)
{
        Job *job = (Job *)data;
        Gstreamill *gstreamill = (Gstreamill *)user_data;

        if (gstreamill->stop) {
                GST_ERROR ("waitting %s stopped", job->name);
                return;
        }

        /* stat report. */
        if (gstreamill->daemon && (job->worker_pid != 0)) {
                job_stat_update (job);
                GST_INFO ("Job %s's average cpu: %d%%, cpu: %d%%, rss: %lu",
                                job->name,
                                job->cpu_average,
                                job->cpu_current,
                                job->memory);
        }

        if (*(job->output->state) != JOB_STATE_PLAYING) {
                return;
        }

        source_check (gstreamill, job);

        encoders_check (gstreamill, job);

        if (job->is_live) {
                sync_check (gstreamill, job);
        }

        /* check non live job eos */
        if (!job->is_live) {
                gint i;
                gboolean eos = TRUE;

                for (i = 0; i < job->output->encoder_count; i++) {
                        if (!(*(job->output->encoders[i].eos))) {
                                eos = FALSE;
                                break;

                        } else {
                                /* add #EXT-X-ENDLIST to playlist if output is m3u8 */
                                gchar *location, *property, *playlist1, *playlist2;

                                property = g_strdup_printf ("encoder.%d.elements.hlssink.property.playlist-location", i);
                                location = jobdesc_element_property_value (job->description, property);
                                g_free (property);
                                if (location != NULL) {
                                        g_file_get_contents (location, &playlist1, NULL, NULL);
                                        playlist2 = g_strdup_printf ("%s#EXT-X-ENDLIST\n",  playlist1);
                                        g_file_set_contents (location, playlist2, strlen(playlist2), NULL);
                                        g_free (playlist1);
                                        g_free (playlist2);
                                        g_free (location);
                                }
                        }
                }

                if (eos) {
                        stop_job (job, SIGTERM);
                        job->eos = TRUE;
                }
        }
}
Esempio n. 9
0
static void encoders_check (Gstreamill *gstreamill, Job *job)
{
        gint j, k;
        GstClockTimeDiff time_diff;
        GstClockTime now;

        /* log encoder current timestamp. */
        for (j = 0; j < job->output->encoder_count; j++) {
                for (k = 0; k < job->output->encoders[j].stream_count; k++) {
                        GST_INFO ("%s.%s timestamp %" GST_TIME_FORMAT,
                                        job->output->encoders[j].name,
                                        job->output->encoders[j].streams[k].name,
                                        GST_TIME_ARGS (job->output->encoders[j].streams[k].current_timestamp));
                }
        }

        /* non live job, don't check heartbeat */
        if (!job->is_live) {
                return;
        }

        /* encoder heartbeat check */
        for (j = 0; j < job->output->encoder_count; j++) {
                for (k = 0; k < job->output->encoders[j].stream_count; k++) {
                        if (!g_str_has_prefix (job->output->encoders[j].streams[k].name, "video") &&
                            !g_str_has_prefix (job->output->encoders[j].streams[k].name, "audio")) {
                                continue;
                        }

                        now = gst_clock_get_time (gstreamill->system_clock);
                        time_diff = GST_CLOCK_DIFF (job->output->encoders[j].streams[k].last_heartbeat, now);
                        if ((time_diff > HEARTBEAT_THRESHHOLD) && gstreamill->daemon) {
                                GST_ERROR ("%s.%s heartbeat error %lu, restart",
                                                job->output->encoders[j].name,
                                                job->output->encoders[j].streams[k].name,
                                                time_diff);
                                /* restart job. */
                                stop_job (job, SIGKILL);
                                return;

                        } else {
                                GST_INFO ("%s.%s heartbeat %" GST_TIME_FORMAT,
                                                job->output->encoders[j].name,
                                                job->output->encoders[j].streams[k].name,
                                                GST_TIME_ARGS (job->output->encoders[j].streams[k].last_heartbeat));
                        }
                }
        }

        /* encoder job->output heartbeat check. */
        for (j = 0; j < job->output->encoder_count; j++) {
                now = gst_clock_get_time (gstreamill->system_clock);
                time_diff = GST_CLOCK_DIFF (*(job->output->encoders[j].heartbeat), now);
                if ((time_diff > ENCODER_OUTPUT_HEARTBEAT_THRESHHOLD) && gstreamill->daemon) {
                        GST_ERROR ("%s job->output heart beat error %lu, restart",
                                        job->output->encoders[j].name,
                                        time_diff);
                        /* restart job. */
                        stop_job (job, SIGKILL);
                        return;

                } else {
                        GST_INFO ("%s job->output heartbeat %" GST_TIME_FORMAT,
                                        job->output->encoders[j].name,
                                        GST_TIME_ARGS (*(job->output->encoders[j].heartbeat)));
                }
        }
}
Esempio n. 10
0
static void
restart_job(const char* name)
{
	stop_job(name);
	start_job(name);
}
Esempio n. 11
0
static gsize request_gstreamill_admin (HTTPMgmt *httpmgmt, RequestData *request_data, gchar **buf)
{
        gchar *path, *http_header, *p;
        gsize buf_size;
        GError *err = NULL;

        path = NULL;
        if (g_strcmp0 (request_data->uri, "/admin/") == 0) {
                path = g_strdup_printf ("%s/gstreamill/admin/index.html", DATADIR);

        } else if (g_str_has_prefix (request_data->uri, "/admin/start")) {
                p = start_job (httpmgmt, request_data);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_str_has_prefix (request_data->uri, "/admin/stop")) {
                p = stop_job (httpmgmt, request_data);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/networkinterfaces") == 0) {
                p = network_interfaces ();
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/setnetworkinterfaces") == 0) {
                p = set_network_interfaces (request_data);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/networkdevices") == 0) {
                p = network_devices ();
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/audiodevices") == 0) {
                p = list_files ("/dev/snd/pcmC*c", NULL);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/videodevices") == 0) {
                p = list_files ("/dev/video*", NULL);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/getconf") == 0) {
                p = get_conf ();
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if ((request_data->method == HTTP_POST) && (g_strcmp0 (request_data->uri, "/admin/putconf") == 0)) {
                p = put_conf (request_data);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/listlivejob") == 0) {
                p = list_files ("/etc/gstreamill.d/*.job", "/etc/gstreamill.d/%[^.].job");
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_strcmp0 (request_data->uri, "/admin/listrunningjob") == 0) {
                p = gstreamill_list_running_job (httpmgmt->gstreamill);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_str_has_prefix (request_data->uri, "/admin/getjob/")) {
                p = get_job (request_data->uri);
                if (p != NULL) {
                        *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                        g_free (p);

                } else {
                        *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
                }

        } else if (g_str_has_prefix (request_data->uri, "/admin/rmjob/")) {
                p = rm_job (request_data->uri);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if ((request_data->method == HTTP_POST) && (g_str_has_prefix (request_data->uri, "/admin/putjob/"))) {
                p = put_job (request_data);
                *buf = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "application/json", strlen (p), NO_CACHE, p);
                g_free (p);

        } else if (g_str_has_prefix (request_data->uri, "/admin/jobmanage.html")) {
                if (g_str_has_prefix (request_data->parameters, "name=")) {
                        path = g_strdup_printf ("%s/gstreamill/admin/jobmanage.html", DATADIR);

                } else {
                        *buf = g_strdup_printf (http_400, PACKAGE_NAME, PACKAGE_VERSION);
                }

        } else {
                /* static content, prepare file path */
                path = g_strdup_printf ("%s/gstreamill%s", DATADIR, request_data->uri);
        }

        if (path == NULL) {
                /* not static content */
                buf_size = strlen (*buf);

        } else if (!g_file_get_contents (path, buf, &buf_size, &err)) {
                GST_ERROR ("read file %s failure: %s", p, err->message);
                *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
                buf_size = strlen (*buf);
                g_error_free (err);

        } else {
                /* jobmanage.html? process name parameter */
                if (g_str_has_suffix (path, "jobmanage.html")) {
                        gchar name[32], *temp_buf;

                        sscanf (request_data->parameters, "name=%s", name);
                        temp_buf = g_strdup_printf (*buf, name);
                        g_free (*buf);
                        *buf = temp_buf;
                }
                /* html file? add top and bottom */
                if (g_str_has_suffix (path, ".html")) {
                        gchar *body;

                        body = *buf;
                        *buf = add_header_footer (body);
                        g_free (body);
                        buf_size = strlen (*buf);
                }
                http_header = gen_http_header (path, buf_size);
                p = g_malloc (buf_size + strlen (http_header));
                memcpy (p, http_header, strlen (http_header));
                memcpy (p + strlen (http_header), *buf, buf_size);
                g_free (*buf);
                *buf = p;
                buf_size += strlen (http_header);
                g_free (http_header);
        }

        if (path != NULL) {
                g_free (path);
        }

        return buf_size;
}