- `SRT` fichiers sous-titres SubRip, ils accompagnent en général des films
- `WebVTT` Web Video Text Tracks, un nouveau standard W3C
-Note : ce programme ne peut pas encore ouvrir des fichiers WebVTT (il supporte toutefois les 3 formats en écriture)
-
## Options
- **--help** (or **-h**) : information sur la syntaxe du programme
- `SRT` SubRip subtitle files, usually distributed with films
- `WebVTT` Web Video Text Tracks, a new W3C standard
-Note: this program can not yet open WebVTT files (it supports all 3 formats as output, though)
-
## Options
- **--help** (or **-h**): information about the syntax
case NSUB_FMT_SRT:
read_a_line = nsub_read_srt;
break;
+ case NSUB_FMT_WEBVTT:
+ read_a_line = nsub_read_webvtt;
+ break;
default:
fprintf(stderr, "Unsupported read format %d\n", fmt);
goto fail;
return 0;
}
}
+
+int nsub_to_ms(const char line[], char deci_sym) {
+ // 00:00:17,400
+
+ /* should not happen! */
+ /* note: also, we assume max 3 decimal digits */
+ if (!nsub_is_timing(line, deci_sym, 3)) {
+ fprintf(stderr,
+ "Warning: called nsub_to_ms with bad input [%s], ignoring...\n",
+ line);
+ return 0;
+ }
+
+ int mults[] = { 1, 1000, 60000, 3600000 };
+
+ int group[4] = { 0, 0, 0, 0 };
+ int igroup = -1;
+
+ char mtmp[3] = { 1, 10, 100 };
+ int itmp = 0;
+
+ int has_milli = 0;
+
+ size_t end = strlen(line) - 1;
+
+ for (size_t i = end; i >= 0; i--) {
+ char car = line[i];
+
+ int digit = (car >= '0' && car <= '9');
+ int dot = car == deci_sym;
+ int col = (car == ':');
+
+ if (!digit && !dot && !col) {
+ break;
+ }
+
+ if (digit) {
+ if (itmp == 0)
+ igroup++;
+
+ group[igroup] += mtmp[itmp] * (car - (int) '0');
+ itmp++;
+ } else {
+ if (dot)
+ has_milli = 1;
+
+ itmp = 0;
+ }
+ }
+
+ int total = 0;
+ int multOffset = (has_milli ? 0 : 1);
+ for (int i = 0; i <= igroup; i++) {
+ total += mults[i + multOffset] * group[i];
+ }
+
+ return total;
+}
+
+int nsub_is_timing(const char line[], char deci_sym, int max_deci) {
+ // 00:00:14,800
+
+ int digits = 0;
+ int groups = 0;
+ int sep = 0;
+
+ int max_digits = 2;
+ int max_groups = 3;
+
+ for (char *ptr = (char *) line; *ptr; ptr++) {
+ int digit = (*ptr >= '0' && *ptr <= '9');
+ int col = (*ptr == ':');
+ int dot = *ptr == deci_sym;
+
+ if (digit) {
+ digits++;
+ } else if (col) {
+ digits = 0;
+ groups++;
+ } else if (dot) {
+ digits = 0;
+ max_digits = max_deci;
+ sep++;
+ } else {
+ return 0;
+ }
+
+ if (digits > max_digits)
+ return 0;
+ if (groups > max_groups)
+ return 0;
+ if (sep > 1)
+ return 0;
+ }
+
+ return 1;
+}
/* Read */
+/**
+ * Convert a text line into milliseconds (for instance, 00:00:17,400).
+ * Text <b>must</b> be conform, though less groups or less digits per group
+ * is allowed.
+ *
+ * @note maximum number of groups: 4,
+ * maximum number of digits per
+ * group: 2 except decimal group which is allowed up to 3
+ *
+ * @param line the line to convert
+ * @param deci_sep the decimal separator symbol (usually '.' or ',')
+ * @param max_deci maximum number of digits for the decimal value (max is 3)
+ *
+ * @return the number of milliseconds it means
+ */
+int nsub_to_ms(const char line[], char deci_sym);
+
+/**
+ * Validate that the given line is a timing (for instance, 00:00:17,400).
+ * Text <b>must</b> be conform, though less groups or less digits per group
+ * is allowed.
+ *
+ * @note maximum number of groups: 4,
+ * maximum number of digits per
+ * group: 2 except decimal group which is allowed up to 3
+ *
+ * @param line the line to check
+ * @param deci_sep the decimal separator symbol (usually '.' or ',')
+ * @param max_deci maximum number of digits for the decimal value
+ *
+ * @return TRUE if it is
+ */
+int nsub_is_timing(const char line[], char deci_sym, int max_deci);
+
song_t *nsub_read(FILE *in, NSUB_FORMAT fmt);
int nsub_read_lrc(song_t *song, char *line);
int nsub_read_webvtt(song_t *song, char *line);
/* Declarations */
// test if this is an offset line
-int is_lrc_offset(char *line);
+static int is_lrc_offset(char *line);
// test if it is a timed lyric
-int is_lrc_lyric(char *line, int*end);
+static int is_lrc_lyric(char *line, int*end);
// test if this is a meta line
-int is_lrc_meta(char *line, int *colon, int *end);
+static int is_lrc_meta(char *line, int *colon, int *end);
// count the ms in the line "[(00:0)0:14.80]" or "[offset: +0:12]"
-int lrc_millisec(char *line);
+static int lrc_millisec(char *line);
/* Public */
/* Private */
-int is_lrc_offset(char *line) {
- const char offset[] = { "[offset" };
- int i = 0;
- while (line[i] && offset[i] && line[i] == offset[i])
- i++;
+static int is_lrc_offset(char *line) {
+ // [offset: +0:12]
- if (!offset[i]) {
- while (line[i] == ' ')
- i++;
+ // skip spaces
+ while (*line == ' ')
+ line++;
- if (line[i] == ':')
- return 1;
+ // skip [offset
+ char *offset = { "[offset" };
+ while (*line && *offset && *offset == *line) {
+ line++;
+ offset++;
}
+ if (*offset)
+ return 0;
- return 0;
-}
+ // skip spaces then ':'
+ while (*line == ' ')
+ line++;
+ if (*line && *line != ':')
+ return 0;
+ line++;
-int is_lrc_lyric(char *line, int *end) {
- if (line[0] != '[')
+ // allow sign
+ if (*line == '-' || *line == '+')
+ line++;
+ while (*line == ' ')
+ line++;
+
+ // find end
+ int i = 0;
+ while (line[i] && line[i] != ']')
+ i++;
+ if (line[i] != ']')
return 0;
- *end = 0;
+ // validate timing
+ cstring_t*tmp = cstring_substring(line, 0, i);
+ int ok = nsub_is_timing(tmp->string, '.', 2);
+ free_cstring(tmp);
+ return ok;
+}
- for (int i = 1; line[i]; i++) {
- char car = line[i];
+static int is_lrc_lyric(char *line, int *end) {
+ // "[(00:0)0:14.80] bla bla bla"
- if (car == ']') {
- *end = i;
- return i >= 2;
- }
+ *end = 0;
- int digit = (car >= '0' && car <= '9');
- int sep = (car == ':' || car == '.' || car == ' ');
+ // skip spaces
+ while (*line == ' ')
+ line++;
- if (!digit && !sep)
- break;
- }
+ // skip [
+ if (*line != '[')
+ return 0;
+ line++;
+
+ // find end
+ int i = 0;
+ while (line[i] && line[i] != ']')
+ i++;
+ if (line[i] != ']')
+ return 0;
+ *end = i;
- return 0;
+ // validate timing
+ cstring_t*tmp = cstring_substring(line, 0, i);
+ int ok = nsub_is_timing(tmp->string, '.', 2);
+ free_cstring(tmp);
+ return ok;
}
-int is_lrc_meta(char *line, int *colon, int *end) {
+static int is_lrc_meta(char *line, int *colon, int *end) {
if (line[0] != '[')
return 0;
return (*colon) && (*end);
}
-int lrc_millisec(char *line) {
- int mults[] = { 1000, 10000, 60000, 600000, 3600000, 36000000 };
+static int lrc_millisec(char *line) {
+ // count the ms in the line "[(00:0)0:14.80]" or "[offset: +0:12]"
- size_t end = 0;
- for (size_t i = 0; line[i]; i++) {
- if (line[i] == ']') {
- end = i - 1;
- break;
- }
- }
-
- int total = 0;
- for (size_t i = end; i >= 0; i--) {
- char car = line[i];
-
- int digit = (car >= '0' && car <= '9');
- int sign = (car == '-' || car == '+');
- int dot = car == '.';
- int col = (car == ':');
+ int sign = 1;
+ int dummy = 0;
- if (!digit && !sign && !dot && !col) {
- break;
- }
-
- if (dot) {
- int mult = 1;
-
- int j = i + 3;
- while (j > end) {
- mult *= 10;
- j--;
- }
-
- for (; j > i; j--) {
- total += mult * ((int) line[j] - (int) '0');
- mult *= 10;
- }
+ // skip spaces
+ while (*line == ' ')
+ line++;
- end = i - 1;
- break;
+ if (is_lrc_lyric(line, &dummy)) {
+ // skip [
+ line++;
+ } else if (is_lrc_offset(line)) {
+ // skip [offset:
+ while (*line != ':')
+ line++;
+ while (*line == ' ')
+ line++;
+
+ // allow sign
+ if (*line == '+') {
+ line++;
+ } else if (*line == '-') {
+ line++;
+ sign = -1;
}
+ while (*line == ' ')
+ line++;
+ } else {
+ /* should not happen! */
+ fprintf(stderr,
+ "Warning: called lrc_millisec with bad input [%s], ignoring...\n",
+ line);
+ return 0;
}
- int imult = 0;
- for (size_t i = end; 1; i--) {
- char car = line[i];
- int digit = (car >= '0' && car <= '9');
-
- if (digit)
- total += (car - '0') * mults[imult++];
-
- if (car == '-')
- total = -total;
-
- if (i == 0)
- break;
- }
+ // find end
+ int i = 0;
+ while (line[i] != ']')
+ i++;
- return total;
+ cstring_t*tmp = cstring_substring(line, 0, i);
+ int ms = nsub_to_ms(tmp->string, '.');
+ free_cstring(tmp);
+ return sign * ms;
}
/* Declarations */
-static int is_srt_id(const char line[]);
-static int is_srt_timing(const char line[]);
-static int get_start(const char line[]);
-static int get_stop(const char line[]);
-static int to_ms(const char line[]);
+static int is_srt_id(char *line);
+static int is_srt_timing(char *line);
+static int get_start(char *line);
+static int get_stop(char *line);
int nsub_read_srt(song_t *song, char *line) {
int empty = 1;
if (is_srt_id(line)) {
int new_count = atoi(line);
-
if (new_count != count + 1) {
fprintf(stderr,
- "Warning: line %zu is out of order (it is numbered %i), ignoring order...",
+ "Warning: line %zu is out of order (it is numbered %i), ignoring order...\n",
count, new_count);
}
song_add_lyric(song, 0, 0, NULL, NULL);
} else if (is_srt_timing(line)) {
+ // no headers in srt
if (!lyric) {
return 0;
}
char *text = lyric->text;
if (text)
- text = cstring_concat(text, "\n", line);
+ text = cstring_concat(text, "\n", line, NULL);
else
text = strdup(line);
/* Private */
-static int is_srt_id(const char line[]) {
+static int is_srt_id(char *line) {
for (char *ptr = (char *) line; *ptr; ptr++) {
switch (*ptr) {
case '0':
return 1;
}
-static int is_srt_timing(const char line[]) {
+static int is_srt_timing(char *line) {
// Canonical example:
- // 00:00:14,800 --> 00:00:17,400
-
- int vals = 0;
- int vals_groups = 0;
- int sep = 0;
- int deci = 0;
-
- for (char *ptr = (char *) line; *ptr; ptr++) {
- switch (*ptr) {
- case ' ': // ignore space if not in sep
- if (sep && sep < 2)
- return 0;
- break;
-
- case '0': // count a new numeric
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- vals++;
- break;
-
- case ',': // we just did a group
- case ':':
- if (*ptr == ',')
- deci = 1;
-
- if (vals < 1 || vals > 2)
- return 0;
-
- vals = 0;
- vals_groups++;
- break;
+ // 00:00:14,800 --> 00:00:17,400 align: center
- case '-': // Separator (-->)
- if (!sep) {
- vals_groups++;
+ cstring_t *tmp;
+ int ok;
+ int i;
- if (vals < 1 || (vals > 2 && !deci) || vals > 3)
- return 0;
+ // skip spaces
+ while (*line == ' ')
+ line++;
- if (vals_groups < 1 || (vals_groups > 3 && !deci)
- || vals_groups > 4)
- return 0;
-
- vals = 0;
- vals_groups = 0;
- deci = 0;
- }
+ // check part 1
+ i = 0;
+ while (line[i] && line[i] != ' ' && line[i] != '-')
+ i++;
+ if (line[i] != ' ' && line[i] != '-')
+ return 0;
+ tmp = cstring_substring(line, 0, i);
+ ok = nsub_is_timing(tmp->string, ',', 3);
+ free_cstring(tmp);
+ if (!ok)
+ return 0;
- if (sep > 2)
- return 0;
+ // skip part 1
+ line += i;
- sep++;
- break;
+ // skip spaces
+ while (*line == ' ')
+ line++;
- case '>': // Separator (-->)
- if (sep != 2)
- return 0;
-
- sep++;
- break;
- }
+ // skip -->
+ char *arrow = { "-->" };
+ while (*line && *arrow && *arrow == *line) {
+ line++;
+ arrow++;
}
-
- if (vals < 1 || (vals > 2 && !deci) || vals > 3)
+ if (*arrow)
return 0;
- if (vals_groups < 1 || (vals_groups > 3 && !deci) || vals_groups > 4)
- return 0;
+ // skip spaces
+ while (*line == ' ')
+ line++;
- if (sep != 3)
- return 0;
+ // find end
+ i = 0;
+ while (line[i] && line[i] != ' ')
+ i++;
- return 1;
+ // validate part 2
+ tmp = cstring_substring(line, 0, i);
+ ok = nsub_is_timing(tmp->string, ',', 3);
+ free_cstring(tmp);
+ return !!ok;
}
-static int get_start(const char line[]) {
- char *ptr = (char *) line;
- while (*ptr == ' ')
- ptr++;
+static int get_start(char *line) {
+ // 00:00:14,800 --> 00:00:17,400 align: center
- size_t i;
- for (i = 0; ptr[i] != ' ' && ptr[i] != '-'; i++)
- ;
+ if (!is_srt_timing(line)) {
+ /* should not happen! */
+ fprintf(stderr,
+ "Warning: called get_start with bad input [%s], ignoring...\n",
+ line);
+ return 0;
+ }
- cstring_t*start = cstring_substring(ptr, 0, i);
- int ms = to_ms(start->string);
- free_cstring(start);
- return ms;
-}
+ // skip spaces
+ while (*line == ' ')
+ line++;
-static int get_stop(const char line[]) {
- char *ptr = (char *) line;
- while (*ptr != '>')
- ptr++;
- ptr++;
- while (*ptr == ' ')
- ptr++;
+ // find end
+ int i = 0;
+ while (line[i] && line[i] != ' ' && line[i] != '-')
+ i++;
- return to_ms(ptr);
+ cstring_t*start = cstring_substring(line, 0, i);
+ int ms = nsub_to_ms(start->string, ',');
+ free_cstring(start);
+ return ms;
}
-static int to_ms(const char line[]) {
- // 00:00:17,400
-
- int mults[] = { 1, 1000, 60000, 3600000 };
-
- int group[4] = { 0, 0, 0, 0 };
- int igroup = -1;
-
- char mtmp[3] = { 1, 10, 100 };
- int itmp = 0;
+static int get_stop(char *line) {
+ // 00:00:14,800 --> 00:00:17,400 align: center
- int has_milli = 0;
-
- size_t end = strlen(line) - 1;
-
- for (size_t i = end; i >= 0; i--) {
- char car = line[i];
-
- int digit = (car >= '0' && car <= '9');
- int dot = car == ',';
- int col = (car == ':');
-
- if (!digit && !dot && !col) {
- break;
- }
-
- if (digit) {
- if (itmp == 0)
- igroup++;
+ if (!is_srt_timing(line)) {
+ /* should not happen! */
+ fprintf(stderr,
+ "Warning: called get_stop with bad input [%s], ignoring...\n",
+ line);
+ return 0;
+ }
- group[igroup] += mtmp[itmp] * (car - (int) '0');
- itmp++;
- } else {
- if (dot)
- has_milli = 1;
+ // skip to >
+ while (*line != '>')
+ line++;
+ line++;
- itmp = 0;
- }
- }
+ // skip spaces
+ while (*line == ' ')
+ line++;
- int total = 0;
- int multOffset = (has_milli ? 0 : 1);
- for (int i = 0; i <= igroup; i++) {
- total += mults[i + multOffset] * group[i];
- }
+ // find end
+ int i = 0;
+ while (line[i] && line[i] != ' ')
+ i++;
- return total;
+ cstring_t*end = cstring_substring(line, 0, i);
+ int ms = nsub_to_ms(end->string, ',');
+ free_cstring(end);
+ return ms;
}
--- /dev/null
+/*
+ * NSub: Subtitle/Lyrics conversion program (webvtt/srt/lrc)
+ *
+ * Copyright (C) 2022 Niki Roo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "nsub.h"
+#include "utils/utils.h"
+
+/* Declarations */
+
+static int is_srt_id(char *line);
+static int is_srt_timing(char *line);
+static int get_start(char *line);
+static int get_stop(char *line);
+
+int nsub_read_webvtt(song_t *song, char *line) {
+ int empty = 1;
+ for (int i = 0; empty && line[i]; i++) {
+ if (line[i] != ' ')
+ empty = 0;
+ }
+
+ if (empty)
+ return 1;
+
+ size_t count = array_count(song->lyrics);
+ lyric_t *lyric = NULL;
+ if (count)
+ lyric = array_get(song->lyrics, array_count(song->lyrics) - 1);
+
+ if (is_srt_id(line)) {
+ int new_count = atoi(line);
+ if (new_count != count + 1) {
+ fprintf(stderr,
+ "Warning: line %zu is out of order (it is numbered %i), ignoring order...\n",
+ count, new_count);
+ }
+ } else if (is_srt_timing(line)) {
+ song_add_lyric(song, 0, 0, NULL, NULL);
+ lyric = array_get(song->lyrics, array_count(song->lyrics) - 1);
+
+ lyric->start = get_start(line);
+ lyric->stop = get_stop(line);
+ } else {
+ // a header has been found
+ if (!lyric) {
+ return 1;
+ }
+
+ char *text = lyric->text;
+ if (text)
+ text = cstring_concat(text, "\n", line, NULL);
+ else
+ text = strdup(line);
+
+ free(lyric->text);
+ lyric->text = text;
+ }
+
+ return 1;
+}
+
+/* Private */
+
+static int is_srt_id(char *line) {
+ for (char *ptr = (char *) line; *ptr; ptr++) {
+ int digit = (*ptr >= '0' && *ptr <= '9');
+ int space = (*ptr == ' ');
+
+ if (!digit && !space)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int is_srt_timing(char *line) {
+ // Canonical example:
+ // 00:00:14.800 --> 00:00:17.400 align: center
+
+ cstring_t *tmp;
+ int ok;
+ int i;
+
+ // skip spaces
+ while (*line == ' ')
+ line++;
+
+ // check part 1
+ i = 0;
+ while (line[i] && line[i] != ' ' && line[i] != '-')
+ i++;
+ if (!line[i])
+ return 0;
+ tmp = cstring_substring(line, 0, i);
+ ok = nsub_is_timing(tmp->string, '.', 3);
+ free_cstring(tmp);
+ if (!ok)
+ return 0;
+
+ // skip part 1
+ line += i;
+
+ // skip spaces
+ while (*line == ' ')
+ line++;
+
+ // skip -->
+ char *arrow = { "-->" };
+ while (*line && *arrow && *arrow == *line) {
+ line++;
+ arrow++;
+ }
+ if (*arrow)
+ return 0;
+
+ // skip spaces
+ while (*line == ' ')
+ line++;
+
+ // find end
+ i = 0;
+ while (line[i] && line[i] != ' ')
+ i++;
+
+ // validate part 2
+ tmp = cstring_substring(line, 0, i);
+ ok = nsub_is_timing(tmp->string, '.', 3);
+ free_cstring(tmp);
+ return !!ok;
+}
+
+static int get_start(char *line) {
+ // 00:00:14,800 --> 00:00:17,400 align: center
+
+ if (!is_srt_timing(line)) {
+ /* should not happen! */
+ fprintf(stderr,
+ "Warning: called get_start with bad input [%s], ignoring...\n",
+ line);
+ return 0;
+ }
+
+ // skip spaces
+ while (*line == ' ')
+ line++;
+
+ // find end
+ int i = 0;
+ while (line[i] && line[i] != ' ' && line[i] != '-')
+ i++;
+
+ cstring_t*start = cstring_substring(line, 0, i);
+ int ms = nsub_to_ms(start->string, '.');
+ free_cstring(start);
+ return ms;
+}
+
+static int get_stop(char *line) {
+ // 00:00:14,800 --> 00:00:17,400 align: center
+
+ if (!is_srt_timing(line)) {
+ /* should not happen! */
+ fprintf(stderr,
+ "Warning: called get_stop with bad input [%s], ignoring...\n",
+ line);
+ return 0;
+ }
+
+ // skip to >
+ while (*line != '>')
+ line++;
+ line++;
+
+ // skip spaces
+ while (*line == ' ')
+ line++;
+
+ // find end
+ int i = 0;
+ while (line[i] && line[i] != ' ')
+ i++;
+
+ cstring_t*end = cstring_substring(line, 0, i);
+ int ms = nsub_to_ms(end->string, '.');
+ free_cstring(end);
+ return ms;
+}
#include <stdio.h>
#include "nsub.h"
+#include "utils/utils.h"
/* Declarations */
}
if (lyric->type == NSUB_COMMENT || lyric->type == NSUB_UNKNOWN) {
- fprintf(out, "-- %s\n", lyric->text);
+ cstring_t *tmp = cstring_clone(lyric->text);
+ if (tmp) {
+ cstring_replace(tmp, "\n", "\\n");
+ }
+
+ fprintf(out, "-- %s\n", tmp->string);
lrc_last_stop = 0;
+
+ free_cstring(tmp);
return;
}
- if (lyric->name)
- fprintf(out, "-- %s\n", lyric->name);
+ if (lyric->name) {
+ cstring_t *tmp = cstring_clone(lyric->name);
+ if (tmp) {
+ cstring_replace(tmp, "\n", "\\n");
+ }
+
+ fprintf(out, "-- %s\n", tmp->string);
+
+ free_cstring(tmp);
+ }
char *time = nsub_lrc_time_str(lyric->start + offset, 0);
- fprintf(out, "[%s] %s\n", time, lyric->text);
+ cstring_t *tmp = cstring_clone(lyric->text);
+ if (tmp) {
+ cstring_replace(tmp, "\n", "\\n");
+ }
+ fprintf(out, "[%s] %s\n", time, tmp->string);
free(time);
+ free_cstring(tmp);
lrc_last_stop = lyric->stop + offset;
}
#include <stdio.h>
#include "nsub.h"
+#include "utils/utils.h"
/* Declarations */
return;
}
+ // Num is mandatory for srt
+ fprintf(out, "%d\n", lyric->num);
+
//if (lyric->name)
// not supported, ignored
char *start = nsub_srt_time_str(lyric->start + offset, 0);
char *stop = nsub_srt_time_str(lyric->stop + offset, 0);
- fprintf(out, "%d\n%s --> %s\n%s\n\n", lyric->num, start, stop, lyric->text);
+ fprintf(out, "%s --> %s\n%s\n\n", start, stop, lyric->text);
free(start);
free(stop);
}
// metas
array_loop(song->metas, meta, meta_t)
{
- fprintf(out, "NOTE META %s: %s\n\n", meta->key, meta->value);
+ // Not always supported by clients, so disabled:
+ //fprintf(out, "NOTE META %s: %s\n\n", meta->key, meta->value);
}
// offset is not supported in WebVTT (so, always applied)
// other metas
{
- fprintf(out,
- "NOTE META created by: nsub (https://github.com/nikiroo/nsub)]\n");
+ // Not always supported by clients, so disabled:
+ //fprintf(out,
+ // "NOTE META created by: nsub (https://github.com/nikiroo/nsub)]\n");
}
// lyrics
return;
}
- if (lyric->name)
- fprintf(out, "%s\n", lyric->name);
+ // Num is optional for WebVTT, but maybe easier for clients
+ fprintf(out, "%d\n", lyric->num);
+
+ // Not always supported by clients, so disabled:
+ // if (lyric->name)
+ //fprintf(out, "%s\n", lyric->name);
char *start = nsub_webvtt_time_str(lyric->start + offset, 0);
char *stop = nsub_webvtt_time_str(lyric->stop + offset, 0);