| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /* GStreamer
- * Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
- #include <gst/gst.h>
- #include <gst/rtsp-server/rtsp-onvif-server.h>
- #include <string.h>
- #include <stdio.h>
- #include "iniparser/iniparser.h"
- #define CONF "/oem/etc/config.xml"
- #define SPK_CONF "/etc/speaker.conf"
- #define MAX_LINE_LENGTH 256
- struct SPEAKER_CONF
- {
- char hw_version[16];
- char dev_type[32];
- char enable_mic[8];
- char media_stream[8];
- };
- void find_tag_in_file(const char* file_path, const char* tag, char *value);
- void confParse(struct SPEAKER_CONF *conf);
- void confParse(struct SPEAKER_CONF *conf)
- {
- dictionary * ini ;
- ini = iniparser_load(SPK_CONF);
-
- if (ini==NULL) {
- fprintf(stderr, "cannot parse file: %s\n", SPK_CONF);
- exit(-1);
- }
- strcpy(conf->dev_type, iniparser_getstring(ini, "system:ui_model", ""));
- strcpy(conf->hw_version, iniparser_getstring(ini, "system:hard_version", ""));
- strcpy(conf->enable_mic, iniparser_getstring(ini, "onvif:enable_mic", "no"));
- strcpy(conf->media_stream, iniparser_getstring(ini, "onvif:media_stream", "main"));
-
- iniparser_freedict(ini);
- }
- static gchar *htdigest_path = NULL;
- static gchar *realm = NULL;
- static GOptionEntry entries[] = {
- {"htdigest-path", 'h', 0, G_OPTION_ARG_STRING, &htdigest_path,
- "Path to an htdigest file to parse (default: None)", "PATH"},
- {"realm", 'r', 0, G_OPTION_ARG_STRING, &realm,
- "Authentication realm (default: None)", "REALM"},
- {NULL}
- };
- int
- main (int argc, char *argv[])
- {
- GMainLoop *loop;
- GstRTSPServer *server;
- GstRTSPMountPoints *mounts;
- GstRTSPMediaFactory *factory;
- GstRTSPAuth *auth;
- GstRTSPToken *token;
- GOptionContext *optctx;
- GError *error = NULL;
- struct SPEAKER_CONF conf;
- confParse(&conf);;
- char launchstr[512];
- char username[64] = { 0 };
- char password[64] = { 0 };
- find_tag_in_file(CONF, "auth_user", username);
- find_tag_in_file(CONF, "auth_pass", password);
- if (strlen(username) == 0 || strlen(password) == 0) {
- g_print ("Please username or password in config.xml\n");
- return -1;
- }
- // putenv("GST_DEBUG=4");
- gst_init (&argc, &argv);
- optctx = g_option_context_new (NULL);
- g_option_context_add_main_entries (optctx, entries, NULL);
- g_option_context_add_group (optctx, gst_init_get_option_group ());
- if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
- g_printerr ("Error parsing options: %s\n", error->message);
- g_option_context_free (optctx);
- g_clear_error (&error);
- return -1;
- }
- g_option_context_free (optctx);
- loop = g_main_loop_new (NULL, FALSE);
- /* create a server instance */
- server = gst_rtsp_onvif_server_new ();
- /* get the mount points for this server, every server has a default object
- * that be used to map uri mount points to media factories */
- mounts = gst_rtsp_server_get_mount_points (server);
- /* make a media factory for a test stream. The default media factory can use
- * gst-launch syntax to create pipelines.
- * any launch line works as long as it contains elements named pay%d. Each
- * element with pay%d names will be a stream */
- factory = gst_rtsp_onvif_media_factory_new ();
- //! video/x-raw, format=(string)RGB, width=(int)640, height=(int)480
-
- strcpy(launchstr, "( filesrc loop=true location=\"/usr/share/onvif/speaker.h264\" ! video/x-h264 ! h264parse ! rtph264pay pt=96 config-interval=5 name=pay0 ");
- if(strcmp(conf.enable_mic, "yes") == 0)
- {
- strcat(launchstr, "alsasrc device=plug:mixmic ! queue ! audioconvert ! audioresample ! mulawenc ! rtppcmupay name=pay1 )");
- }
- else
- {
- strcat(launchstr, " )");
- }
- gst_rtsp_media_factory_set_launch (factory,launchstr);
-
- gst_rtsp_onvif_media_factory_set_backchannel_launch
- (GST_RTSP_ONVIF_MEDIA_FACTORY (factory),
- "( capsfilter caps=\"application/x-rtp, media=audio, payload=0, clock-rate=8000, encoding-name=PCMU, channels=1\" name=depay_backchannel ! rtppcmudepay ! mulawdec ! audioconvert ! audio/x-raw,channels=2 ! audioresample ! alsasink async=false sync=false )");
- //"( capsfilter caps=\"application/x-rtp, media=audio, payload=8, clock-rate=8000, encoding-name=PCMA, channels=1\" name=depay_backchannel ! rtpjitterbuffer latency=80 ! rtppcmadepay ! alawdec ! identity drop-probability=0.01 sync=true ! audioconvert ! audioresample ! alsasink async=false sync=false )");
- gst_rtsp_media_factory_set_shared (factory, FALSE);
- gst_rtsp_media_factory_set_media_gtype (factory, GST_TYPE_RTSP_ONVIF_MEDIA);
- /* attach the test factory to the /test url */
- gst_rtsp_mount_points_add_factory (mounts, "/MainStream", factory);
- /* allow admin to access this resource */
- gst_rtsp_media_factory_add_role (factory, username,
- GST_RTSP_PERM_MEDIA_FACTORY_ACCESS, G_TYPE_BOOLEAN, TRUE,
- GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT, G_TYPE_BOOLEAN, TRUE, NULL);
- /* don't need the ref to the mapper anymore */
- g_object_unref (mounts);
- /* make a new authentication manager */
- auth = gst_rtsp_auth_new ();
- gst_rtsp_auth_set_supported_methods (auth, GST_RTSP_AUTH_DIGEST);
- if (realm)
- gst_rtsp_auth_set_realm (auth, realm);
- /* make admin token */
- token =
- gst_rtsp_token_new (GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
- username, NULL);
- gst_rtsp_auth_add_digest (auth, username, password, token);
- gst_rtsp_token_unref (token);
- /* set as the server authentication manager */
- gst_rtsp_server_set_auth (server, auth);
- g_object_unref (auth);
- /* attach the server to the default maincontext */
- gst_rtsp_server_attach (server, NULL);
- /* start serving */
- g_print ("stream ready at rtsp://0.0.0.0:554/MainStream\n");
- g_main_loop_run (loop);
- return 0;
- }
- void find_tag_in_file(const char* file_path, const char* tag, char *value) {
- FILE* file = fopen(file_path, "r");
- if (file == NULL) {
- g_print ("Failed to open file: %s\n", file_path);
- return;
- }
- char line[MAX_LINE_LENGTH];
- char start_tag[MAX_LINE_LENGTH] = { 0 };
- char end_tag[MAX_LINE_LENGTH] = { 0 };
- sprintf(start_tag, "<%s>", tag);
- sprintf(end_tag, "</%s>", tag);
- while (fgets(line, MAX_LINE_LENGTH, file)) {
- if (strstr(line, start_tag) && strstr(line, end_tag)) {
- // Extract the data between the start and end tags.
- char* start = strstr(line, start_tag) + strlen(start_tag);
- char* end = strstr(line, end_tag);
- *end = '\0'; // Null-terminate the string at the end of the data.
- strcpy(value, start);
- break;
- }
- }
- fclose(file);
- }
|