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,
+};
--
⑨