Spaces:
Sleeping
Sleeping
const plugin = requirePlugin("WechatSI"); | |
const manager = plugin.getRecordRecognitionManager(); | |
Page({ | |
data: { | |
languages: { | |
'zh': { name: '中文', flag: 'cn', code: 'zh_CN' }, | |
'en': { name: 'English', flag: 'us', code: 'en_US' }, | |
'ja': { name: '日本語', flag: 'jp', code: 'ja_JP' }, | |
'ko': { name: '한국어', flag: 'kr', code: 'ko_KR' } | |
}, | |
langCodes: ['zh', 'en', 'ja', 'ko'], | |
sourceLang: 'zh', | |
targetLang: 'en', | |
transcript: '', | |
outputText: '', | |
isRecording: false, | |
sourceLanguages: [], | |
targetLanguages: [], | |
hfSpaceUrl: 'https://dazaozi-wechat-translator-app.hf.space', | |
// This flag will determine if we need to call our backend | |
useHfBridge: false | |
}, | |
onLoad: function () { | |
this.initializeLanguages(); | |
this.initManager(); | |
}, | |
// --- Language Selection Logic --- | |
initializeLanguages: function () { | |
const { langCodes, languages, sourceLang, targetLang } = this.data; | |
this.setData({ | |
sourceLanguages: langCodes.map(c => ({ | |
langCode: c, | |
name: languages[c].name, | |
flag: languages[c].flag, | |
selected: c === sourceLang | |
})), | |
targetLanguages: langCodes.map(c => ({ | |
langCode: c, | |
name: languages[c].name, | |
flag: languages[c].flag, | |
selected: c === targetLang | |
})) | |
}); | |
}, | |
selectSourceLanguage: function (e) { | |
const newSourceLang = e.currentTarget.dataset.langCode; | |
this.setData({ sourceLang: newSourceLang }, this.initializeLanguages); | |
}, | |
selectTargetLanguage: function (e) { | |
const newTargetLang = e.currentTarget.dataset.langCode; | |
this.setData({ targetLang: newTargetLang }, this.initializeLanguages); | |
}, | |
swapLanguages: function () { | |
const { sourceLang, targetLang } = this.data; | |
this.setData({ | |
sourceLang: targetLang, | |
targetLang: sourceLang, | |
transcript: this.data.outputText, | |
outputText: this.data.transcript | |
}, this.initializeLanguages); | |
}, | |
// --- Unified Plugin Manager Initialization --- | |
initManager: function () { | |
manager.onStart = (res) => { | |
this.setData({ transcript: '正在聆听...', outputText: '' }); | |
}; | |
manager.onRecognize = (res) => { | |
// Live recognition feedback | |
this.setData({ transcript: res.result }); | |
}; | |
manager.onStop = (res) => { | |
this.setData({ isRecording: false }); | |
if (res.result) { | |
this.setData({ transcript: res.result }); | |
// If using HF Bridge, the plugin only provides the transcript. | |
// We then manually call our backend for translation. | |
if (this.data.useHfBridge) { | |
this.translateViaHfBridge(res.result); | |
} else { | |
// Otherwise, the plugin provides the translation directly. | |
this.setData({ outputText: res.translateResult || '翻译结果为空' }); | |
} | |
} else { | |
this.setData({ transcript: '识别结果为空', outputText: '' }); | |
} | |
}; | |
manager.onError = (res) => { | |
this.setData({ isRecording: false, transcript: '识别失败', outputText: res.msg }); | |
}; | |
}, | |
// --- Unified Start/Stop Recording --- | |
startRecording: function () { | |
const { sourceLang, targetLang, languages } = this.data; | |
// Block recording if source is not CN or EN | |
if (sourceLang !== 'zh' && sourceLang !== 'en') { | |
wx.showToast({ | |
title: '语音输入暂仅支持中文和英文', | |
icon: 'none', | |
duration: 2000 | |
}); | |
return; | |
} | |
const isChineseEnglishPair = (sourceLang === 'zh' || sourceLang === 'en') && (targetLang === 'zh' || targetLang === 'en'); | |
const useHfBridge = !isChineseEnglishPair; | |
this.setData({ | |
isRecording: true, | |
useHfBridge: useHfBridge, | |
transcript: '', | |
outputText: '' | |
}); | |
manager.start({ | |
lang: languages[sourceLang].code, | |
trans_lang: languages[targetLang].code, | |
// Critical: Only enable plugin's internal translation for direct CN/EN pairs | |
translate: !useHfBridge | |
}); | |
}, | |
stopRecording: function () { | |
manager.stop(); | |
}, | |
// --- HF Bridge Translation Flow --- | |
translateViaHfBridge: function(text) { | |
const { sourceLang, targetLang } = this.data; | |
this.setData({ outputText: '翻译中 (HF)...' }); | |
// The plugin has already done the ASR (e.g., EN). | |
// Now we translate it to the final target (e.g., JA). | |
this.translateViaHF(text, sourceLang, targetLang, (finalResult) => { | |
if (finalResult) { | |
this.setData({ outputText: finalResult }); | |
} | |
// Error message is set within translateViaHF | |
}); | |
}, | |
translateViaHF: function(text, sourceLang, targetLang, callback) { | |
wx.request({ | |
url: `${this.data.hfSpaceUrl}/api/translate`, | |
method: 'POST', | |
header: { 'Content-Type': 'application/json' }, | |
data: { | |
"text": text, | |
"source_lang": sourceLang, | |
"target_lang": targetLang | |
}, | |
timeout: 45000, | |
success: (res) => { | |
if (res.statusCode === 200 && res.data.translated_text) { | |
callback(res.data.translated_text); | |
} else { | |
const errorMsg = res.data.error || `HF翻译失败 (${sourceLang}->${targetLang})`; | |
this.setData({ outputText: errorMsg }); | |
callback(null); | |
} | |
}, | |
fail: (err) => { | |
this.setData({ outputText: `HF请求失败 (${sourceLang}->${targetLang})` }); | |
callback(null); | |
} | |
}); | |
} | |
}); |