ref: b7306bef352fc0796d84a5ef0bd5a301629adfe9
dir: /peertube.c/
#include <u.h> #include <libc.h> #include <json.h> #include "nvi.h" static int addfmt(Info *i, JSON *f) { JSON *x, *j; Format *fmt; char *s, *t; JSONEl *e; int fd, n; j = nil; if((x = jfield(f, JSONString, "metadataUrl", nil)) == nil){ werrstr("no metadataUrl"); goto err; } j = nil; if((fd = hget(jsonstr(x), -1)) >= 0){ if((s = readall(fd)) != nil){ j = jsonparse(s); free(s); } close(fd); } procwait(); if(j == nil) goto err; if((x = jfield(f, JSONString, "fileDownloadUrl", nil)) == nil){ werrstr("no fileDownloadUrl"); goto err; } i->nfmt++; if((i->fmt = realloc(i->fmt, i->nfmt * sizeof(*fmt))) == nil) sysfatal("memory"); fmt = &i->fmt[i->nfmt - 1]; memset(fmt, 0, sizeof(*fmt)); fmt->url = estrdup(jsonstr(x)); if((x = jsonbyname(f, "size")) != nil) fmt->sz = x->n; s = strdup(""); if((x = jfield(j, JSONArray, "streams", nil)) != nil){ for(e = x->first; e != nil; e = e->next){ if((x = jfield(e->val, JSONString, "codec_name", nil)) != nil){ t = smprint("%s%s%s", s, *s ? "," : "", jsonstr(x)); free(s); s = t; } if((x = jfield(e->val, JSONString, "codec_type", nil)) != nil){ t = jsonstr(x); if(strcmp(t, "video") == 0) fmt->included |= Ivideo; else if(strcmp(t, "audio") == 0){ fmt->included |= Iaudio; if((n = jint(e->val, "sample_rate")) != 0){ t = smprint("%s,rate=%d", s, n); free(s); s = t; } if((n = jint(e->val, "channels")) != 0){ t = smprint("%s,channels=%d", s, n); free(s); s = t; } } }else{ werrstr("codec_type missing"); goto err; } } } fmt->type = s; jsonfree(j); if((x = jfield(f, JSONObject, "resolution", nil)) != nil){ fmt->id = jint(x, "id"); if((s = jsonstr(jfield(x, JSONString, "label", nil))) != nil && *s != '0') fmt->quality = jstrdup(x, "label"); } return 0; err: werrstr("addfmt: %r"); jsonfree(j); return -1; } Info * peertube(char *url) { int fd, peertube; char *s, *o, *id; JSONEl *e, *f; JSON *j, *z; Info *i; peertube = 0; i = nil; if((fd = hget(url, -1)) >= 0){ if((s = readall(fd)) != nil){ if((o = strstr(s, "property=\"og:platform\"")) != nil && strstr(o+23, "content=\"PeerTube\"") != nil) peertube = 1; free(s); } close(fd); } procwait(); if(!peertube){ if(fd >= 0) werrstr("not peertube"); return nil; } if((id = strrchr(url, '/')) == nil || (s = strstr(url, "://")) == nil || (s = strchr(s+3, '/')) == nil){ werrstr("bad url"); return nil; } url = smprint("%.*s/api/v1/videos%s", (int)(s-url), url, id); fd = hget(url, -1); free(url); j = nil; if(fd >= 0){ if((s = readall(fd)) != nil){ j = jsonparse(s); free(s); } close(fd); } procwait(); if(j == nil) goto err; if((i = calloc(1, sizeof(*i))) == nil) sysfatal("memory"); i->author = estrdup(jsonstr(jfield(j, JSONString, "account", "displayName", nil))); i->title = jstrdup(j, "name"); i->description = jstrdup(j, "description"); i->duration = jint(j, "duration"); if((s = jsonstr(jsonbyname(j, "publishedAt"))) != nil) tmparse(&i->published, "YYYY-MM-DDThh:mm:ss.ttt", s, nil, nil); if((z = jfield(j, JSONArray, "files", nil)) != nil){ for(f = z->first; f != nil; f = f->next){ if(addfmt(i, f->val) != 0) goto err; } } if((z = jfield(j, JSONArray, "streamingPlaylists", nil)) != nil){ for(e = z->first; e != nil; e = e->next){ if((z = jfield(e->val, JSONArray, "files", nil)) != nil){ for(f = z->first; f != nil; f = f->next){ if(addfmt(i, f->val) != 0) goto err; } } } } jsonfree(j); return i; err: werrstr("peertube: %r"); free(i); return nil; }