Split content in playVoice instead of readChannel handler
This commit is contained in:
parent
d77f3694a6
commit
d4f8013d94
4 changed files with 67 additions and 24 deletions
|
|
@ -64,10 +64,7 @@ export default defineEvent("messageCreate", async (message) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const text of content.split("\n")) {
|
await playVoice(guild, profile, voice, content, options);
|
||||||
await playVoice(guild, profile, voice, text, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
message.reply("말이 꼬이네요 ㅜ.ㅜ");
|
message.reply("말이 꼬이네요 ㅜ.ㅜ");
|
||||||
console.log("playVoice failed. ", err);
|
console.log("playVoice failed. ", err);
|
||||||
|
|
|
||||||
|
|
@ -68,40 +68,48 @@ export async function playVoice(
|
||||||
throw new Error(`the user ${profile.userId} is can't use typecast voice`);
|
throw new Error(`the user ${profile.userId} is can't use typecast voice`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let voiceBuffer: Buffer
|
let voiceBufferList: Buffer[]
|
||||||
if (voice == "TypeCast") {
|
if (voice == "TypeCast") {
|
||||||
const content = TTSTypecastModel.instance.ttsify(text);
|
const content = TTSTypecastModel.instance.ttsify(text);
|
||||||
|
|
||||||
if (!content.length)
|
if (!content.length)
|
||||||
throw new Error("Empty content");
|
throw new Error("Empty content");
|
||||||
|
|
||||||
voiceBuffer = await TTSTypecastModel.instance.getMemcachedVoice(
|
voiceBufferList = await Promise.all(content.split("\n").map(
|
||||||
TTSTypecastModel.instance.createRequestId(content)
|
(content) => TTSTypecastModel.instance.getMemcachedVoice(
|
||||||
);
|
TTSTypecastModel.instance.createRequestId(content)
|
||||||
|
)
|
||||||
|
));
|
||||||
} else if (voice == "Supertonic") {
|
} else if (voice == "Supertonic") {
|
||||||
const content = TTSSupertonicModel.instance.ttsify(text);
|
const content = TTSSupertonicModel.instance.ttsify(text);
|
||||||
|
|
||||||
if (!content.length)
|
if (!content.length)
|
||||||
throw new Error("Empty content");
|
throw new Error("Empty content");
|
||||||
|
|
||||||
voiceBuffer = await TTSSupertonicModel.instance.getMemcachedVoice(
|
voiceBufferList = await Promise.all(content.split("\n").map(
|
||||||
TTSSupertonicModel.instance.createRequestId(content, options?.supertonicStyleId)
|
(content) => TTSSupertonicModel.instance.getMemcachedVoice(
|
||||||
);
|
TTSSupertonicModel.instance.createRequestId(content, options?.supertonicStyleId)
|
||||||
|
)
|
||||||
|
));
|
||||||
} else if (voice == "Papago") {
|
} else if (voice == "Papago") {
|
||||||
const content = TTSPapagoModel.instance.ttsify(text);
|
const content = TTSPapagoModel.instance.ttsify(text);
|
||||||
if (!content.length)
|
if (!content.length)
|
||||||
throw new Error("Empty content");
|
throw new Error("Empty content");
|
||||||
|
|
||||||
voiceBuffer = await TTSPapagoModel.instance.getMemcachedVoice(
|
voiceBufferList = await Promise.all(content.split("\n").map(
|
||||||
TTSPapagoModel.instance.createRequestId(content)
|
(content) => TTSPapagoModel.instance.getMemcachedVoice(
|
||||||
);
|
TTSPapagoModel.instance.createRequestId(content)
|
||||||
|
)
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unknown voice type: ${voice}`);
|
throw new Error(`Unknown voice type: ${voice}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
VoiceQueue.fromConnection(connection).enqueue(
|
for (const voiceBuffer of voiceBufferList) {
|
||||||
TTSModelBase.bufferToAudioResource(voiceBuffer)
|
VoiceQueue.fromConnection(connection).enqueue(
|
||||||
);
|
TTSModelBase.bufferToAudioResource(voiceBuffer)
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
OutputHandler.errorLog("[PlayVoice Error]", err);
|
OutputHandler.errorLog("[PlayVoice Error]", err);
|
||||||
throw new Error(err as any);
|
throw new Error(err as any);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export default class IntegerKorean {
|
||||||
}
|
}
|
||||||
|
|
||||||
static convertFromString(num: string): string {
|
static convertFromString(num: string): string {
|
||||||
|
num = num.replace(/,/g, "");
|
||||||
let isNegative = false;
|
let isNegative = false;
|
||||||
if (num.startsWith("-")) {
|
if (num.startsWith("-")) {
|
||||||
num = num.slice(1, -1);
|
num = num.slice(1, -1);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@ export const SymbolMap = {
|
||||||
"~": "물결표",
|
"~": "물결표",
|
||||||
"\\": "역슬래쉬",
|
"\\": "역슬래쉬",
|
||||||
"♡": "하트 ",
|
"♡": "하트 ",
|
||||||
|
"|": "",
|
||||||
|
">": "",
|
||||||
|
"<": "",
|
||||||
|
":": "콜론",
|
||||||
|
";": "세미콜론"
|
||||||
};
|
};
|
||||||
export const VersionPostfix = {
|
export const VersionPostfix = {
|
||||||
"a": "알파",
|
"a": "알파",
|
||||||
|
|
@ -120,7 +125,19 @@ export const SIPrefix = {
|
||||||
"zi": "제비",
|
"zi": "제비",
|
||||||
"y": "요타",
|
"y": "요타",
|
||||||
"yi": "요비",
|
"yi": "요비",
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export const LiterPrefix = {
|
||||||
|
"m": "밀리",
|
||||||
|
"": "",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MeterPrefix = {
|
||||||
|
"m": "밀리",
|
||||||
|
"c": "센치",
|
||||||
|
"": "",
|
||||||
|
"k": "킬로",
|
||||||
|
};
|
||||||
|
|
||||||
export function processDots(input: string): string {
|
export function processDots(input: string): string {
|
||||||
return input.replace(/[\.,]+$/, "")
|
return input.replace(/[\.,]+$/, "")
|
||||||
|
|
@ -136,6 +153,8 @@ export function saferKorean(input: string): string {
|
||||||
element as keyof typeof IsolatedSymbolMap
|
element as keyof typeof IsolatedSymbolMap
|
||||||
]).join("")
|
]).join("")
|
||||||
))
|
))
|
||||||
|
.replace(/\s\|\|\s/g, " 오얼 ")
|
||||||
|
.replace(/\s\&\&\s/g, " 엔드 ")
|
||||||
|
|
||||||
// Process codeblock
|
// Process codeblock
|
||||||
.replace(/\`\`\`([\s\S]*?)\`\`\`/g, (_, content: string)=>{
|
.replace(/\`\`\`([\s\S]*?)\`\`\`/g, (_, content: string)=>{
|
||||||
|
|
@ -153,7 +172,6 @@ export function saferKorean(input: string): string {
|
||||||
// Process koreans
|
// Process koreans
|
||||||
.replace(/ㅋ{2,}/g, (content) => "크".repeat(content.length))
|
.replace(/ㅋ{2,}/g, (content) => "크".repeat(content.length))
|
||||||
.replace(/[아ㅏ]{3,}/g, "아아아")
|
.replace(/[아ㅏ]{3,}/g, "아아아")
|
||||||
.replace(/https\S+/g, "링크")
|
|
||||||
.replace(/ㅌ{2,}/g, "틔틔")
|
.replace(/ㅌ{2,}/g, "틔틔")
|
||||||
.replace(/ㄷ{2,}/g, "덜덜")
|
.replace(/ㄷ{2,}/g, "덜덜")
|
||||||
.replace(/(ㅊㅋ)+/g, (content: string) => {
|
.replace(/(ㅊㅋ)+/g, (content: string) => {
|
||||||
|
|
@ -173,12 +191,24 @@ export function saferKorean(input: string): string {
|
||||||
.replace(/[ㄱ-ㅎㄲㄸㅃㅆㅉ]/g, (char: string) => ChoseongMap[char as keyof typeof ChoseongMap])
|
.replace(/[ㄱ-ㅎㄲㄸㅃㅆㅉ]/g, (char: string) => ChoseongMap[char as keyof typeof ChoseongMap])
|
||||||
|
|
||||||
// Process number, unit
|
// Process number, unit
|
||||||
.replace(/(\d+)([kKMmgGtTpP][iI]?)[bB]/g, (_, num: string, mod: string) => {
|
.replace(/([\d,]+)([kKMmgGtTpP][iI]?)[bB]/g, (_, num: string, mod: string) => {
|
||||||
// 10kib => 10키비바이트
|
// 10kib => 십키비바이트
|
||||||
num = IntegerKorean.convertFromString(num);
|
num = IntegerKorean.convertFromString(num);
|
||||||
mod = SIPrefix[mod.toLowerCase() as keyof typeof SIPrefix];
|
mod = SIPrefix[mod.toLowerCase() as keyof typeof SIPrefix];
|
||||||
return `${num} ${mod}바이트 `;
|
return `${num} ${mod}바이트 `;
|
||||||
})
|
})
|
||||||
|
.replace(/([\d,]+)([mck]?)m/g, (_, num: string, mod: string) => {
|
||||||
|
// 10m => 십미터
|
||||||
|
num = IntegerKorean.convertFromString(num);
|
||||||
|
mod = MeterPrefix[mod as keyof typeof MeterPrefix];
|
||||||
|
return `${num} ${mod}미터`;
|
||||||
|
})
|
||||||
|
.replace(/([\d,]+)([m]?)l/g, (_, num: string, mod: string) => {
|
||||||
|
// 10l => 십리터
|
||||||
|
num = IntegerKorean.convertFromString(num);
|
||||||
|
mod = LiterPrefix[mod as keyof typeof LiterPrefix];
|
||||||
|
return `${num} ${mod}리터`;
|
||||||
|
})
|
||||||
.replace(/([\d\.]+)\s*([개살시평명])/g, (_, num: string, postfix: string)=>{
|
.replace(/([\d\.]+)\s*([개살시평명])/g, (_, num: string, postfix: string)=>{
|
||||||
// 10명 => 열명
|
// 10명 => 열명
|
||||||
if (num.includes(".")) {
|
if (num.includes(".")) {
|
||||||
|
|
@ -194,7 +224,6 @@ export function saferKorean(input: string): string {
|
||||||
.replace(/[\d,]+/g, (num: string) => {
|
.replace(/[\d,]+/g, (num: string) => {
|
||||||
// 1,000 원 => 천원
|
// 1,000 원 => 천원
|
||||||
if (!num.includes(",")) return num;
|
if (!num.includes(",")) return num;
|
||||||
num = num.replace(/,/g, "");
|
|
||||||
return IntegerKorean.convertFromString(num);
|
return IntegerKorean.convertFromString(num);
|
||||||
})
|
})
|
||||||
.replace(/(v?)([\d\.]+)([ab]?)/g, (_, suffix: string, num: string, postfix: string) => {
|
.replace(/(v?)([\d\.]+)([ab]?)/g, (_, suffix: string, num: string, postfix: string) => {
|
||||||
|
|
@ -231,10 +260,18 @@ export function saferKorean(input: string): string {
|
||||||
.replace(/㎡/g, "제곱미터")
|
.replace(/㎡/g, "제곱미터")
|
||||||
.replace(/㎢/g, "제곱킬로미터")
|
.replace(/㎢/g, "제곱킬로미터")
|
||||||
|
|
||||||
|
// Process link
|
||||||
|
.replace(/[hH][tT]{2}[pP][sS]?:\/\/(\S+)/g, (_, url: string) => {
|
||||||
|
if (url.startsWith("tenor.com/view")) {
|
||||||
|
return "움짤";
|
||||||
|
}
|
||||||
|
return "링크";
|
||||||
|
})
|
||||||
|
|
||||||
// Process symbol
|
// Process symbol
|
||||||
.replace(/[\%\^\&\*\#\@\.\-\+\_\=\/\\♡\$]/g, (t) => (
|
.replace(/[\%\^\&\*\#\@\.\-\+\_\=\/\\♡\$\|\:\;\>\<]/g, (t) => (
|
||||||
SymbolMap[t as keyof typeof SymbolMap]
|
SymbolMap[t as keyof typeof SymbolMap]
|
||||||
))
|
))
|
||||||
.replace(/([\?\!]+)/g, (_, content: string) => content[0])
|
.replace(/([\?\!]+)/g, (_, content: string) => content[0])
|
||||||
.replace(/\s+/g, " ")
|
.replace(/[ \t\f\r]+/g, " ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue