ref: 53cbe4d7f606040ea5cec9669524582b6c6f2526
parent: 3ca28bcf70c149cfefa97adb810ba4da2420023a
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Mar 2 05:22:42 EST 2021
added stream_sub.c
--- /dev/null
+++ b/stream_sub.c
@@ -1,0 +1,130 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ctype.h>
+#include "misc.h"
+#include "stream.h"
+
+extern Streamops subops;
+
+int
+subopenfd(int fd, Stream *s, int *failed)
+{
+ if(fd < 0)
+ return -1;
+
+ s->type = Ssubtitles;
+ s->timebase.denum = 1;
+ s->timebase.num = 1;
+ s->b = Bfdopen(fd, OREAD);
+ memmove(&s->ops, &subops, sizeof(subops));
+ *failed = 0;
+
+ return 0;
+}
+
+Stream *
+subopen(char *path, int *num, int *failed)
+{
+ Stream *s;
+
+ if((s = calloc(1, sizeof(*s))) == nil){
+ *failed = 1;
+ return nil;
+ }
+
+ *num = 1;
+ if(subopenfd(open(path, OREAD), s, failed) != 0){
+ free(s);
+ s = nil;
+ }
+
+ return s;
+}
+
+static int
+subts2ns(char *s, char **e, uvlong *ns)
+{
+ if(strlen(s) < 9){
+ werrstr("timestamp too short");
+ goto err;
+ }
+ *ns = 0;
+ s--;
+ do{
+ s++;
+ *ns *= 60;
+ *ns += strtod(s, &s)*1000000000.0;
+ if(*s == ','){
+ *ns += strtod(s+1, &s)*1000000.0;
+ break;
+ }
+ }while(*s == ':');
+
+ *e = s;
+
+ return 0;
+err:
+ werrstr("subts2ns: %r");
+ return -1;
+}
+
+static int
+subread(Stream *s, Streamframe *f)
+{
+ uvlong end;
+ char *x;
+ int i, n;
+
+ Brdline(s->b, '\n'); /* index */
+ if((x = Brdline(s->b, '\n')) == nil){ /* timestamp */
+ f->sz = 0;
+ return 0;
+ }
+ if((n = Blinelen(s->b)) < 1){
+ werrstr("unexpected empty line");
+ goto err;
+ }
+ x[n-1] = 0;
+ if(subts2ns(x, &x, &f->timestamp) != 0)
+ goto err;
+ while(isspace(*x))
+ x++;
+ if(strncmp(x, "-->", 3) != 0){
+ werrstr("no timestamp delimeter: %s", x);
+ goto err;
+ }
+ x += 3;
+ if(subts2ns(x, &x, &end) != 0)
+ goto err;
+ f->dt = end - f->timestamp;
+
+ for(i = 0; i < nelem(f->lines); i++){
+ if((x = Brdstr(s->b, '\n', 1)) == nil || *x == 0){
+ free(x);
+ break;
+ }
+ f->lines[i] = x;
+ }
+ f->nlines = i;
+
+ s->timestamp = f->timestamp;
+
+ return 0;
+err:
+ werrstr("subread: %r");
+ return -1;
+}
+
+static void
+subclose(Stream *s)
+{
+ Bterm(s->b);
+ free(s->buf);
+}
+
+Streamops subops = {
+ .open = subopen,
+ .read = subread,
+ .close = subclose,
+};