Browse Source

rtv4d-dl 0.1.2

master 0.1.2
Anton Luka Šijanec 10 months ago
parent
commit
b0b02f0cb2
  1. 11
      README.md
  2. 177
      rtv4d-dl.c
  3. 2
      tcp.c

11
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

177
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':

2
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];

Loading…
Cancel
Save

Med zimskimi počitnicami so pričakovani občasni izpadi podomrežja O, ker bodo izvajana testiranja varnosti komunikacijsko-informacijske opreme.