summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsijanec <anton@sijanec.eu>2021-01-30 01:09:56 +0100
committersijanec <anton@sijanec.eu>2021-01-30 01:09:56 +0100
commitb0b02f0cb2e1276ff7638d082a7f3b50d03d69e0 (patch)
tree77c1e40dbef8aa2111ae537e5e7d9fc3190fe58c
parent0.1.1-6: lahko no. (diff)
downloadrtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.tar
rtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.tar.gz
rtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.tar.bz2
rtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.tar.lz
rtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.tar.xz
rtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.tar.zst
rtv4d-dl-b0b02f0cb2e1276ff7638d082a7f3b50d03d69e0.zip
-rw-r--r--README.md11
-rw-r--r--rtv4d-dl.c177
-rw-r--r--tcp.c2
3 files changed, 163 insertions, 27 deletions
diff --git a/README.md b/README.md
index 3c18daa..8d1012f 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ namestitev prek upravitelja paketov `apt`.
```
wget https://sijanec.eu/pgp-key.txt -qO- | sudo apt-key add -
-sudo apt-add-repository https://prog.sijanec.eu/ppa
+sudo echo deb http://prog.sijanec.eu/ $(lsb_release -sc) main \>\> /etc/apt/sources.list
sudo apt update
sudo apt install rtv4d-dl
```
@@ -59,10 +59,14 @@ z uporabo programa se strinjate z naslednjimi stavki:
* program se poveže na \*.rtvslo.si, spremenite izvorno kodo za drugo
infrastrukturo
* **živo**: za možne programe in razlago dolžine glej *dodatno o prenosu v živo*
+* če RTV strežnik ne ponuja enotne .mp4 datoteke za oddajo ampak zgolj HLS, se
+ bo oddaja shranila kot kosi prenosa v živo (datoteka.mp4 => datoteka/....m3u8)
+ - take datoteke lahko kasneje združite z ukazom
+ `cat datoteka/*.ts | ffmpeg -i - -c:v copy -c:a copy datoteka.mp4`
# trenutna izdaja programa:
-* program je bil nazadnje ročno testiran 11. januarja 2021 in takrat je DELOVAL.
-* različica: 0.1.1
+* program je bil nazadnje ročno testiran 29. januarja 2021 in takrat je DELOVAL.
+* različica: 0.1.2
## dnevnik sprememb:
* 0.0.2 - 13. december 2020: sedaj pravilno naloži samo največjo kvaliteto, pred
@@ -77,6 +81,7 @@ z uporabo programa se strinjate z naslednjimi stavki:
izogne, ne bom več gradil okenskih datotek
* 0.1.0 - 11. januar 2021: paket za debian/ubuntu
* 0.1.1 - 11. januar 2021: standardizacija Makefile
+* 0.1.2 - 29. januar 2021: dodano nalaganje geoblokiranih datotek prek HLS
# o
* program je spisan 100% v C programskem jeziku
diff --git a/rtv4d-dl.c b/rtv4d-dl.c
index 460f3d5..f54e9ec 100644
--- a/rtv4d-dl.c
+++ b/rtv4d-dl.c
@@ -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':
diff --git a/tcp.c b/tcp.c
index 1265a58..a1b0ed4 100644
--- a/tcp.c
+++ b/tcp.c
@@ -13,7 +13,7 @@
#include <string.h>
#include <sys/time.h>
#define ERR_INET_ADDR "0.9.9.0"
-#define TCPC_READ_BUF 1048576 /* en megabajt */
+#define TCPC_READ_BUF 1024 /* en kilobajt */
#define TCPC_RESOLVE_RETRIES 12
union ip_conv {
unsigned char c[4];