From: volpol Date: Fri, 13 Sep 2013 22:51:14 +0000 (+0000) Subject: Cosmetics only X-Git-Url: https://git.packet-gain.de/?a=commitdiff_plain;h=8a32b0300eda6acaad3a07325e9693d2a00c610d;p=hls.git Cosmetics only --- diff --git a/curly.c b/curly.c index b8ad046..a7850aa 100644 --- a/curly.c +++ b/curly.c @@ -29,106 +29,106 @@ static unsigned bufsize; #ifdef USE_TCP static void simple_http(int sock) { - const char *RSP = - "HTTP/1.0 200 OK\r\nContent-Type: video/mp2t\r\nConnection: close\r\n\r\n\r\n"; - char drain[1024] = ""; - int err; - - WHOAMI; - //TODO POLL - do { - err = read(sock, drain, sizeof drain); - if (err <= 0) - return; - drain[err] = 0; - DPRINT("%s\n", drain); - } while (!strstr(drain, "\r\n\r\n")); - - send(sock, RSP, strlen(RSP), MSG_NOSIGNAL); - - DPRINT ("simple http response sent\n"); + const char *RSP = + "HTTP/1.0 200 OK\r\nContent-Type: video/mp2t\r\nConnection: close\r\n\r\n\r\n"; + char drain[1024] = ""; + int err; + + WHOAMI; + //TODO POLL + do { + err = read(sock, drain, sizeof drain); + if (err <= 0) + return; + drain[err] = 0; + DPRINT("%s\n", drain); + } while (!strstr(drain, "\r\n\r\n")); + + send(sock, RSP, strlen(RSP), MSG_NOSIGNAL); + + DPRINT ("simple http response sent\n"); } size_t fetch_send(void *ptr, size_t size, size_t nmemb, void *stream) { - size_t bytesize = size * nmemb; + size_t bytesize = size * nmemb; - int sent; + int sent; - WHOAMI; + WHOAMI; - if (conn < 0) - conn = accept(sock, NULL, NULL); + if (conn < 0) + conn = accept(sock, NULL, NULL); - if (conn >= 0 && !flag_conn) { - DPRINT("Connection accepted\n"); - flag_conn = 1; - simple_http(conn); - } + if (conn >= 0 && !flag_conn) { + DPRINT("Connection accepted\n"); + flag_conn = 1; + simple_http(conn); + } - if (flag_conn) { - sent = send(conn, ptr, bytesize, MSG_NOSIGNAL); - if (sent <= 0) { - DPRINT("Pious Teardown!\n"); - shutdown(conn, SHUT_RDWR); - close(conn); - conn = -1; - flag_conn = 0; - } - } + if (flag_conn) { + sent = send(conn, ptr, bytesize, MSG_NOSIGNAL); + if (sent <= 0) { + DPRINT("Pious Teardown!\n"); + shutdown(conn, SHUT_RDWR); + close(conn); + conn = -1; + flag_conn = 0; + } + } (void)stream; - return bytesize; + return bytesize; } static int prepare_tcp_dream(const char *ip, unsigned short port) { - int err = -1; - struct sockaddr_in lob; - WHOAMI; + int err = -1; + struct sockaddr_in lob; + WHOAMI; - sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); - if (sock < 0) - goto ERR_SOCK; + sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); + if (sock < 0) + goto ERR_SOCK; - lob.sin_family = AF_INET; - lob.sin_port = htons(port); - lob.sin_addr.s_addr = inet_addr(ip); + lob.sin_family = AF_INET; + lob.sin_port = htons(port); + lob.sin_addr.s_addr = inet_addr(ip); - err = bind(sock, (const struct sockaddr*) &lob, sizeof lob); + err = bind(sock, (const struct sockaddr*) &lob, sizeof lob); - if (err < 0) - goto ERR_BIND; + if (err < 0) + goto ERR_BIND; - err = listen(sock, 5); + err = listen(sock, 5); - if (err < 0) - goto ERR_LSTN; + if (err < 0) + goto ERR_LSTN; - flag_conn = 0; - conn = -1; - err = 0; + flag_conn = 0; + conn = -1; + err = 0; - goto ERR_SUCC; + goto ERR_SUCC; ERR_LSTN: ERR_BIND: - close(sock); + close(sock); ERR_SOCK: ERR_SUCC: - return err; + return err; } static void cleanup_tcp_dream(void){ - WHOAMI; - if (conn>=0){ - shutdown(conn, SHUT_RDWR); - close(conn); - conn = -1; - flag_conn = 0; - } - close(sock); + WHOAMI; + if (conn>=0){ + shutdown(conn, SHUT_RDWR); + close(conn); + conn = -1; + flag_conn = 0; + } + close(sock); } #else @@ -138,52 +138,52 @@ static void cleanup_tcp_dream(void){} static void prepare_tcp_dream(void){} size_t fetch_send(void *ptr, size_t size, size_t nmemb, void *stream) { - return (size * nmemb); + return (size * nmemb); } #endif int curly_init(void) { - CURLcode cc; - WHOAMI; + CURLcode cc; + WHOAMI; - cc = curl_global_init(CURL_GLOBAL_NOTHING); - if (cc != CURLE_OK) - return -1; - return 0; + cc = curl_global_init(CURL_GLOBAL_NOTHING); + if (cc != CURLE_OK) + return -1; + return 0; } void curly_cleanup(void) { - WHOAMI; - curl_global_cleanup(); + WHOAMI; + curl_global_cleanup(); } static CURL *sch; int curly_stream_init(const char *ip, unsigned short port) { - int err; + int err; - WHOAMI; + WHOAMI; - sch = curl_easy_init(); - bufsize = BSIZE; + sch = curl_easy_init(); + bufsize = BSIZE; //TODO error handling - err = prepare_tcp_dream(ip, port); + err = prepare_tcp_dream(ip, port); - return (sch != NULL && 0 == err); + return (sch != NULL && 0 == err); } void curly_stream_cleanup(void) { - WHOAMI; + WHOAMI; - if (sch) - curl_easy_cleanup(sch); + if (sch) + curl_easy_cleanup(sch); - cleanup_tcp_dream(); - sch = NULL; + cleanup_tcp_dream(); + sch = NULL; } #ifdef USE_TC7200_WORKAROUND @@ -192,51 +192,54 @@ void curly_stream_cleanup(void) { #endif int curly_stream(const char *from_url, unsigned long duration) { - CURLcode cc = CURLE_COULDNT_CONNECT; - int err = -1; - double abps, size; + CURLcode cc = CURLE_COULDNT_CONNECT; + int err = -1; + double abps, size; +#ifdef USE_TC7200_WORKAROUND + static int tc7200_deathcounter = 0; +#endif #ifdef USE_TC7200_WORKAROUND static int tc7200_deathcounter = 0; #endif - WHOAMI; + WHOAMI; #ifdef USE_TCP - //when we don't have a client don't actually stream anything - //but try to take just as long - time_t st = time(NULL); + //when we don't have a client don't actually stream anything + //but try to take just as long + time_t st = time(NULL); while (conn < 0 && (unsigned long)(time(NULL)-st) < duration) { - conn = accept(sock, NULL, NULL); - usleep(1); - } + conn = accept(sock, NULL, NULL); + usleep(1); + } - if (conn < 0){ - abps = 0; - size = 0; - cc = CURLE_OK; - goto FAKED; - } + if (conn < 0){ + abps = 0; + size = 0; + cc = CURLE_OK; + goto FAKED; + } #endif - if (!sch) - goto OUT; + if (!sch) + goto OUT; - cc = curl_easy_setopt(sch, CURLOPT_URL, from_url); - if (CURLE_OK != cc) - goto OUT; + cc = curl_easy_setopt(sch, CURLOPT_URL, from_url); + if (CURLE_OK != cc) + goto OUT; #ifdef USE_TCP - cc = curl_easy_setopt(sch, CURLOPT_WRITEFUNCTION, fetch_send); + cc = curl_easy_setopt(sch, CURLOPT_WRITEFUNCTION, fetch_send); #else - cc = curl_easy_setopt(sch, CURLOPT_WRITEDATA, stdout); + cc = curl_easy_setopt(sch, CURLOPT_WRITEDATA, stdout); #endif - if (CURLE_OK != cc) - goto OUT; + if (CURLE_OK != cc) + goto OUT; - curl_easy_setopt(sch, CURLOPT_BUFFERSIZE, bufsize); + curl_easy_setopt(sch, CURLOPT_BUFFERSIZE, bufsize); #ifdef USE_TC7200_WORKAROUND //this is to work around a fucked up tc7200 router @@ -250,28 +253,28 @@ int curly_stream(const char *from_url, unsigned long duration) { #endif #ifdef DEBUG - curl_easy_setopt(sch, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(sch, CURLOPT_VERBOSE, 1L); #endif - curl_easy_setopt(sch, CURLOPT_TIMEOUT, 6*duration); //better than never timing out + curl_easy_setopt(sch, CURLOPT_TIMEOUT, 6*duration); //better than never timing out - cc = curl_easy_perform(sch); + cc = curl_easy_perform(sch); - if (CURLE_OK != cc) - goto OUT; + if (CURLE_OK != cc) + goto OUT; - cc = curl_easy_getinfo(sch,CURLINFO_SIZE_DOWNLOAD, &size); - cc |= curl_easy_getinfo(sch,CURLINFO_SPEED_DOWNLOAD, &abps); + cc = curl_easy_getinfo(sch,CURLINFO_SIZE_DOWNLOAD, &size); + cc |= curl_easy_getinfo(sch,CURLINFO_SPEED_DOWNLOAD, &abps); FAKED: - if (CURLE_OK == cc) - printf("%8.0f bytes @ %4.2f KB/s (%lu real seconds)\n", size, abps / 1000.0, time(NULL)-st); + if (CURLE_OK == cc) + printf("%8.0f bytes @ %4.2f KB/s (%lu real seconds)\n", size, abps / 1000.0, time(NULL)-st); - err = 0; + err = 0; OUT: - return err; + return err; } @@ -290,37 +293,37 @@ int curly_refresh_m3u8(const char *from_url, MFILE *f) { #endif - CURL *ch = NULL; - CURLcode cc; + CURL *ch = NULL; + CURLcode cc; #ifdef USE_STREAM - FILE *f; + FILE *f; #endif - int err = -1; - WHOAMI; + int err = -1; + WHOAMI; #ifdef USE_STREAM - f = fopen(to_file, "w"); + f = fopen(to_file, "w"); - if (!f) - goto OUT; + if (!f) + goto OUT; #endif - /* - if (sch) - ch = sch; - else - */ + /* + if (sch) + ch = sch; + else + */ - ch = curl_easy_init(); + ch = curl_easy_init(); - if (!ch) - goto OUT; + if (!ch) + goto OUT; - cc = curl_easy_setopt(ch, CURLOPT_URL, from_url); - if (CURLE_OK != cc) - goto OUT; + cc = curl_easy_setopt(ch, CURLOPT_URL, from_url); + if (CURLE_OK != cc) + goto OUT; WHOAMI; @@ -342,31 +345,31 @@ int curly_refresh_m3u8(const char *from_url, MFILE *f) { cc = curl_easy_perform(ch); - if (CURLE_OK != cc) - goto OUT; + if (CURLE_OK != cc) + goto OUT; - err = 0; + err = 0; OUT: #ifdef USE_STREAM if (f) - fclose(f); + fclose(f); #endif - //if (ch && ch!=sch) curl_easy_cleanup(ch); + //if (ch && ch!=sch) curl_easy_cleanup(ch); - if (ch) - curl_easy_cleanup(ch); + if (ch) + curl_easy_cleanup(ch); - return err; + return err; } int curly_is_connected(void){ - WHOAMI; + WHOAMI; #ifdef USE_TCP - return flag_conn; + return flag_conn; #else - return 1; + return 1; #endif } diff --git a/itemq.c b/itemq.c index a5005d0..e00f83b 100644 --- a/itemq.c +++ b/itemq.c @@ -34,30 +34,30 @@ static void handle_signal(int sig){ } struct item { - char url[1024]; - unsigned int hash; - //will be set to 1 after streamed - int done; - // will be set to 1 when it can be purged from the list - // this is true when done is 1 and after the last refresh round - // this hash was no longer present in the m3u8 - int purge; - struct item *next; - unsigned long duration; - int is_streamlist; - int bandwidth; + char url[1024]; + unsigned int hash; + //will be set to 1 after streamed + int done; + // will be set to 1 when it can be purged from the list + // this is true when done is 1 and after the last refresh round + // this hash was no longer present in the m3u8 + int purge; + struct item *next; + unsigned long duration; + int is_streamlist; + int bandwidth; }; static void *zalloc(size_t size) { - void *ptr; + void *ptr; - WHOAMI; + WHOAMI; - ptr = malloc(size); - if (ptr) - memset(ptr, 0, size); + ptr = malloc(size); + if (ptr) + memset(ptr, 0, size); - return ptr; + return ptr; } @@ -65,122 +65,122 @@ static void *zalloc(size_t size) { static void print_list(void) { #ifdef DEBUG - struct item *n = head; - int i = 0; + struct item *n = head; + int i = 0; - WHOAMI; + WHOAMI; - while (n != NULL) { - DPRINT("[%d] %s:%lu:%X:%d:%d\n", ++i, n->url, n->duration, n->hash, n->done, - n->purge); - n = n->next; - } + while (n != NULL) { + DPRINT("[%d] %s:%lu:%X:%d:%d\n", ++i, n->url, n->duration, n->hash, n->done, + n->purge); + n = n->next; + } #endif } struct item *find_hash(unsigned int hash) { - struct item *n = head; + struct item *n = head; - WHOAMI; + WHOAMI; - while (n != NULL) { - if (n->hash == hash) - break; - n = n->next; - } - return n; + while (n != NULL) { + if (n->hash == hash) + break; + n = n->next; + } + return n; } static int compute_hash(const char *s) { - int hash = 0; - unsigned char bcc = 0; - - WHOAMI; - - while (*s) { - bcc ^= *s; - hash ^= bcc; - hash <<= 2; - s++; - } - return hash; + int hash = 0; + unsigned char bcc = 0; + + WHOAMI; + + while (*s) { + bcc ^= *s; + hash ^= bcc; + hash <<= 2; + s++; + } + return hash; } static void purge_run(int killemall) { - struct item *n; + struct item *n; - WHOAMI; + WHOAMI; //purge here while (head && (head->purge || killemall)) { - DPRINT("Purging %s:%X:%d:%d\n", head->url, head->hash, head->done, - head->purge); - n = head; - head = head->next; - free(n); - } + DPRINT("Purging %s:%X:%d:%d\n", head->url, head->hash, head->done, + head->purge); + n = head; + head = head->next; + free(n); + } } static void purge_prepare(void) { - struct item *n; + struct item *n; - WHOAMI; + WHOAMI; - //mark done entries as ok to purge - //don't mark curr as ok to purge because we might - //still need it to advance to its next in emulate_stream() - for (n = head; n && n->done && n!=curr; n = n->next){ - n->purge = 1; - } + //mark done entries as ok to purge + //don't mark curr as ok to purge because we might + //still need it to advance to its next in emulate_stream() + for (n = head; n && n->done && n!=curr; n = n->next){ + n->purge = 1; + } } void emulate_stream(void) { - int err; - - WHOAMI; - - if (!curr) { - //this should never happen, no reasonable way to recover - fprintf(stderr,"curr is NULL, bailing out\n"); - in_game = 0; - return; - } - - if (curr->done){ - if (curr->next){ - curr = curr->next; - } else { - //we end up here if we are faster than the server can produce - if (!live) { - in_game = 0; - } else { - DPRINT("sleeping\n"); - sleep(1); - } - return; - } - } - - do { - printf("Streaming %s (%lu)\n", curr->url, curr->duration); + int err; + + WHOAMI; + + if (!curr) { + //this should never happen, no reasonable way to recover + fprintf(stderr,"curr is NULL, bailing out\n"); + in_game = 0; + return; + } + + if (curr->done){ + if (curr->next){ + curr = curr->next; + } else { + //we end up here if we are faster than the server can produce + if (!live) { + in_game = 0; + } else { + DPRINT("sleeping\n"); + sleep(1); + } + return; + } + } + + do { + printf("Streaming %s (%lu)\n", curr->url, curr->duration); #if 1 - err = curly_stream(curr->url, curr->duration); + err = curly_stream(curr->url, curr->duration); #else - err = -1; curly_fake_stream(); + err = -1; curly_fake_stream(); #endif - if (err){ - DPRINT("Streaming failed\n"); - } + if (err){ + DPRINT("Streaming failed\n"); + } - } while (0); + } while (0); - curr->done = 1; + curr->done = 1; } #ifdef USE_STREAM @@ -190,216 +190,216 @@ int reload_m3u8(MFILE *f, const char *urlbase) { #endif #ifdef USE_STREAM - FILE *f; + FILE *f; #endif - char buf[1024]; - struct item *n; - struct item *p; - unsigned int thash; - unsigned long lval; + char buf[1024]; + struct item *n; + struct item *p; + unsigned int thash; + unsigned long lval; - int plist,pid,bw; + int plist,pid,bw; - const char *v; - MTAG m; - int urloff; + const char *v; + MTAG m; + int urloff; - WHOAMI; + WHOAMI; - plist = pid = bw = 0; + plist = pid = bw = 0; - DPRINT("Reloading M3U8\n"); + DPRINT("Reloading M3U8\n"); #ifdef USE_STREAM f = fopen(from_file, "r"); #endif - if (!f) - return -1; + if (!f) + return -1; #ifdef USE_STREAM - while (fgets(buf, sizeof buf, f)) { + while (fgets(buf, sizeof buf, f)) { #else - while (mgets(buf, sizeof buf, f)) { + while (mgets(buf, sizeof buf, f)) { #endif - if (buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = 0; - if (buf[strlen(buf) - 1] == '\r') - buf[strlen(buf) - 1] = 0; - - m = m3u8_parse(buf, &v); - - if (M_EXTINF == m){ - m3u8_get_property(P_DURATION, v, &lval); - } - if (M_X_ENDLIST == m){ - printf("This is not a live stream!\n"); - live = 0; - } - if (M_X_STREAM_INF == m){ - //playlist entry detected; - plist = 1; - m3u8_get_property(P_BANDWIDTH, v, &lval); - bw = lval; - m3u8_get_property(P_PROGRAM_ID, v, &lval); - pid = lval; - printf ("PID: %d BW:%d\n",pid, bw); - } - - if (M_URL != m) continue; - - /* - position to add will be determined by the hash of new entry vs hashes already in the list - that is...all new hashes will be added at tail unless this entry's hash is already in the list - the entry is not then not added but the next new one will be added after this one - this will in degenerate into adding at tail if m3u8 refresh interval is too long (old entries purged) - */ - - thash = compute_hash(buf); - - if ((p = find_hash(thash))) { - //element is still in the newest m3u8 - //hold onto it some longer - p->purge = 0; - continue; - } - - n = zalloc(sizeof(struct item)); - n->hash = thash; - n->is_streamlist = plist; - n->bandwidth = bw; - - urloff = 0; - - if (strncmp(buf,"http://",7)){ - strcpy(n->url,urlbase); - urloff = strlen(urlbase); - } - - strcpy(n->url+urloff, buf); - n->duration = lval; - - if (!head) { - //XXX curr is always first, which is not what we want in certain scenarios - head = tail = curr = n; - } else { - if (!p || p == tail) { //hash not found - tail->next = n; - tail = n; - } else { - n->next = p->next; - p->next = n; - } - } - } + if (buf[strlen(buf) - 1] == '\n') + buf[strlen(buf) - 1] = 0; + if (buf[strlen(buf) - 1] == '\r') + buf[strlen(buf) - 1] = 0; + + m = m3u8_parse(buf, &v); + + if (M_EXTINF == m){ + m3u8_get_property(P_DURATION, v, &lval); + } + if (M_X_ENDLIST == m){ + printf("This is not a live stream!\n"); + live = 0; + } + if (M_X_STREAM_INF == m){ + //playlist entry detected; + plist = 1; + m3u8_get_property(P_BANDWIDTH, v, &lval); + bw = lval; + m3u8_get_property(P_PROGRAM_ID, v, &lval); + pid = lval; + printf ("PID: %d BW:%d\n",pid, bw); + } + + if (M_URL != m) continue; + + /* + position to add will be determined by the hash of new entry vs hashes already in the list + that is...all new hashes will be added at tail unless this entry's hash is already in the list + the entry is not then not added but the next new one will be added after this one + this will in degenerate into adding at tail if m3u8 refresh interval is too long (old entries purged) + */ + + thash = compute_hash(buf); + + if ((p = find_hash(thash))) { + //element is still in the newest m3u8 + //hold onto it some longer + p->purge = 0; + continue; + } + + n = zalloc(sizeof(struct item)); + n->hash = thash; + n->is_streamlist = plist; + n->bandwidth = bw; + + urloff = 0; + + if (strncmp(buf,"http://",7)){ + strcpy(n->url,urlbase); + urloff = strlen(urlbase); + } + + strcpy(n->url+urloff, buf); + n->duration = lval; + + if (!head) { + //XXX curr is always first, which is not what we want in certain scenarios + head = tail = curr = n; + } else { + if (!p || p == tail) { //hash not found + tail->next = n; + tail = n; + } else { + n->next = p->next; + p->next = n; + } + } + } #ifdef USE_STREAM - fclose(f); + fclose(f); #endif - return 0; + return 0; } const char *choose_url(void){ - struct item *n; - const char *u; - int bw = 0; - - WHOAMI; - - n = head; - u = head->url; - while (n){ - //choose first matching url, >= to choose last, but could lead to problems, allow user selection! - if (n->bandwidth>bw) {u = n->url; bw=n->bandwidth; } - n->done = 1; - n->purge = 1; - n=n->next; - } - - printf ("Final BW: %d | URL: %s\n",bw, u); - return u; + struct item *n; + const char *u; + int bw = 0; + + WHOAMI; + + n = head; + u = head->url; + while (n){ + //choose first matching url, >= to choose last, but could lead to problems, allow user selection! + if (n->bandwidth>bw) {u = n->url; bw=n->bandwidth; } + n->done = 1; + n->purge = 1; + n=n->next; + } + + printf ("Final BW: %d | URL: %s\n",bw, u); + return u; } static void reset_base(char *base, char *url){ - WHOAMI; + WHOAMI; - strcpy(base,url); - //TODO risky dice - *(strrchr(base, '/')+1) = 0; + strcpy(base,url); + //TODO risky dice + *(strrchr(base, '/')+1) = 0; } int main(int argc, char *argv[]) { - time_t last, now; + time_t last, now; - int refreshed; - int refresh_period = 20; - char url[1024]; - char base[1024]; + int refreshed; + int refresh_period = 20; + char url[1024]; + char base[1024]; - if (argc>1) - strcpy(url, argv[1]); - else - strcpy(url, QVC_MASTER_M3U8); + if (argc>1) + strcpy(url, argv[1]); + else + strcpy(url, QVC_MASTER_M3U8); - printf ("Master URL: %s\n",url); + printf ("Master URL: %s\n",url); - reset_base(base, url); + reset_base(base, url); - curly_init(); + curly_init(); curly_stream_init("0.0.0.0",7120); - last = now = 0; - head = tail = curr = NULL; - live = in_game = 1; + last = now = 0; + head = tail = curr = NULL; + live = in_game = 1; signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); - while (in_game) { - now = time(NULL); - if (live && now-last>=refresh_period) { - DPRINT("Refreshing M3U8 after %d real seconds\n",(int)(last?now-last:0)); + while (in_game) { + now = time(NULL); + if (live && now-last>=refresh_period) { + DPRINT("Refreshing M3U8 after %d real seconds\n",(int)(last?now-last:0)); #ifdef USE_STREAM - refreshed = (0 == curly_refresh_m3u8(url, PLS)); + refreshed = (0 == curly_refresh_m3u8(url, PLS)); #else MFILE *f = mopen(NULL, 0, "w+"); refreshed = (0 == curly_refresh_m3u8(url, f)); #endif - if (refreshed) { - last = now = time(NULL); - purge_prepare(); + if (refreshed) { + last = now = time(NULL); + purge_prepare(); #ifdef USE_STREAM - if (0 == reload_m3u8(PLS, base)) { + if (0 == reload_m3u8(PLS, base)) { #else if (0 == reload_m3u8(f, base)) { mclose(f); #endif - refreshed = 0; + refreshed = 0; purge_run(0); - print_list(); + print_list(); - if (head->is_streamlist){ - strcpy (url, choose_url()); - reset_base(base, url); - curr = NULL; //so purge will not spare it + if (head->is_streamlist){ + strcpy (url, choose_url()); + reset_base(base, url); + curr = NULL; //so purge will not spare it purge_run(0); - last = 0; - continue; - } - } - } else { - DPRINT ("Could not load M3U8 from %s!\n",url); - sleep (1); - } - } + last = 0; + continue; + } + } + } else { + DPRINT ("Could not load M3U8 from %s!\n",url); + sleep (1); + } + } - emulate_stream(); + emulate_stream(); - } + } purge_run(1); - curly_stream_cleanup(); - curly_cleanup(); - return 0; + curly_stream_cleanup(); + curly_cleanup(); + return 0; }