|
|
|
@ -45,8 +45,9 @@
|
|
|
|
|
#define RTV_NAPISI(kaj, frmt, ...) /* pazi na format string RCE! */ \ |
|
|
|
|
do { if ( RTV_NAPISI_ ##kaj ) fprintf(stderr, \
|
|
|
|
|
"[" #kaj "] %s@%s:" NIZ(__LINE__) " " frmt "\n", \
|
|
|
|
|
__func__, __FILE__, ##__VA_ARGS__ ); } while(0); |
|
|
|
|
#define RTV_VER "0.1.1" |
|
|
|
|
__func__, __FILE__, ##__VA_ARGS__ ); \
|
|
|
|
|
fflush(stderr); } while(0); |
|
|
|
|
#define RTV_VER "0.1.2" |
|
|
|
|
#define RTV_USER_AGENT "Mozilla/5.0 equivalent (rtv4d-dl " RTV_VER "; C " \ |
|
|
|
|
NIZ(__STDC_VERSION__) " GCC " __VERSION__ "; " __DATE__ " " __TIME__ "; " \
|
|
|
|
|
__FILE__ ":" NIZ(__LINE__) ")" |
|
|
|
@ -111,7 +112,7 @@
|
|
|
|
|
if (strncmp(otr, str+RTV_JSON_i-(2+strlen(otr)), strlen(otr)) == 0) \
|
|
|
|
|
RTV_JSON_globina++; \
|
|
|
|
|
} \
|
|
|
|
|
if ( (RTV_JSON_globina > 0 || otr == NULL) \
|
|
|
|
|
if ( ( RTV_JSON_globina > 0 || otr == NULL) \
|
|
|
|
|
&& strncmp(str+RTV_JSON_i, key, strlen(key)) == 0) { \
|
|
|
|
|
RTV_JSON_IZPOLNI(out, fmt, spl, RTV_JSON_VALUE(str, RTV_JSON_i, key)); \
|
|
|
|
|
break; \
|
|
|
|
@ -359,6 +360,8 @@ int rtv_meta_izpolni(struct meta_oddaja * m) {
|
|
|
|
|
FILE * odgstream; |
|
|
|
|
char * odg; |
|
|
|
|
size_t sizeloc; |
|
|
|
|
size_t i; |
|
|
|
|
char * c; |
|
|
|
|
RTV_JSON_INIT(); |
|
|
|
|
snprintf(m->get_meta_url, RTV_API_META_URL_SIZEOF, RTV_API_META_URL, m->id); |
|
|
|
|
snprintf(m->predvajalnik_url, RTV_PREDVAJALNIK_URL_SIZEOF, RTV_PREDVAJALNIK_URL, m->id); |
|
|
|
@ -440,8 +443,44 @@ int rtv_meta_izpolni(struct meta_oddaja * m) {
|
|
|
|
|
RTV_HTTPS_V_HTTP(m->posnetek_url); |
|
|
|
|
goto rtv_meta_izpolni_naselnajboljsistream; |
|
|
|
|
} |
|
|
|
|
/* očitno še nismo našli ustreznega naslova, poskusimo hardcore */ |
|
|
|
|
RTV_NAPISI(INFO, "nisem našel direktnega mp4 URLja, poskušam HLS."); |
|
|
|
|
RTV_JSON(odg, sizeloc, "\"hls\"", m->posnetek_url, s, '"', |
|
|
|
|
"addaptiveMedia"); /* addaptiveMedia je fuckery m3u8 fajlov */ |
|
|
|
|
if (m->posnetek_url[0] == '\0') { |
|
|
|
|
RTV_NAPISI(NAPAKA, "ni uspelo pridobiti HLS URLja."); |
|
|
|
|
returnstatus = 1; |
|
|
|
|
goto rtv_meta_izpolni_returncleanly; |
|
|
|
|
} |
|
|
|
|
/* na mojo srečo je tukaj sicer najboljši stream vedno prvi */ |
|
|
|
|
rewind(odgstream); |
|
|
|
|
fflush(odgstream); |
|
|
|
|
returnstatus = http_get(m->posnetek_url, odgstream); |
|
|
|
|
if (!RTV_HTTP_SUCCESS(returnstatus)) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "zahteva za HLS naslov je spodletela."); |
|
|
|
|
goto rtv_meta_izpolni_returncleanly; |
|
|
|
|
} else returnstatus = 0; |
|
|
|
|
fflush(odgstream); |
|
|
|
|
for (i = 0; i < sizeloc && odg[i] != '\0'; i++) { |
|
|
|
|
if ((i == 0 && odg[i] != '#') |
|
|
|
|
|| (i != 0 && odg[i-1] == '\n' && odg[i] != '#')) { |
|
|
|
|
c = strrchr(m->posnetek_url, '/'); |
|
|
|
|
if (c == NULL) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "napaka na tej vrstici, kontaktiraj razvijalce"); |
|
|
|
|
returnstatus = 1; |
|
|
|
|
goto rtv_meta_izpolni_returncleanly; |
|
|
|
|
} |
|
|
|
|
if (m->posnetek_url_sizeof-1 < /* če ni dovolj prostora */ |
|
|
|
|
((c+(strchrnul(odg+i, '\n')-(odg+i)))-m->posnetek_url)) { |
|
|
|
|
m->posnetek_url_sizeof =
|
|
|
|
|
((c+(strchrnul(odg+i, '\n')-(odg+i)))-m->posnetek_url) + 25; |
|
|
|
|
m->posnetek_url = realloc(m->posnetek_url, m->posnetek_url_sizeof); |
|
|
|
|
} |
|
|
|
|
strncpy(c+1, odg+i, strchrnul(odg+i, '\n')-(odg+i)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
rtv_meta_izpolni_naselnajboljsistream: |
|
|
|
|
|
|
|
|
|
rtv_meta_izpolni_returncleanly: |
|
|
|
|
fclose(odgstream); |
|
|
|
|
free(odg); |
|
|
|
@ -611,7 +650,86 @@ int rtv_zivo_izpolni(struct rtv_zivo_meta * m) {
|
|
|
|
|
return returnstatus; |
|
|
|
|
#pragma GCC diagnostic pop |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int rtv_prenesi_hls (char * url, char * datotecna_predpona) { |
|
|
|
|
int returnstatus; |
|
|
|
|
DIR * dir; |
|
|
|
|
size_t max_kos_fn = strlen("seznam_predvajanja.m3u8"); |
|
|
|
|
char * fn=malloc(sizeof(char)*(strlen(datotecna_predpona)+2+max_kos_fn)); |
|
|
|
|
char * odg; |
|
|
|
|
size_t sizeloc; |
|
|
|
|
FILE * odgstream = open_memstream(&odg, &sizeloc); |
|
|
|
|
size_t kosov = 0; |
|
|
|
|
size_t i = 0; |
|
|
|
|
size_t ti = 0; /* temp in temp intt */ |
|
|
|
|
char ** k /* kosi */ = malloc(sizeof(char *)*1); |
|
|
|
|
FILE * fd = NULL; |
|
|
|
|
FILE * fd2 = NULL; |
|
|
|
|
char * c; |
|
|
|
|
returnstatus = http_get(url, odgstream); /* shranimo m3u8 */ |
|
|
|
|
if (!RTV_HTTP_SUCCESS(returnstatus)) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "ni uspelo prenesti HLS datoteke"); |
|
|
|
|
returnstatus = 1; |
|
|
|
|
goto returncleanly; |
|
|
|
|
} else returnstatus = 0; |
|
|
|
|
fflush(odgstream); |
|
|
|
|
dir = opendir(datotecna_predpona); |
|
|
|
|
if (dir) { |
|
|
|
|
closedir(dir); /* direktorij obstaja, hvala */ |
|
|
|
|
} else if (errno == ENOENT) { |
|
|
|
|
if (mkdir(datotecna_predpona, 0755) != 0) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "med izdelavo direktorija: %s", strerror(errno)); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
RTV_NAPISI(NAPAKA, "med iskanjem direktorija: %s", |
|
|
|
|
strerror(errno)); |
|
|
|
|
returnstatus = 5; |
|
|
|
|
goto returncleanly; |
|
|
|
|
} |
|
|
|
|
for (i = 0; i <= sizeloc && odg[i] != '\0'; i++) { |
|
|
|
|
if (odg[i] == '\n') |
|
|
|
|
odg[i] = '\0'; |
|
|
|
|
if ((i == 0 && odg[i] != '#') |
|
|
|
|
|| (i != 0 && odg[i-1] == '\0' /* == '\n' */ && odg[i] != '#')) { |
|
|
|
|
k = realloc(k, sizeof(char *)*i+2); |
|
|
|
|
k[kosov++] = odg+i; |
|
|
|
|
ti = strlen(odg+i); |
|
|
|
|
if (ti > max_kos_fn) |
|
|
|
|
max_kos_fn = ti; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
sprintf(fn, "%s/seznam_predvajanja.m3u8", datotecna_predpona); |
|
|
|
|
fd2 = fopen(fn, "w"); |
|
|
|
|
fprintf(fd2, "# generiral rtv4d-dl\n"); |
|
|
|
|
fn=realloc(fn,sizeof(char)*(strlen(datotecna_predpona)+1+1+max_kos_fn |
|
|
|
|
+strlen(url))); |
|
|
|
|
for (i = 0; i < kosov; i++) { |
|
|
|
|
c = strchrnul(k[i], '?'); |
|
|
|
|
c[0] = '\0'; |
|
|
|
|
sprintf(fn, "%s/%05lu%s", datotecna_predpona, i, strchrnul(k[i], '.')); |
|
|
|
|
fprintf(fd2, "%05lu%s\n", i, strchrnul(k[i], '.')); |
|
|
|
|
if (c != NULL) |
|
|
|
|
c[0] = '?'; |
|
|
|
|
RTV_NAPISI(HROSC, "prenašam %lu. kos oddaje od %lu v datoteko %s", |
|
|
|
|
i+1, kosov, fn); |
|
|
|
|
fd = fopen(fn, "w"); |
|
|
|
|
strcpy(fn, url); |
|
|
|
|
strcpy(strrchr(fn, '/')+1, k[i]); /* c'mon, url mora imeti / */ |
|
|
|
|
returnstatus = http_get(fn, fd); /* shranimo ts */ |
|
|
|
|
if (!RTV_HTTP_SUCCESS(returnstatus)) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "ni uspelo prenesti TS datoteke"); |
|
|
|
|
returnstatus = 1; |
|
|
|
|
goto returncleanly; |
|
|
|
|
} else returnstatus = 0; |
|
|
|
|
fclose(fd); |
|
|
|
|
} |
|
|
|
|
fflush(fd2); |
|
|
|
|
fclose(fd2); |
|
|
|
|
returncleanly: |
|
|
|
|
fclose(odgstream); |
|
|
|
|
free(odg); |
|
|
|
|
odg = NULL; |
|
|
|
|
return returnstatus; |
|
|
|
|
} |
|
|
|
|
int main (int argc, char ** argv) { |
|
|
|
|
if (argc < 1+1) { |
|
|
|
|
fprintf(stderr, "preberi README.md pred uporabo programa, saj vsebuje " |
|
|
|
@ -667,25 +785,38 @@ int main (int argc, char ** argv) {
|
|
|
|
|
returnstatus = 4; |
|
|
|
|
goto returncleanly; |
|
|
|
|
} |
|
|
|
|
if (argc < 4) { |
|
|
|
|
e = strrchr(m->posnetek_url, '.'); |
|
|
|
|
snprintf(fn, 68, "%u%.4s", m->id, e); |
|
|
|
|
fd = fopen(fn, "w"); |
|
|
|
|
} else { |
|
|
|
|
fd = fopen(argv[3], "w"); |
|
|
|
|
} |
|
|
|
|
if (fd == NULL) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "Ni uspelo odpreti datoteke za pisanje vanjo."); |
|
|
|
|
returnstatus = 5; |
|
|
|
|
goto returncleanly; |
|
|
|
|
} |
|
|
|
|
if (RTV_HTTP_SUCCESS(http_get(m->posnetek_url, fd))) { |
|
|
|
|
fclose(fd); |
|
|
|
|
RTV_NAPISI(INFO, "uspešno shranjeno.");
|
|
|
|
|
if (strstr(m->posnetek_url, ".m3u8") != NULL) { |
|
|
|
|
if (argc < 4) |
|
|
|
|
snprintf(fn, 68, "%u", m->id); |
|
|
|
|
else |
|
|
|
|
strncpy(fn, argv[3], 419); |
|
|
|
|
e = strrchr(fn, '.'); |
|
|
|
|
if (e != NULL) |
|
|
|
|
e[0] = '\0'; |
|
|
|
|
if (rtv_prenesi_hls(m->posnetek_url, fn) != 0) |
|
|
|
|
RTV_NAPISI(NAPAKA, "nisem uspel narediti HLS prenosa."); |
|
|
|
|
RTV_NAPISI(INFO, "uspešno prenesel oddajo v mapo po kosih."); |
|
|
|
|
} else { |
|
|
|
|
fclose(fd); |
|
|
|
|
RTV_NAPISI(NAPAKA, "Nekaj je spodletelo pri http_get()"); |
|
|
|
|
returnstatus = 6; |
|
|
|
|
if (argc < 4) { |
|
|
|
|
e = strrchr(m->posnetek_url, '.'); |
|
|
|
|
snprintf(fn, 68, "%u%.4s", m->id, e); |
|
|
|
|
fd = fopen(fn, "w"); |
|
|
|
|
} else { |
|
|
|
|
fd = fopen(argv[3], "w"); |
|
|
|
|
} |
|
|
|
|
if (fd == NULL) { |
|
|
|
|
RTV_NAPISI(NAPAKA, "Ni uspelo odpreti datoteke za pisanje vanjo."); |
|
|
|
|
returnstatus = 5; |
|
|
|
|
goto returncleanly; |
|
|
|
|
} |
|
|
|
|
if (RTV_HTTP_SUCCESS(http_get(m->posnetek_url, fd))) { |
|
|
|
|
fclose(fd); |
|
|
|
|
RTV_NAPISI(INFO, "uspešno shranjeno.");
|
|
|
|
|
} else { |
|
|
|
|
fclose(fd); |
|
|
|
|
RTV_NAPISI(NAPAKA, "Nekaj je spodletelo pri http_get()"); |
|
|
|
|
returnstatus = 6; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 'M': |
|
|
|
|