fix(tts): rename japanese station audio suffix to ja
Switch generated station audio entries from en-* to ja-* and update the generator flow so Chinese plus Japanese audio imports use the new suffix consistently.
This commit is contained in:
@@ -566,8 +566,8 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>English Station Name (e.g., Beijing)</label>
|
||||
<input type="text" id="en-text" placeholder="Enter English Name">
|
||||
<label>Japanese Station Name (e.g., ちば)</label>
|
||||
<input type="text" id="en-text" placeholder="输入日文站名">
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" id="btn-generate" onclick="generateAudio()">
|
||||
@@ -584,7 +584,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>English Preview</label>
|
||||
<label>Japanese Preview</label>
|
||||
<div class="audio-preview">
|
||||
<audio id="en-audio" controls></audio>
|
||||
</div>
|
||||
@@ -605,8 +605,8 @@
|
||||
<!-- Batch Generation View -->
|
||||
<div id="view-batch" style="display: none; flex-direction: column; gap: 20px;">
|
||||
<div class="form-group" id="batch-input-group">
|
||||
<label>Paste Data (Format: ID <Tab> Chinese <Tab> English)</label>
|
||||
<textarea id="batch-input" rows="8" placeholder="01-01	千叶	Chiba CK-01	沼津	Numazu" style="resize: vertical; font-family: var(--font-mono); white-space: pre;"></textarea>
|
||||
<label>Paste Data (Format: ID <Tab> Chinese <Tab> Japanese)</label>
|
||||
<textarea id="batch-input" rows="8" placeholder="01-01	千叶	ちば CK-01	沼津	ぬまづ" style="resize: vertical; font-family: var(--font-mono); white-space: pre;"></textarea>
|
||||
<button class="btn btn-primary" id="btn-batch-preview" onclick="previewBatch()" style="margin-top: 10px;">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
|
||||
Preview Tasks
|
||||
@@ -721,10 +721,10 @@
|
||||
<script>
|
||||
const TTS_MODEL = "s2.1-pro-free";
|
||||
const ZH_REFERENCE_ID = "0aee9f0f5683480d987c9e3c5d2de04c";
|
||||
const EN_REFERENCE_ID = "38985e545cff41b79c11c32b0196c9a0";
|
||||
const JA_REFERENCE_ID = "38985e545cff41b79c11c32b0196c9a0";
|
||||
|
||||
let zhTempFile = null;
|
||||
let enTempFile = null;
|
||||
let jaTempFile = null;
|
||||
|
||||
let listData = [];
|
||||
let availableFiles = [];
|
||||
@@ -829,11 +829,11 @@
|
||||
return data;
|
||||
}
|
||||
|
||||
async function _importSingleAudio(code, zhTemp, enTemp) {
|
||||
async function _importSingleAudio(code, zhTemp, jaTemp) {
|
||||
const res = await fetch('/api/tts/import', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({ stationCode: code, zhTemp, enTemp })
|
||||
body: JSON.stringify({ stationCode: code, zhTemp, jaTemp })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!data.success) throw new Error(data.message);
|
||||
@@ -878,9 +878,9 @@
|
||||
batchTasks.forEach((task, index) => {
|
||||
// Initialize temp vars
|
||||
task.zhTempName = null;
|
||||
task.enTempName = null;
|
||||
task.jaTempName = null;
|
||||
task.zhUrl = null;
|
||||
task.enUrl = null;
|
||||
task.jaUrl = null;
|
||||
|
||||
const item = document.createElement('div');
|
||||
item.className = 'edit-file-item';
|
||||
@@ -892,7 +892,7 @@
|
||||
<div style="display:flex; justify-content:space-between; align-items:flex-start;">
|
||||
<div style="display:flex; flex-direction:column; gap:2px;">
|
||||
<span style="font-weight:600; color:var(--accent)">${task.code}</span>
|
||||
<span class="edit-file-name" style="color:var(--text-muted)">ZH: ${task.zh} | EN: ${task.en}</span>
|
||||
<span class="edit-file-name" style="color:var(--text-muted)">ZH: ${task.zh} | JA: ${task.en}</span>
|
||||
</div>
|
||||
<span id="batch-status-span-${index}" style="font-size:0.8rem; color:var(--text-muted)">Pending</span>
|
||||
</div>
|
||||
@@ -902,8 +902,8 @@
|
||||
<audio id="batch-audio-zh-${index}" controls style="height:24px;"></audio>
|
||||
</div>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="font-size:0.75rem; color:var(--text-muted); width:20px;">EN</span>
|
||||
<audio id="batch-audio-en-${index}" controls style="height:24px;"></audio>
|
||||
<span style="font-size:0.75rem; color:var(--text-muted); width:20px;">JA</span>
|
||||
<audio id="batch-audio-ja-${index}" controls style="height:24px;"></audio>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -957,14 +957,14 @@
|
||||
while (retryCount < 2 && !success) {
|
||||
try {
|
||||
// 1. Generate ZH
|
||||
const zhData = await _generateSingleTTS(task.zh, ZH_MODEL);
|
||||
// 2. Generate EN
|
||||
const enData = await _generateSingleTTS(task.en, EN_MODEL);
|
||||
const zhData = await _generateSingleTTS(task.zh, ZH_REFERENCE_ID);
|
||||
// 2. Generate JA
|
||||
const jaData = await _generateSingleTTS(task.en, JA_REFERENCE_ID);
|
||||
|
||||
task.zhTempName = zhData.tempName;
|
||||
task.enTempName = enData.tempName;
|
||||
task.jaTempName = jaData.jaTempName || jaData.enTempName || jaData.tempName;
|
||||
task.zhUrl = zhData.url;
|
||||
task.enUrl = enData.url;
|
||||
task.jaUrl = jaData.jaUrl || jaData.enUrl || jaData.url;
|
||||
|
||||
success = true;
|
||||
} catch (e) {
|
||||
@@ -987,7 +987,7 @@
|
||||
const previewDiv = document.getElementById(`batch-audio-preview-${i}`);
|
||||
previewDiv.style.display = 'flex';
|
||||
document.getElementById(`batch-audio-zh-${i}`).src = task.zhUrl;
|
||||
document.getElementById(`batch-audio-en-${i}`).src = task.enUrl;
|
||||
document.getElementById(`batch-audio-ja-${i}`).src = task.jaUrl;
|
||||
|
||||
successCount++;
|
||||
} else {
|
||||
@@ -1031,7 +1031,7 @@
|
||||
|
||||
for (let i = 0; i < batchTasks.length; i++) {
|
||||
const task = batchTasks[i];
|
||||
if (!task.zhTempName || !task.enTempName) continue; // Skip failed ones
|
||||
if (!task.zhTempName || !task.jaTempName) continue; // Skip failed ones
|
||||
|
||||
// Replace slashes with dashes to ensure filesystem compatibility
|
||||
if (task.code.includes('/')) {
|
||||
@@ -1044,10 +1044,10 @@
|
||||
statusSpan.style.color = 'var(--warning)';
|
||||
|
||||
try {
|
||||
await _importSingleAudio(task.code, task.zhTempName, task.enTempName);
|
||||
await _importSingleAudio(task.code, task.zhTempName, task.jaTempName);
|
||||
|
||||
// Update listData
|
||||
const filesStr = `ch-${task.code}.wav,en-${task.code}.wav`;
|
||||
const filesStr = `ch-${task.code}.wav,ja-${task.code}.wav`;
|
||||
const existingIndex = listData.findIndex(item => item.code === task.code);
|
||||
if (existingIndex >= 0) {
|
||||
listData[existingIndex].files = filesStr.split(',');
|
||||
@@ -1088,10 +1088,10 @@
|
||||
|
||||
async function generateAudio() {
|
||||
const zhText = document.getElementById('zh-text').value.trim();
|
||||
const enText = document.getElementById('en-text').value.trim();
|
||||
const jaText = document.getElementById('en-text').value.trim();
|
||||
|
||||
if (!zhText || !enText) {
|
||||
showToast("Error", "Please enter both Chinese and English names");
|
||||
if (!zhText || !jaText) {
|
||||
showToast("Error", "Please enter both Chinese and Japanese names");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1119,30 +1119,30 @@
|
||||
const dataZh = await resZh.json();
|
||||
if (!dataZh.success) throw new Error("ZH TTS failed: " + dataZh.message);
|
||||
|
||||
status.textContent = "Generating English audio...";
|
||||
status.textContent = "Generating Japanese audio...";
|
||||
|
||||
// Generate English via Server-Side Proxy
|
||||
const resEn = await fetch('/api/tts/generate', {
|
||||
// Generate Japanese via Server-Side Proxy
|
||||
const resJa = await fetch('/api/tts/generate', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
text: enText,
|
||||
reference_id: EN_REFERENCE_ID,
|
||||
text: jaText,
|
||||
reference_id: JA_REFERENCE_ID,
|
||||
model: TTS_MODEL
|
||||
})
|
||||
});
|
||||
|
||||
const dataEn = await resEn.json();
|
||||
if (!dataEn.success) throw new Error("EN TTS failed: " + dataEn.message);
|
||||
const dataJa = await resJa.json();
|
||||
if (!dataJa.success) throw new Error("JA TTS failed: " + dataJa.message);
|
||||
|
||||
// Success
|
||||
zhTempFile = dataZh.tempName;
|
||||
enTempFile = dataEn.tempName;
|
||||
jaTempFile = dataJa.jaTempName || dataJa.enTempName || dataJa.tempName;
|
||||
|
||||
document.getElementById('zh-audio').src = dataZh.url;
|
||||
document.getElementById('en-audio').src = dataEn.url;
|
||||
document.getElementById('en-audio').src = dataJa.jaUrl || dataJa.enUrl || dataJa.url;
|
||||
|
||||
document.getElementById('preview-section').style.display = 'block';
|
||||
status.textContent = "Generation complete!";
|
||||
@@ -1170,7 +1170,7 @@
|
||||
code = code.replace(/\//g, '-');
|
||||
}
|
||||
|
||||
if (!zhTempFile || !enTempFile) {
|
||||
if (!zhTempFile || !jaTempFile) {
|
||||
showToast("Error", "No audio generated to import");
|
||||
return;
|
||||
}
|
||||
@@ -1186,7 +1186,7 @@
|
||||
body: JSON.stringify({
|
||||
stationCode: code,
|
||||
zhTemp: zhTempFile,
|
||||
enTemp: enTempFile
|
||||
jaTemp: jaTempFile
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1196,7 +1196,7 @@
|
||||
showToast("Success", "Files imported to Station folder!");
|
||||
|
||||
// Automatically add/update to listData if generated via this panel
|
||||
const filesStr = `ch-${code}.wav,en-${code}.wav`;
|
||||
const filesStr = `ch-${code}.wav,ja-${code}.wav`;
|
||||
const existingIndex = listData.findIndex(item => item.code === code);
|
||||
if (existingIndex >= 0) {
|
||||
listData[existingIndex].files = filesStr.split(',');
|
||||
@@ -1209,7 +1209,7 @@
|
||||
|
||||
// Reset
|
||||
zhTempFile = null;
|
||||
enTempFile = null;
|
||||
jaTempFile = null;
|
||||
document.getElementById('preview-section').style.display = 'none';
|
||||
document.getElementById('gen-status').textContent = "";
|
||||
document.getElementById('zh-text').value = "";
|
||||
|
||||
Reference in New Issue
Block a user