wechat-translator-app / pages /index /index_v27_old.js
AKIRA
Finalize all local changes
b3b0b53
raw
history blame
7.81 kB
const plugin = requirePlugin("WechatSI");
const pluginManager = plugin.getRecordRecognitionManager();
const nativeRecorderManager = wx.getRecorderManager();
function showDetailedError(title, content) {
wx.showModal({
title: title,
content: typeof content === 'object' ? JSON.stringify(content) : String(content),
showCancel: false
});
}
Page({
data: {
languages: {
'zh': { name: '中文', flag: 'cn', code: 'zh_CN', usePlugin: true },
'en': { name: 'English', flag: 'us', code: 'en_US', usePlugin: true },
'ja': { name: '日本語', flag: 'jp', code: 'ja_JP', usePlugin: false },
'ko': { name: '한국어', flag: 'kr', code: 'ko_KR', usePlugin: false }
},
sourceLang: 'zh',
targetLang: 'en',
transcript: '',
outputText: '',
isRecording: false,
hfSpaceUrl: 'https://dazaozi-wechat-translator-app.hf.space',
},
onLoad: function () {
this.setData({
sourceLanguages: Object.values(this.data.languages).map(lang => ({...lang, langCode: lang.code.split('_')[0]})),
targetLanguages: Object.values(this.data.languages).map(lang => ({...lang, langCode: lang.code.split('_')[0]}))
});
this.initPluginManager();
this.initNativeRecorderManager();
},
// --- Language Selection & UI with DEBUG ---
selectSourceLanguage: function (e) {
const newLang = e.currentTarget.dataset.langCode;
console.log(`[DEBUG] Language button tapped. Changing sourceLang to: ${newLang}`);
this.setData({ sourceLang: newLang });
},
selectTargetLanguage: function (e) {
const newLang = e.currentTarget.dataset.langCode;
console.log(`[DEBUG] Language button tapped. Changing targetLang to: ${newLang}`);
this.setData({ targetLang: newLang });
},
swapLanguages: function () {
this.setData({ sourceLang: this.data.targetLang, targetLang: this.data.sourceLang, transcript: this.data.outputText, outputText: this.data.transcript });
},
// --- Manager Initializations ---
initPluginManager: function () {
pluginManager.onStart = () => this.setData({ transcript: '正在聆听 (插件)...', outputText: '' });
pluginManager.onRecognize = (res) => this.setData({ transcript: res.result });
pluginManager.onStop = (res) => {
this.setData({ isRecording: false });
if (!res.result) { return this.setData({ transcript: '识别结果为空' }); }
this.setData({ transcript: res.result });
const { sourceLang, targetLang, languages } = this.data;
if (sourceLang === targetLang) { return this.setData({ outputText: res.result }); }
const isPluginTarget = languages[targetLang].usePlugin;
if (isPluginTarget) { this.translateViaPlugin(res.result); }
else { this.translateViaHfBridge(res.result, sourceLang, targetLang); }
};
pluginManager.onError = (res) => { this.setData({ isRecording: false }); showDetailedError('插件录音失败', res); };
},
initNativeRecorderManager: function () {
nativeRecorderManager.onStart = () => this.setData({ transcript: '正在聆听 (原生)...', outputText: '' });
nativeRecorderManager.onStop = (res) => {
this.setData({ isRecording: false });
if (res.tempFilePath) { this.uploadAudioForASR(res.tempFilePath); }
else { this.setData({ transcript: '原生录音文件获取失败' }); }
};
nativeRecorderManager.onError = (res) => { this.setData({ isRecording: false }); showDetailedError('原生录音失败', res); };
},
// --- Main Record Button Handler ---
handleRecordToggle: function() {
if (this.data.isRecording) { this.stopRecording(); return; }
wx.getSetting({
success: (res) => {
if (!res.authSetting['scope.record']) {
wx.authorize({ scope: 'scope.record', success: this.startRecording, fail: (err) => showDetailedError('授权失败', err) });
} else { this.startRecording(); }
},
fail: (err) => showDetailedError('无法获取权限设置', err)
});
},
startRecording: function () {
const { sourceLang, languages } = this.data;
const langConfig = languages[sourceLang];
// Fallback to a default config if something goes wrong, to prevent crashes
const shouldUsePlugin = langConfig ? langConfig.usePlugin : false;
// *** ULTIMATE DEBUG LOG ***
console.log(`[DEBUG] Start decision: sourceLang=${sourceLang}, langConfig=${JSON.stringify(langConfig)}, shouldUsePlugin=${shouldUsePlugin}`);
this.setData({ isRecording: true });
if (shouldUsePlugin) {
pluginManager.start({ lang: (langConfig || {code: 'zh_CN'}).code, translate: false });
} else {
nativeRecorderManager.start({ format: 'mp3', sampleRate: 16000, numberOfChannels: 1 });
}
},
// --- ROBUST Stop Recording ---
stopRecording: function () {
this.setData({ isRecording: false });
try { pluginManager.stop(); } catch (e) { /* Ignore error */ }
try { nativeRecorderManager.stop(); } catch (e) { /* Ignore error */ }
},
// --- Translation Logic ---
translateViaPlugin: function(text) {
const { sourceLang, targetLang, languages } = this.data;
this.setData({ outputText: '翻译中 (插件)...' });
plugin.translate({
lfrom: languages[sourceLang].code, lto: languages[targetLang].code, content: text,
success: (res) => { if (res.retcode === 0) { this.setData({ outputText: res.result }); } else { showDetailedError('插件翻译失败', res); } },
fail: (err) => showDetailedError('插件翻译接口调用失败', err)
});
},
uploadAudioForASR: function (filePath) {
this.setData({ transcript: '正在识别 (HF)...' });
wx.getFileSystemManager().readFile({ filePath, encoding: 'base64', success: (res) => {
wx.request({
url: `${this.data.hfSpaceUrl}/api/asr`, method: 'POST', data: { "audio_data_uri": `data:audio/mp3;base64,${res.data}` }, timeout: 60000,
success: (asrRes) => {
if (asrRes.statusCode === 200 && asrRes.data.transcript) {
const transcript = asrRes.data.transcript;
this.setData({ transcript });
this.translateViaHfBridge(transcript, this.data.sourceLang, this.data.targetLang);
} else { showDetailedError('HF识别失败', asrRes.data); }
},
fail: (err) => showDetailedError('HF识别请求失败', err)
});
}});
},
translateViaHfBridge: function(text, source, target) {
if (source === target) { return this.setData({ outputText: text }); }
this.setData({ outputText: '翻译中 (HF)...' });
this.translateViaHF(text, source, target, (result) => { if (result) { this.setData({ outputText: result }); } });
},
translateViaHF: function(text, sourceLang, targetLang, callback) {
wx.request({
url: `${this.data.hfSpaceUrl}/api/translate`, method: 'POST', 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 { showDetailedError('HF翻译失败', res.data); callback(null); } },
fail: (err) => { showDetailedError('HF翻译请求失败', err); callback(null); }
});
}
});