This repository has been archived by the owner on Nov 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathyukari.js
78 lines (68 loc) · 2.33 KB
/
yukari.js
1
2
3
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const CONFIG = require('./config.json');
const fs = require('fs');
const crypto = require('crypto');
const request = require('request');
const Yukari = function(text, success, minimumDelay) {
const hash = crypto.createHash('md5').update(text).digest('hex');
const tempPath = `${CONFIG.yukariTempPath}ytmp${hash}.ogg`;
const cachePath = `${CONFIG.yukariCache}${hash}.ogg`;
if (fs.existsSync(cachePath)) {
setTimeout(() => {
success(cachePath);
}, minimumDelay);
return;
}
const startTime = Date.now();
// request the file to be generated
request.post(
'https://cloud.ai-j.jp/demo/aitalk2webapi_nop.php',
{ form: {
speaker_id: 1206,
text,
ext: 'ogg',
volume: 2.0,
speed: 1.4,
pitch: 1.1,
callback: 'callback',
} },
(error, response, body) => {
if (!error && response.statusCode == 200) {
const stringjson = body.slice(9, -1); // chop off the jQuery callback stuff... I'm sure there's a better way to do this, but it's OK for now
let json;
try {
json = JSON.parse(stringjson);
}
catch (e) {
return;
}
// obtain the file
request('https:' + json.url)
.pipe(fs.createWriteStream(tempPath))
.on('finish', () => {
// detect the first silence in the file
execute(`ffmpeg -i "${tempPath}" -af silencedetect=d=0.2 -f null -`, (stdout) => {
const silence = /silence_end:\s([0-9]+\.[0-9]+)/.exec(stdout);
if (!silence) {
return;
}
// chop off up to the first silence
execute(`ffmpeg -ss ${silence[1]} -i "${tempPath}" -af "volume=5dB" -y "${tempPath}"`, () => {
execute(`ffmpeg -i "assets/yukari/start.ogg" -i "${tempPath}" -i "assets/yukari/end.ogg" -filter_complex "[0:a:0][1:a:0][2:a:0]concat=n=3:v=0:a=1[outa]" -map "[outa]" -y "${tempPath}"`, () => {
fs.createReadStream(`${tempPath}`).pipe(fs.createWriteStream(cachePath));
setTimeout(() => {
fs.unlink(tempPath, ()=>{});
success(cachePath);
}, Math.max(0, minimumDelay - (Date.now() - startTime)));
});
});
});
});
}
}
);
};
const exec = require('child_process').exec;
function execute(command, callback) {
exec(command, {}, function(error, stdout, stderr) { callback(stderr); });
}
module.exports = Yukari;