test-onvif-backchannel.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /* GStreamer
  2. * Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  17. * Boston, MA 02110-1301, USA.
  18. */
  19. #include <gst/gst.h>
  20. #include <gst/rtsp-server/rtsp-onvif-server.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include "iniparser/iniparser.h"
  24. #define CONF "/oem/etc/config.xml"
  25. #define SPK_CONF "/etc/speaker.conf"
  26. #define MAX_LINE_LENGTH 256
  27. struct SPEAKER_CONF
  28. {
  29. char hw_version[16];
  30. char dev_type[32];
  31. char enable_mic[8];
  32. char media_stream[8];
  33. };
  34. void find_tag_in_file(const char* file_path, const char* tag, char *value);
  35. void confParse(struct SPEAKER_CONF *conf);
  36. void confParse(struct SPEAKER_CONF *conf)
  37. {
  38. dictionary * ini ;
  39. ini = iniparser_load(SPK_CONF);
  40. if (ini==NULL) {
  41. fprintf(stderr, "cannot parse file: %s\n", SPK_CONF);
  42. exit(-1);
  43. }
  44. strcpy(conf->dev_type, iniparser_getstring(ini, "system:ui_model", ""));
  45. strcpy(conf->hw_version, iniparser_getstring(ini, "system:hard_version", ""));
  46. strcpy(conf->enable_mic, iniparser_getstring(ini, "onvif:enable_mic", "no"));
  47. strcpy(conf->media_stream, iniparser_getstring(ini, "onvif:media_stream", "main"));
  48. iniparser_freedict(ini);
  49. }
  50. static gchar *htdigest_path = NULL;
  51. static gchar *realm = NULL;
  52. static GOptionEntry entries[] = {
  53. {"htdigest-path", 'h', 0, G_OPTION_ARG_STRING, &htdigest_path,
  54. "Path to an htdigest file to parse (default: None)", "PATH"},
  55. {"realm", 'r', 0, G_OPTION_ARG_STRING, &realm,
  56. "Authentication realm (default: None)", "REALM"},
  57. {NULL}
  58. };
  59. int
  60. main (int argc, char *argv[])
  61. {
  62. GMainLoop *loop;
  63. GstRTSPServer *server;
  64. GstRTSPMountPoints *mounts;
  65. GstRTSPMediaFactory *factory;
  66. GstRTSPAuth *auth;
  67. GstRTSPToken *token;
  68. GOptionContext *optctx;
  69. GError *error = NULL;
  70. struct SPEAKER_CONF conf;
  71. confParse(&conf);;
  72. char launchstr[512];
  73. char username[64] = { 0 };
  74. char password[64] = { 0 };
  75. find_tag_in_file(CONF, "auth_user", username);
  76. find_tag_in_file(CONF, "auth_pass", password);
  77. if (strlen(username) == 0 || strlen(password) == 0) {
  78. g_print ("Please username or password in config.xml\n");
  79. return -1;
  80. }
  81. // putenv("GST_DEBUG=4");
  82. gst_init (&argc, &argv);
  83. optctx = g_option_context_new (NULL);
  84. g_option_context_add_main_entries (optctx, entries, NULL);
  85. g_option_context_add_group (optctx, gst_init_get_option_group ());
  86. if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
  87. g_printerr ("Error parsing options: %s\n", error->message);
  88. g_option_context_free (optctx);
  89. g_clear_error (&error);
  90. return -1;
  91. }
  92. g_option_context_free (optctx);
  93. loop = g_main_loop_new (NULL, FALSE);
  94. /* create a server instance */
  95. server = gst_rtsp_onvif_server_new ();
  96. /* get the mount points for this server, every server has a default object
  97. * that be used to map uri mount points to media factories */
  98. mounts = gst_rtsp_server_get_mount_points (server);
  99. /* make a media factory for a test stream. The default media factory can use
  100. * gst-launch syntax to create pipelines.
  101. * any launch line works as long as it contains elements named pay%d. Each
  102. * element with pay%d names will be a stream */
  103. factory = gst_rtsp_onvif_media_factory_new ();
  104. //! video/x-raw, format=(string)RGB, width=(int)640, height=(int)480
  105. strcpy(launchstr, "( filesrc loop=true location=\"/usr/share/onvif/speaker.h264\" ! video/x-h264 ! h264parse ! rtph264pay pt=96 config-interval=5 name=pay0 ");
  106. if(strcmp(conf.enable_mic, "yes") == 0)
  107. {
  108. strcat(launchstr, "alsasrc device=plug:mixmic ! queue ! audioconvert ! audioresample ! mulawenc ! rtppcmupay name=pay1 )");
  109. }
  110. else
  111. {
  112. strcat(launchstr, " )");
  113. }
  114. gst_rtsp_media_factory_set_launch (factory,launchstr);
  115. gst_rtsp_onvif_media_factory_set_backchannel_launch
  116. (GST_RTSP_ONVIF_MEDIA_FACTORY (factory),
  117. "( 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 )");
  118. //"( 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 )");
  119. gst_rtsp_media_factory_set_shared (factory, FALSE);
  120. gst_rtsp_media_factory_set_media_gtype (factory, GST_TYPE_RTSP_ONVIF_MEDIA);
  121. /* attach the test factory to the /test url */
  122. gst_rtsp_mount_points_add_factory (mounts, "/MainStream", factory);
  123. /* allow admin to access this resource */
  124. gst_rtsp_media_factory_add_role (factory, username,
  125. GST_RTSP_PERM_MEDIA_FACTORY_ACCESS, G_TYPE_BOOLEAN, TRUE,
  126. GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT, G_TYPE_BOOLEAN, TRUE, NULL);
  127. /* don't need the ref to the mapper anymore */
  128. g_object_unref (mounts);
  129. /* make a new authentication manager */
  130. auth = gst_rtsp_auth_new ();
  131. gst_rtsp_auth_set_supported_methods (auth, GST_RTSP_AUTH_DIGEST);
  132. if (realm)
  133. gst_rtsp_auth_set_realm (auth, realm);
  134. /* make admin token */
  135. token =
  136. gst_rtsp_token_new (GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING,
  137. username, NULL);
  138. gst_rtsp_auth_add_digest (auth, username, password, token);
  139. gst_rtsp_token_unref (token);
  140. /* set as the server authentication manager */
  141. gst_rtsp_server_set_auth (server, auth);
  142. g_object_unref (auth);
  143. /* attach the server to the default maincontext */
  144. gst_rtsp_server_attach (server, NULL);
  145. /* start serving */
  146. g_print ("stream ready at rtsp://0.0.0.0:554/MainStream\n");
  147. g_main_loop_run (loop);
  148. return 0;
  149. }
  150. void find_tag_in_file(const char* file_path, const char* tag, char *value) {
  151. FILE* file = fopen(file_path, "r");
  152. if (file == NULL) {
  153. g_print ("Failed to open file: %s\n", file_path);
  154. return;
  155. }
  156. char line[MAX_LINE_LENGTH];
  157. char start_tag[MAX_LINE_LENGTH] = { 0 };
  158. char end_tag[MAX_LINE_LENGTH] = { 0 };
  159. sprintf(start_tag, "<%s>", tag);
  160. sprintf(end_tag, "</%s>", tag);
  161. while (fgets(line, MAX_LINE_LENGTH, file)) {
  162. if (strstr(line, start_tag) && strstr(line, end_tag)) {
  163. // Extract the data between the start and end tags.
  164. char* start = strstr(line, start_tag) + strlen(start_tag);
  165. char* end = strstr(line, end_tag);
  166. *end = '\0'; // Null-terminate the string at the end of the data.
  167. strcpy(value, start);
  168. break;
  169. }
  170. }
  171. fclose(file);
  172. }