iptv_input_mux_started ( iptv_mux_t *im )
{
/* Allocate input buffer */
- sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
- im->mm_iptv_rtp_seq = -1;
+ sbuf_reset_and_alloc(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
if (iptv_input_fd_started(im))
return;
iptv_network_delete ( mpegts_network_t *mn, int delconf )
{
iptv_network_t *in = (iptv_network_t*)mn;
- char *s = in->in_url;
+ char *url = in->in_url;
+ char *sane_url = in->in_url_sane;
if (in->mn_id.in_class == &iptv_auto_network_class)
iptv_auto_network_done(in);
free(in->in_remove_args);
mpegts_network_delete(mn, delconf);
- free(s);
+ free(sane_url);
+ free(url);
}
/* **************************************************************************
}
};
+static int
+iptv_auto_network_class_url_set( void *in, const void *v )
+{
+ iptv_network_t *mn = in;
+ return iptv_url_set(&mn->in_url, &mn->in_url_sane, v, 1, 0);
+}
+
+static void
+iptv_auto_network_class_notify_url( void *in, const char *lang )
+{
+ iptv_auto_network_trigger(in);
+}
+
const idclass_t iptv_auto_network_class = {
.ic_super = &iptv_network_class,
.ic_class = "iptv_auto_network",
.id = "url",
.name = N_("URL"),
.off = offsetof(iptv_network_t, in_url),
+ .set = iptv_auto_network_class_url_set,
+ .notify = iptv_auto_network_class_notify_url,
+ .opts = PO_MULTILINE
},
{
.type = PT_S64,
memset(&u, 0, sizeof(u));
+ if (in->in_url == NULL)
+ goto done;
+
if (strncmp(in->in_url, "file://", 7) == 0) {
iptv_auto_network_file(in, in->in_url + 7);
- goto arm;
+ goto done;
}
gtimer_disarm(&in->in_auto_timer);
if (urlparse(in->in_url, &u) < 0) {
tvherror("iptv", "wrong url for network '%s'", in->mn_network_name);
- goto arm;
+ goto done;
}
hc = http_client_connect(in, HTTP_VERSION_1_1, u.scheme, u.host, u.port, NULL);
if (hc == NULL) {
tvherror("iptv", "unable to open http client for network '%s'", in->mn_network_name);
- goto arm;
+ goto done;
}
hc->hc_handle_location = 1;
hc->hc_data_limit = 1024*1024;
if (http_client_simple(hc, &u) < 0) {
http_client_close(hc);
tvherror("iptv", "unable to send http command for network '%s'", in->mn_network_name);
- goto arm;
+ goto done;
}
in->in_http_client = hc;
-arm:
- urlreset(&u);
gtimer_arm(&in->in_auto_timer, iptv_auto_network_fetch, in,
MAX(1, in->in_refetch_period) * 60);
+done:
+ urlreset(&u);
}
/*
*
*/
void
-iptv_auto_network_init( iptv_network_t *in )
+iptv_auto_network_trigger( iptv_network_t *in )
{
gtimer_arm(&in->in_auto_timer, iptv_auto_network_fetch, in, 0);
}
+/*
+ *
+ */
+void
+iptv_auto_network_init( iptv_network_t *in )
+{
+ iptv_auto_network_trigger(in);
+}
+
/*
*
*/
s = http_arg_get(&hc->hc_args, "Content-Type");
if (s) {
n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';');
- printf("mime: '%s'\n", s);
if (n > 0 &&
(strcasecmp(s, "audio/mpegurl") == 0 ||
- strcasecmp(s, "audio/x-mpegurl") == 0)) {
+ strcasecmp(s, "audio/x-mpegurl") == 0 ||
+ strcasecmp(s, "application/apple.vnd.mpegurl") == 0 ||
+ strcasecmp(s, "application/vnd.apple.mpegurl") == 0)) {
if (im->im_m3u_header > 10) {
im->im_m3u_header = 0;
return 0;
im->im_m3u_header = 0;
sbuf_append(&im->mm_iptv_buffer, "", 1);
url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data);
+ sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
if (url == NULL) {
tvherror("iptv", "m3u contents parsing failed");
return 0;
return SM_CODE_TUNING_FAILED;
}
im->im_data = hc;
+ sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
return 0;
}
extern const idclass_t mpegts_mux_class;
extern const idclass_t mpegts_mux_instance_class;
-static int
-iptv_mux_url_set ( void *p, const void *v )
+static inline void
+iptv_url_set0 ( char **url, char **sane_url,
+ const char *url1, const char *sane_url1 )
{
- iptv_mux_t *im = p;
- const char *str = v, *x;
+ free(*url);
+ free(*sane_url);
+ *url = url1 ? strdup(url1) : NULL;
+ *sane_url = sane_url1 ? strdup(sane_url1) : NULL;
+}
+
+int
+iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe )
+{
+ const char *x;
char *buf, port[16] = "";
size_t len;
- url_t url;
+ url_t u;
- if (strcmp(str ?: "", im->mm_iptv_url ?: "")) {
- if (str == NULL || *str == '\0') {
- free(im->mm_iptv_url);
- free(im->mm_iptv_url_sane);
- im->mm_iptv_url = NULL;
- im->mm_iptv_url_sane = NULL;
- return 1;
- }
- if (!strncmp(str, "pipe://", 7)) {
- x = str + strlen(str);
- while (x != str && *x <= ' ')
- x--;
- ((char *)x)[1] = '\0';
- free(im->mm_iptv_url);
- free(im->mm_iptv_url_sane);
- im->mm_iptv_url = strdup(str);
- im->mm_iptv_url_sane = strdup(str);
- return 1;
- }
- memset(&url, 0, sizeof(url));
- if (!urlparse(str, &url)) {
- free(im->mm_iptv_url);
- free(im->mm_iptv_url_sane);
- im->mm_iptv_url = strdup(str);
- if (im->mm_iptv_url) {
- len = (url.scheme ? strlen(url.scheme) + 3 : 0) +
- (url.host ? strlen(url.host) + 1 : 0) +
- /* port */ 16 +
- (url.path ? strlen(url.path) + 1 : 0) +
- (url.query ? strlen(url.query) + 2 : 0);
- buf = alloca(len);
- if (url.port > 0 && url.port <= 65535)
- snprintf(port, sizeof(port), ":%d", url.port);
- snprintf(buf, len, "%s%s%s%s%s%s%s",
- url.scheme ?: "", url.scheme ? "://" : "",
- url.host ?: "", port,
- url.path ?: "", url.query ? "?" : "",
- url.query ?: "");
- im->mm_iptv_url_sane = strdup(buf);
- } else {
- im->mm_iptv_url_sane = NULL;
- }
- urlreset(&url);
- return 1;
- }
- urlreset(&url);
+ if (strcmp(str ?: "", *url ?: "") == 0)
+ return 0;
+
+ if (str == NULL || *str == '\0') {
+ iptv_url_set0(url, sane_url, NULL, NULL);
+ return 1;
+ }
+ if (allow_file && !strncmp(str, "file://", 7)) {
+ iptv_url_set0(url, sane_url, str, str);
+ return 1;
}
+ if (allow_pipe && !strncmp(str, "pipe://", 7)) {
+ x = str + strlen(str);
+ while (x != str && *x <= ' ')
+ x--;
+ ((char *)x)[1] = '\0';
+ iptv_url_set0(url, sane_url, str, str);
+ return 1;
+ }
+ memset(&u, 0, sizeof(u));
+ if (!urlparse(str, &u)) {
+ len = (u.scheme ? strlen(u.scheme) + 3 : 0) +
+ (u.host ? strlen(u.host) + 1 : 0) +
+ /* port */ 16 +
+ (u.path ? strlen(u.path) + 1 : 0) +
+ (u.query ? strlen(u.query) + 2 : 0);
+ buf = alloca(len);
+ if (u.port > 0 && u.port <= 65535)
+ snprintf(port, sizeof(port), ":%d", u.port);
+ snprintf(buf, len, "%s%s%s%s%s%s%s",
+ u.scheme ?: "", u.scheme ? "://" : "",
+ u.host ?: "", port,
+ u.path ?: "", (u.query && u.query[0]) ? "?" : "",
+ u.query ?: "");
+ iptv_url_set0(url, sane_url, str, buf);
+ urlreset(&u);
+ return 1;
+ }
+
return 0;
}
+static int
+iptv_mux_url_set ( void *p, const void *v )
+{
+ iptv_mux_t *im = p;
+ return iptv_url_set(&im->mm_iptv_url, &im->mm_iptv_url_sane, v, 0, 1);
+}
+
static htsmsg_t *
iptv_muxdvr_class_kill_list ( void *o, const char *lang )
{
if (!im->mm_iptv_kill_timeout)
im->mm_iptv_kill_timeout = 5;
+ sbuf_init(&im->mm_iptv_buffer);
+
/* Create Instance */
(void)mpegts_mux_instance_create(mpegts_mux_instance, NULL,
(mpegts_input_t*)iptv_input,
uint32_t in_max_timeout;
char *in_url;
+ char *in_url_sane;
int64_t in_channel_number;
uint32_t in_refetch_period;
int in_ssl_peer_verify;
extern iptv_input_t *iptv_input;
extern iptv_network_t *iptv_network;
+int iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe );
+
void iptv_mux_load_all ( void );
+void iptv_auto_network_trigger( iptv_network_t *in );
void iptv_auto_network_init( iptv_network_t *in );
void iptv_auto_network_done( iptv_network_t *in );