@makefully/dutifully 1.10.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -5
- package/LICENSE +21 -21
- package/README.md +216 -214
- package/cheer.js +36 -36
- package/package.json +63 -63
- package/say.js +15 -15
- package/src/classes/Cheer.js +254 -254
- package/src/classes/ElevenLabs.js +16 -16
- package/src/classes/FFMPEG.js +12 -12
- package/src/classes/LipSync.js +140 -132
- package/src/classes/Polly.js +9 -9
- package/src/classes/Rasterize.js +12 -12
- package/src/classes/TextToSpeech.js +215 -204
- package/src/classes/Transcript.js +72 -68
- package/src/classes/Transcription.js +169 -162
- package/src/formats/File.js +28 -26
- package/src/formats/JSONFile.js +41 -39
- package/src/formats/LRC.js +37 -37
- package/src/formats/MP3.js +61 -59
- package/src/formats/SAMI.js +58 -58
- package/src/formats/SRT.js +39 -39
- package/src/formats/VTT.js +37 -37
- package/src/helpers/dirs.js +30 -0
- package/src/helpers/getCaptions.js +43 -43
- package/src/helpers/getFileData.js +32 -32
- package/src/helpers/getJSON.js +32 -32
- package/src/index.js +58 -58
- package/src/say.js +141 -141
package/src/formats/MP3.js
CHANGED
|
@@ -1,60 +1,62 @@
|
|
|
1
|
-
const
|
|
2
|
-
id3 = require('node-id3').Promise,
|
|
3
|
-
File = require("./File")
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
1
|
+
const
|
|
2
|
+
id3 = require('node-id3').Promise,
|
|
3
|
+
File = require("./File"),
|
|
4
|
+
{ensureParentDir} = require('../helpers/dirs');
|
|
5
|
+
|
|
6
|
+
module.exports = class MP3 extends File {
|
|
7
|
+
async load (path) {
|
|
8
|
+
await super.load(path);
|
|
9
|
+
this.data = await id3.read(path);
|
|
10
|
+
return this.data;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
addHash (hash, {hashKey = 'CaptionHash'} = {}) {
|
|
14
|
+
const
|
|
15
|
+
existing = (this.data.userDefinedText ?? []).filter(({description}) => description !== hashKey);
|
|
16
|
+
|
|
17
|
+
this.data.userDefinedText = [...existing, {description: hashKey, value: hash}];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getHash ({hashKey = 'CaptionHash'} = {}) {
|
|
21
|
+
const
|
|
22
|
+
{userDefinedText} = this.data;
|
|
23
|
+
|
|
24
|
+
if (userDefinedText) {
|
|
25
|
+
for (let i = 0; i < userDefinedText.length; i++) {
|
|
26
|
+
if (userDefinedText[i].description === hashKey) {
|
|
27
|
+
return userDefinedText[i].value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async save () { // return a promise
|
|
36
|
+
await ensureParentDir(this.path);
|
|
37
|
+
return id3.write(this.data, this.path);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
toString () {
|
|
41
|
+
const
|
|
42
|
+
{synchronisedLyrics, unsynchronisedLyrics} = this.data;
|
|
43
|
+
|
|
44
|
+
if (unsynchronisedLyrics?.text) {
|
|
45
|
+
return unsynchronisedLyrics.text;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (synchronisedLyrics) {
|
|
49
|
+
const
|
|
50
|
+
index = synchronisedLyrics.map(({shortText}) => shortText).indexOf('captions');
|
|
51
|
+
|
|
52
|
+
if (index >= 0) {
|
|
53
|
+
const
|
|
54
|
+
{synchronisedText} = synchronisedLyrics[index];
|
|
55
|
+
|
|
56
|
+
return synchronisedText.map(({text}) => text).join(' ');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return '';
|
|
61
|
+
}
|
|
60
62
|
}
|
package/src/formats/SAMI.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
const
|
|
2
|
-
fs = require('fs').promises,
|
|
3
|
-
File = require("./File"),
|
|
4
|
-
removeComments = (html) => html.replace(/<!--[\s\S]*?-->/g, ''),
|
|
5
|
-
cleanHTML = (html) => html
|
|
6
|
-
.replace(/<[^>]+>/g, '') // remove HTML tags
|
|
7
|
-
.replace(/ /gi, ' ') // decode common HTML entities
|
|
8
|
-
.replace(/&/gi, '&')
|
|
9
|
-
.replace(/</gi, '<')
|
|
10
|
-
.replace(/>/gi, '>')
|
|
11
|
-
.replace(/"/gi, '"')
|
|
12
|
-
.trim();
|
|
13
|
-
|
|
14
|
-
module.exports = class SAMI extends File {
|
|
15
|
-
async load (path) {
|
|
16
|
-
await super.load(path);
|
|
17
|
-
this.data = await fs.readFile(path, 'utf8');
|
|
18
|
-
return this.data;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
addHash (hash) {
|
|
22
|
-
this.data = this.data.replace(/<META[\s]+Hash="[a-f0-9]+"[\s]*\/>\n?/i, '');
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
insertAfter = this.data.match(/<META[\s]+Generator="[^"]*"[\s]*\/>/i);
|
|
26
|
-
|
|
27
|
-
if (insertAfter) {
|
|
28
|
-
this.data = this.data.replace(insertAfter[0], `${insertAfter[0]}\n <META Hash="${hash}"/>`);
|
|
29
|
-
} else {
|
|
30
|
-
this.data = this.data.replace(/<HEAD>/i, `<HEAD>\n <META Hash="${hash}"/>`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getHash () {
|
|
35
|
-
const
|
|
36
|
-
match = this.data.match(/<META[\s]+Hash="([a-f0-9]+)"/i);
|
|
37
|
-
|
|
38
|
-
return match ? match[1] : null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
toString () {
|
|
42
|
-
const
|
|
43
|
-
sami = removeComments(this.data),
|
|
44
|
-
regex = /<P[^>]*>([\s\S]*?)<\/P>/gi,
|
|
45
|
-
matches = [];
|
|
46
|
-
let match;
|
|
47
|
-
|
|
48
|
-
while ((match = regex.exec(sami)) !== null) {
|
|
49
|
-
const
|
|
50
|
-
innerText = cleanHTML(match[1]);
|
|
51
|
-
|
|
52
|
-
if (innerText) {
|
|
53
|
-
matches.push(innerText);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return matches.join(' ');
|
|
58
|
-
}
|
|
1
|
+
const
|
|
2
|
+
fs = require('fs').promises,
|
|
3
|
+
File = require("./File"),
|
|
4
|
+
removeComments = (html) => html.replace(/<!--[\s\S]*?-->/g, ''),
|
|
5
|
+
cleanHTML = (html) => html
|
|
6
|
+
.replace(/<[^>]+>/g, '') // remove HTML tags
|
|
7
|
+
.replace(/ /gi, ' ') // decode common HTML entities
|
|
8
|
+
.replace(/&/gi, '&')
|
|
9
|
+
.replace(/</gi, '<')
|
|
10
|
+
.replace(/>/gi, '>')
|
|
11
|
+
.replace(/"/gi, '"')
|
|
12
|
+
.trim();
|
|
13
|
+
|
|
14
|
+
module.exports = class SAMI extends File {
|
|
15
|
+
async load (path) {
|
|
16
|
+
await super.load(path);
|
|
17
|
+
this.data = await fs.readFile(path, 'utf8');
|
|
18
|
+
return this.data;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
addHash (hash) {
|
|
22
|
+
this.data = this.data.replace(/<META[\s]+Hash="[a-f0-9]+"[\s]*\/>\n?/i, '');
|
|
23
|
+
|
|
24
|
+
const
|
|
25
|
+
insertAfter = this.data.match(/<META[\s]+Generator="[^"]*"[\s]*\/>/i);
|
|
26
|
+
|
|
27
|
+
if (insertAfter) {
|
|
28
|
+
this.data = this.data.replace(insertAfter[0], `${insertAfter[0]}\n <META Hash="${hash}"/>`);
|
|
29
|
+
} else {
|
|
30
|
+
this.data = this.data.replace(/<HEAD>/i, `<HEAD>\n <META Hash="${hash}"/>`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getHash () {
|
|
35
|
+
const
|
|
36
|
+
match = this.data.match(/<META[\s]+Hash="([a-f0-9]+)"/i);
|
|
37
|
+
|
|
38
|
+
return match ? match[1] : null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
toString () {
|
|
42
|
+
const
|
|
43
|
+
sami = removeComments(this.data),
|
|
44
|
+
regex = /<P[^>]*>([\s\S]*?)<\/P>/gi,
|
|
45
|
+
matches = [];
|
|
46
|
+
let match;
|
|
47
|
+
|
|
48
|
+
while ((match = regex.exec(sami)) !== null) {
|
|
49
|
+
const
|
|
50
|
+
innerText = cleanHTML(match[1]);
|
|
51
|
+
|
|
52
|
+
if (innerText) {
|
|
53
|
+
matches.push(innerText);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return matches.join(' ');
|
|
58
|
+
}
|
|
59
59
|
}
|
package/src/formats/SRT.js
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
const
|
|
2
|
-
fs = require('fs').promises,
|
|
3
|
-
os = require('os'),
|
|
4
|
-
File = require("./File"),
|
|
5
|
-
getSeparater = (str) => str.indexOf(os.EOL) >= 0 ? os.EOL : '\n';
|
|
6
|
-
|
|
7
|
-
module.exports = class SRT extends File {
|
|
8
|
-
async load (path) {
|
|
9
|
-
await super.load(path);
|
|
10
|
-
this.data = await fs.readFile(path, 'utf8');
|
|
11
|
-
return this.data;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
addHash (hash) {
|
|
15
|
-
this.data = this.data.replace(/<u[\s]+hash="[a-f0-9]+"[\s]*(?:\/>|><\/u>)\n?/im, '');
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
insertAfter = this.data.match(/<u[\s]+generator="[^"]*"[\s]*(?:\/>|><\/u>)/im);
|
|
19
|
-
|
|
20
|
-
if (insertAfter) {
|
|
21
|
-
this.data = this.data.replace(insertAfter[0], `${insertAfter[0]}${getSeparater(this.data)}<u hash="${hash}"></u>`);
|
|
22
|
-
} else {
|
|
23
|
-
const
|
|
24
|
-
sep = getSeparater(this.data);
|
|
25
|
-
|
|
26
|
-
this.data = `1${sep}00:00:00,000 --> 00:00:00,001${sep}<u hash="${hash}"></u>${sep}${sep}${this.data}`;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getHash () {
|
|
31
|
-
const
|
|
32
|
-
match = this.data.match(/<u[\s]+hash="([a-f0-9]+)"[\s]*(?:\/>|><\/u>)/im);
|
|
33
|
-
|
|
34
|
-
return match ? match[1] : null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
toString () {
|
|
38
|
-
return this.data.split(getSeparater(this.data)).filter((line) => line.length > 0 && line.indexOf(' --> ') === -1 && parseInt(line) != line).join(' ');
|
|
39
|
-
}
|
|
1
|
+
const
|
|
2
|
+
fs = require('fs').promises,
|
|
3
|
+
os = require('os'),
|
|
4
|
+
File = require("./File"),
|
|
5
|
+
getSeparater = (str) => str.indexOf(os.EOL) >= 0 ? os.EOL : '\n';
|
|
6
|
+
|
|
7
|
+
module.exports = class SRT extends File {
|
|
8
|
+
async load (path) {
|
|
9
|
+
await super.load(path);
|
|
10
|
+
this.data = await fs.readFile(path, 'utf8');
|
|
11
|
+
return this.data;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
addHash (hash) {
|
|
15
|
+
this.data = this.data.replace(/<u[\s]+hash="[a-f0-9]+"[\s]*(?:\/>|><\/u>)\n?/im, '');
|
|
16
|
+
|
|
17
|
+
const
|
|
18
|
+
insertAfter = this.data.match(/<u[\s]+generator="[^"]*"[\s]*(?:\/>|><\/u>)/im);
|
|
19
|
+
|
|
20
|
+
if (insertAfter) {
|
|
21
|
+
this.data = this.data.replace(insertAfter[0], `${insertAfter[0]}${getSeparater(this.data)}<u hash="${hash}"></u>`);
|
|
22
|
+
} else {
|
|
23
|
+
const
|
|
24
|
+
sep = getSeparater(this.data);
|
|
25
|
+
|
|
26
|
+
this.data = `1${sep}00:00:00,000 --> 00:00:00,001${sep}<u hash="${hash}"></u>${sep}${sep}${this.data}`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getHash () {
|
|
31
|
+
const
|
|
32
|
+
match = this.data.match(/<u[\s]+hash="([a-f0-9]+)"[\s]*(?:\/>|><\/u>)/im);
|
|
33
|
+
|
|
34
|
+
return match ? match[1] : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
toString () {
|
|
38
|
+
return this.data.split(getSeparater(this.data)).filter((line) => line.length > 0 && line.indexOf(' --> ') === -1 && parseInt(line) != line).join(' ');
|
|
39
|
+
}
|
|
40
40
|
}
|
package/src/formats/VTT.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
const
|
|
2
|
-
fs = require('fs').promises,
|
|
3
|
-
os = require('os'),
|
|
4
|
-
File = require("./File"),
|
|
5
|
-
getSeparater = (str) => str.indexOf(os.EOL) >= 0 ? os.EOL : '\n';
|
|
6
|
-
|
|
7
|
-
module.exports = class VTT extends File {
|
|
8
|
-
async load (path) {
|
|
9
|
-
await super.load(path);
|
|
10
|
-
this.data = await fs.readFile(path, 'utf8');
|
|
11
|
-
return this.data;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
addHash (hash) {
|
|
15
|
-
this.data = this.data.replace(/^NOTE[\s]+Hash:[\s]+[a-f0-9]+\n?/im, '');
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
sep = getSeparater(this.data),
|
|
19
|
-
insertAfter = this.data.match(/^NOTE[\s]+Generator:[^\n]*/im);
|
|
20
|
-
|
|
21
|
-
if (insertAfter) {
|
|
22
|
-
this.data = this.data.replace(insertAfter[0], `${insertAfter[0]}${sep}NOTE Hash: ${hash}`);
|
|
23
|
-
} else {
|
|
24
|
-
this.data = this.data.replace('WEBVTT', `WEBVTT${sep}${sep}NOTE Hash: ${hash}`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
getHash () {
|
|
29
|
-
const
|
|
30
|
-
match = this.data.match(/^NOTE[\s]+Hash:[\s]+([a-f0-9]+)/im);
|
|
31
|
-
|
|
32
|
-
return match ? match[1] : null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
toString () {
|
|
36
|
-
return this.data.split(getSeparater(this.data)).filter((line) => line.length > 0 && line.indexOf(' --> ') === -1 && parseInt(line) != line).join(' ');
|
|
37
|
-
}
|
|
1
|
+
const
|
|
2
|
+
fs = require('fs').promises,
|
|
3
|
+
os = require('os'),
|
|
4
|
+
File = require("./File"),
|
|
5
|
+
getSeparater = (str) => str.indexOf(os.EOL) >= 0 ? os.EOL : '\n';
|
|
6
|
+
|
|
7
|
+
module.exports = class VTT extends File {
|
|
8
|
+
async load (path) {
|
|
9
|
+
await super.load(path);
|
|
10
|
+
this.data = await fs.readFile(path, 'utf8');
|
|
11
|
+
return this.data;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
addHash (hash) {
|
|
15
|
+
this.data = this.data.replace(/^NOTE[\s]+Hash:[\s]+[a-f0-9]+\n?/im, '');
|
|
16
|
+
|
|
17
|
+
const
|
|
18
|
+
sep = getSeparater(this.data),
|
|
19
|
+
insertAfter = this.data.match(/^NOTE[\s]+Generator:[^\n]*/im);
|
|
20
|
+
|
|
21
|
+
if (insertAfter) {
|
|
22
|
+
this.data = this.data.replace(insertAfter[0], `${insertAfter[0]}${sep}NOTE Hash: ${hash}`);
|
|
23
|
+
} else {
|
|
24
|
+
this.data = this.data.replace('WEBVTT', `WEBVTT${sep}${sep}NOTE Hash: ${hash}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getHash () {
|
|
29
|
+
const
|
|
30
|
+
match = this.data.match(/^NOTE[\s]+Hash:[\s]+([a-f0-9]+)/im);
|
|
31
|
+
|
|
32
|
+
return match ? match[1] : null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
toString () {
|
|
36
|
+
return this.data.split(getSeparater(this.data)).filter((line) => line.length > 0 && line.indexOf(' --> ') === -1 && parseInt(line) != line).join(' ');
|
|
37
|
+
}
|
|
38
38
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const
|
|
2
|
+
fs = require('fs').promises,
|
|
3
|
+
path = require('path'),
|
|
4
|
+
ensureDir = async (dir) => {
|
|
5
|
+
if (dir) {
|
|
6
|
+
await fs.mkdir(dir, {recursive: true});
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
ensureParentDir = async (filePath) => {
|
|
10
|
+
if (filePath) {
|
|
11
|
+
await ensureDir(path.dirname(filePath));
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
readdirOrEmpty = async (dir) => {
|
|
15
|
+
try {
|
|
16
|
+
return await fs.readdir(dir);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
if (e?.code === 'ENOENT') {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
throw e;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
ensureDir,
|
|
28
|
+
ensureParentDir,
|
|
29
|
+
readdirOrEmpty
|
|
30
|
+
};
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
filter = (fileType, file) => (file.indexOf('.') !== 0) && (file.slice(-(fileType.length + 1)) === `.${fileType}`);
|
|
5
|
-
|
|
6
|
-
module.exports = async (path, fileType) => {
|
|
7
|
-
|
|
8
|
-
// "captions.json" is a proprietary format that includes all captions.
|
|
9
|
-
if (fileType.toLowerCase() === 'json') {
|
|
10
|
-
const
|
|
11
|
-
file = await getFileData(`${path}captions.json`, 'json'),
|
|
12
|
-
{data: json} = file;
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
captions: Object.keys(json).reduce((obj, key) => {
|
|
16
|
-
obj[key] = json[key].map(({content}) => content).join(' ');
|
|
17
|
-
return obj;
|
|
18
|
-
}, {}),
|
|
19
|
-
file,
|
|
20
|
-
files: null
|
|
21
|
-
};
|
|
22
|
-
} else { // Otherwise we pull all the files and construct a key/value object.
|
|
23
|
-
const
|
|
24
|
-
files = (await
|
|
25
|
-
captions = {},
|
|
26
|
-
fileMap = {};
|
|
27
|
-
|
|
28
|
-
for (let i = 0; i < files.length; i++) {
|
|
29
|
-
const
|
|
30
|
-
filename = files[i],
|
|
31
|
-
file = await getFileData(`${path}${filename}`, fileType),
|
|
32
|
-
key = filename.substring(0, filename.length - fileType.length - 1);
|
|
33
|
-
|
|
34
|
-
captions[key] = file.toString();
|
|
35
|
-
fileMap[key] = file;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
captions,
|
|
40
|
-
file: null,
|
|
41
|
-
files: fileMap
|
|
42
|
-
};
|
|
43
|
-
}
|
|
1
|
+
const
|
|
2
|
+
getFileData = require("./getFileData"),
|
|
3
|
+
{readdirOrEmpty} = require("./dirs"),
|
|
4
|
+
filter = (fileType, file) => (file.indexOf('.') !== 0) && (file.slice(-(fileType.length + 1)) === `.${fileType}`);
|
|
5
|
+
|
|
6
|
+
module.exports = async (path, fileType) => {
|
|
7
|
+
|
|
8
|
+
// "captions.json" is a proprietary format that includes all captions.
|
|
9
|
+
if (fileType.toLowerCase() === 'json') {
|
|
10
|
+
const
|
|
11
|
+
file = await getFileData(`${path}captions.json`, 'json'),
|
|
12
|
+
{data: json = {}} = file;
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
captions: Object.keys(json ?? {}).reduce((obj, key) => {
|
|
16
|
+
obj[key] = json[key].map(({content}) => content).join(' ');
|
|
17
|
+
return obj;
|
|
18
|
+
}, {}),
|
|
19
|
+
file,
|
|
20
|
+
files: null
|
|
21
|
+
};
|
|
22
|
+
} else { // Otherwise we pull all the files and construct a key/value object.
|
|
23
|
+
const
|
|
24
|
+
files = (await readdirOrEmpty(path)).filter(filter.bind(null, fileType)),
|
|
25
|
+
captions = {},
|
|
26
|
+
fileMap = {};
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < files.length; i++) {
|
|
29
|
+
const
|
|
30
|
+
filename = files[i],
|
|
31
|
+
file = await getFileData(`${path}${filename}`, fileType),
|
|
32
|
+
key = filename.substring(0, filename.length - fileType.length - 1);
|
|
33
|
+
|
|
34
|
+
captions[key] = file.toString();
|
|
35
|
+
fileMap[key] = file;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
captions,
|
|
40
|
+
file: null,
|
|
41
|
+
files: fileMap
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
44
|
};
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
const
|
|
2
|
-
JSONFile = require("../formats/JSONFile"),
|
|
3
|
-
LRC = require("../formats/LRC"),
|
|
4
|
-
MP3 = require("../formats/MP3"),
|
|
5
|
-
SAMI = require("../formats/SAMI"),
|
|
6
|
-
SRT = require("../formats/SRT"),
|
|
7
|
-
VTT = require("../formats/VTT"),
|
|
8
|
-
formats = {
|
|
9
|
-
json: JSONFile,
|
|
10
|
-
lrc: LRC,
|
|
11
|
-
mp3: MP3,
|
|
12
|
-
sami: SAMI,
|
|
13
|
-
smi: SAMI,
|
|
14
|
-
srt: SRT,
|
|
15
|
-
vtt: VTT
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
module.exports = async (path, fileType) => {
|
|
19
|
-
const
|
|
20
|
-
lcFormat = fileType.toLowerCase(),
|
|
21
|
-
File = formats[lcFormat] ?? formats.JSONFile;
|
|
22
|
-
|
|
23
|
-
// Find file type and throw if that doesn't work.
|
|
24
|
-
if (File) {
|
|
25
|
-
const
|
|
26
|
-
file = new File({fileType: lcFormat});
|
|
27
|
-
|
|
28
|
-
await file.load(path);
|
|
29
|
-
return file;
|
|
30
|
-
} else {
|
|
31
|
-
throw `"${fileType}" not supported.`;
|
|
32
|
-
}
|
|
1
|
+
const
|
|
2
|
+
JSONFile = require("../formats/JSONFile"),
|
|
3
|
+
LRC = require("../formats/LRC"),
|
|
4
|
+
MP3 = require("../formats/MP3"),
|
|
5
|
+
SAMI = require("../formats/SAMI"),
|
|
6
|
+
SRT = require("../formats/SRT"),
|
|
7
|
+
VTT = require("../formats/VTT"),
|
|
8
|
+
formats = {
|
|
9
|
+
json: JSONFile,
|
|
10
|
+
lrc: LRC,
|
|
11
|
+
mp3: MP3,
|
|
12
|
+
sami: SAMI,
|
|
13
|
+
smi: SAMI,
|
|
14
|
+
srt: SRT,
|
|
15
|
+
vtt: VTT
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = async (path, fileType) => {
|
|
19
|
+
const
|
|
20
|
+
lcFormat = fileType.toLowerCase(),
|
|
21
|
+
File = formats[lcFormat] ?? formats.JSONFile;
|
|
22
|
+
|
|
23
|
+
// Find file type and throw if that doesn't work.
|
|
24
|
+
if (File) {
|
|
25
|
+
const
|
|
26
|
+
file = new File({fileType: lcFormat});
|
|
27
|
+
|
|
28
|
+
await file.load(path);
|
|
29
|
+
return file;
|
|
30
|
+
} else {
|
|
31
|
+
throw `"${fileType}" not supported.`;
|
|
32
|
+
}
|
|
33
33
|
};
|
package/src/helpers/getJSON.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
const
|
|
2
|
-
fs = require('fs'),
|
|
3
|
-
getJSON = (path) => new Promise ((resolve, reject) => {
|
|
4
|
-
fs.readFile(path, (err, data) => {
|
|
5
|
-
if (err) {
|
|
6
|
-
reject(err);
|
|
7
|
-
} else {
|
|
8
|
-
let json = null;
|
|
9
|
-
|
|
10
|
-
try {
|
|
11
|
-
json = JSON.parse(data);
|
|
12
|
-
} catch (e) {
|
|
13
|
-
reject(e);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (json) {
|
|
17
|
-
resolve(json);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
module.exports = async (path) => {
|
|
24
|
-
let json = null;
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
json = await getJSON(path);
|
|
28
|
-
} catch (e) {
|
|
29
|
-
console.warn(e);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return json;
|
|
1
|
+
const
|
|
2
|
+
fs = require('fs'),
|
|
3
|
+
getJSON = (path) => new Promise ((resolve, reject) => {
|
|
4
|
+
fs.readFile(path, (err, data) => {
|
|
5
|
+
if (err) {
|
|
6
|
+
reject(err);
|
|
7
|
+
} else {
|
|
8
|
+
let json = null;
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
json = JSON.parse(data);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
reject(e);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (json) {
|
|
17
|
+
resolve(json);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
module.exports = async (path) => {
|
|
24
|
+
let json = null;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
json = await getJSON(path);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.warn(e);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return json;
|
|
33
33
|
};
|