2 * Copyright (C) 2017 Make.TV, Inc. <info@make.tv>
3 * Contact: Jan Alexander Steffens (heftig) <jsteffens@make.tv>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "gstrtmp2locationhandler.h"
22 #include "rtmp/rtmputils.h"
23 #include "rtmp/rtmpclient.h"
26 #define DEFAULT_SCHEME GST_RTMP_SCHEME_RTMP
27 #define DEFAULT_HOST "localhost"
28 #define DEFAULT_APPLICATION "live"
29 #define DEFAULT_STREAM "myStream"
30 #define DEFAULT_LOCATION "rtmp://" DEFAULT_HOST "/" DEFAULT_APPLICATION "/" DEFAULT_STREAM
31 #define DEFAULT_SECURE_TOKEN NULL
32 #define DEFAULT_USERNAME NULL
33 #define DEFAULT_PASSWORD NULL
34 #define DEFAULT_AUTHMOD GST_RTMP_AUTHMOD_AUTO
35 #define DEFAULT_TIMEOUT 5
37 G_DEFINE_INTERFACE (GstRtmpLocationHandler, gst_rtmp_location_handler, 0);
39 #define GST_CAT_DEFAULT gst_rtmp_location_handler_debug_category
40 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
43 gst_rtmp_location_handler_default_init (GstRtmpLocationHandlerInterface * iface)
45 GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "rtmp2locationhandler", 0,
46 "RTMP2 Location Handling");
48 g_object_interface_install_property (iface, g_param_spec_string ("location",
49 "Location", "Location of RTMP stream to access", DEFAULT_LOCATION,
50 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
51 g_object_interface_install_property (iface, g_param_spec_enum ("scheme",
52 "Scheme", "RTMP connection scheme",
53 GST_TYPE_RTMP_SCHEME, DEFAULT_SCHEME,
54 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
55 g_object_interface_install_property (iface, g_param_spec_string ("host",
56 "Host", "RTMP server host name", DEFAULT_HOST,
57 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
58 g_object_interface_install_property (iface, g_param_spec_int ("port", "Port",
59 "RTMP server port", 1, 65535,
60 gst_rtmp_scheme_get_default_port (DEFAULT_SCHEME),
61 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
62 g_object_interface_install_property (iface,
63 g_param_spec_string ("application", "Application",
64 "RTMP application path", DEFAULT_APPLICATION,
65 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
66 g_object_interface_install_property (iface, g_param_spec_string ("stream",
67 "Stream", "RTMP stream path", DEFAULT_STREAM,
68 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
69 g_object_interface_install_property (iface, g_param_spec_string ("username",
70 "User name", "RTMP authorization user name", DEFAULT_USERNAME,
71 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
72 g_object_interface_install_property (iface, g_param_spec_string ("password",
73 "Password", "RTMP authorization password", DEFAULT_PASSWORD,
74 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
75 g_object_interface_install_property (iface,
76 g_param_spec_string ("secure-token", "Secure token",
77 "RTMP authorization token", DEFAULT_SECURE_TOKEN,
78 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
79 g_object_interface_install_property (iface, g_param_spec_enum ("authmod",
80 "Authorization mode", "RTMP authorization mode",
81 GST_TYPE_RTMP_AUTHMOD, DEFAULT_AUTHMOD,
82 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
83 g_object_interface_install_property (iface, g_param_spec_uint ("timeout",
84 "Timeout", "RTMP timeout in seconds", 0, G_MAXUINT, DEFAULT_TIMEOUT,
85 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
86 g_object_interface_install_property (iface,
87 g_param_spec_flags ("tls-validation-flags", "TLS validation flags",
88 "TLS validation flags to use", G_TYPE_TLS_CERTIFICATE_FLAGS,
89 G_TLS_CERTIFICATE_VALIDATE_ALL,
90 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
94 uri_handler_get_type_sink (GType type)
100 uri_handler_get_type_src (GType type)
105 static const gchar *const *
106 uri_handler_get_protocols (GType type)
108 return gst_rtmp_scheme_get_strings ();
112 uri_handler_get_uri (GstURIHandler * handler)
114 GstRtmpLocation location = { 0, };
117 g_object_get (handler, "scheme", &location.scheme, "host", &location.host,
118 "port", &location.port, "application", &location.application,
119 "stream", &location.stream, NULL);
121 string = gst_rtmp_location_get_string (&location, TRUE);
122 gst_rtmp_location_clear (&location);
127 uri_handler_set_uri (GstURIHandler * handler, const gchar * string,
130 GstRtmpLocationHandler *self = GST_RTMP_LOCATION_HANDLER (handler);
132 const gchar *scheme_sep, *path_sep, *stream_sep, *host, *userinfo;
133 GstRtmpScheme scheme;
135 gboolean ret = FALSE;
137 GST_DEBUG_OBJECT (self, "setting URI from %s", GST_STR_NULL (string));
138 g_return_val_if_fail (string, FALSE);
140 scheme_sep = strstr (string, "://");
142 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
143 "URI lacks scheme: %s", string);
147 path_sep = strchr (scheme_sep + 3, '/');
149 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
150 "URI lacks path: %s", string);
154 stream_sep = strrchr (path_sep + 1, '/');
156 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
157 "URI lacks stream: %s", string);
162 gchar *string_without_path = g_strndup (string, path_sep - string);
163 uri = gst_uri_from_string (string_without_path);
164 g_free (string_without_path);
168 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
169 "URI failed to parse: %s", string);
173 gst_uri_normalize (uri);
175 scheme = gst_rtmp_scheme_from_uri (uri);
177 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
178 "URI has bad scheme: %s", string);
182 host = gst_uri_get_host (uri);
184 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
185 "URI lacks hostname: %s", string);
189 port = gst_uri_get_port (uri);
190 if (port == GST_URI_NO_PORT) {
191 port = gst_rtmp_scheme_get_default_port (scheme);
195 const gchar *path = path_sep + 1, *stream = stream_sep + 1;
196 gchar *application = g_strndup (path, stream_sep - path);
198 GST_DEBUG_OBJECT (self, "setting location to %s://%s:%u/%s stream %s",
199 gst_rtmp_scheme_to_string (scheme), host, port, application, stream);
201 g_object_set (self, "scheme", scheme, "host", host, "port", port,
202 "application", application, "stream", stream, "username", NULL,
203 "password", NULL, NULL);
205 g_free (application);
208 userinfo = gst_uri_get_userinfo (uri);
210 gchar **split = g_strsplit (userinfo, ":", 2);
212 if (!split || !split[0] || !split[1]) {
213 g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
214 "Failed to parse username:password data");
219 g_object_set (self, "username", split[0], "password", split[1], NULL);
231 gst_rtmp_location_handler_implement_uri_handler (GstURIHandlerInterface * iface,
236 iface->get_type = uri_handler_get_type_sink;
239 iface->get_type = uri_handler_get_type_src;
242 g_return_if_reached ();
244 iface->get_protocols = uri_handler_get_protocols;
245 iface->get_uri = uri_handler_get_uri;
246 iface->set_uri = uri_handler_set_uri;
250 gst_rtmp_location_handler_set_uri (GstRtmpLocationHandler * handler,
253 GError *error = NULL;
256 g_return_val_if_fail (GST_IS_RTMP_LOCATION_HANDLER (handler), FALSE);
258 ret = gst_uri_handler_set_uri (GST_URI_HANDLER (handler), uri, &error);
260 GST_ERROR_OBJECT (handler, "Failed to set URI: %s", error->message);
261 g_object_set (handler, "scheme", DEFAULT_SCHEME, "host", NULL,
262 "port", gst_rtmp_scheme_get_default_port (DEFAULT_SCHEME),
263 "application", NULL, "stream", NULL, NULL);
264 g_error_free (error);