Spaces:
Sleeping
Sleeping
File size: 5,584 Bytes
b3b0b53 |
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
// FINAL VERSION: v28 - Unified Native Recording and HF Backend
const nativeRecorderManager = wx.getRecorderManager();
// Helper function to show detailed errors
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' },
'en': { name: 'English', flag: 'us' },
'ja': { name: '日本語', flag: 'jp' },
'ko': { name: '한국어', flag: 'kr' }
},
sourceLang: 'zh',
targetLang: 'en',
transcript: '',
outputText: '',
isRecording: false,
hfSpaceUrl: 'https://dazaozi-wechat-translator-app.hf.space',
},
onLoad: function () {
// Directly create language arrays for the UI from the static config
this.setData({
sourceLanguages: Object.keys(this.data.languages).map(key => ({ ...this.data.languages[key], langCode: key })),
targetLanguages: Object.keys(this.data.languages).map(key => ({ ...this.data.languages[key], langCode: key }))
});
this.initNativeRecorderManager();
},
// --- Language Selection & UI ---
selectSourceLanguage: function (e) { this.setData({ sourceLang: e.currentTarget.dataset.langCode }); },
selectTargetLanguage: function (e) { this.setData({ targetLang: e.currentTarget.dataset.langCode }); },
swapLanguages: function () {
this.setData({ sourceLang: this.data.targetLang, targetLang: this.data.sourceLang, transcript: this.data.outputText, outputText: this.data.transcript });
},
// --- Unified Native Recorder Initialization ---
initNativeRecorderManager: function () {
nativeRecorderManager.onStart = () => {
this.setData({ transcript: '正在聆听...', outputText: '' });
};
nativeRecorderManager.onStop = (res) => {
this.setData({ isRecording: false });
if (res.tempFilePath) {
// ALL recordings go to the HF backend for ASR
this.uploadAudioForASR(res.tempFilePath);
} else {
showDetailedError('录音失败', '未能获取到有效的录音文件路径。');
}
};
nativeRecorderManager.onError = (res) => {
this.setData({ isRecording: false });
showDetailedError('录音发生错误', res);
};
},
// --- Main Record Button Handler ---
handleRecordToggle: function() {
if (this.data.isRecording) {
this.stopRecording();
return;
}
// Check permissions before starting
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)
});
},
// --- Unified Start/Stop Recording ---
startRecording: function () {
this.setData({ isRecording: true });
nativeRecorderManager.start({ format: 'mp3', sampleRate: 16000, numberOfChannels: 1 });
},
stopRecording: function () {
this.setData({ isRecording: false });
nativeRecorderManager.stop();
},
// --- Unified Backend ASR & Translation Flow ---
uploadAudioForASR: function (filePath) {
this.setData({ transcript: '正在识别 (1/2)...' });
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 });
// After ASR, ALL translations go to the HF backend
this.translateViaHfBridge(transcript, this.data.sourceLang, this.data.targetLang);
} else {
showDetailedError('语音识别失败', asrRes.data);
}
},
fail: (err) => showDetailedError('识别请求失败', err)
});
}});
},
translateViaHfBridge: function(text, source, target) {
if (source === target) {
return this.setData({ outputText: text });
}
this.setData({ outputText: '正在翻译 (2/2)...' });
wx.request({
url: `${this.data.hfSpaceUrl}/api/translate`,
method: 'POST',
data: { "text": text, "source_lang": source, "target_lang": target },
timeout: 45000,
success: (res) => {
if (res.statusCode === 200 && res.data.translated_text) {
this.setData({ outputText: res.data.translated_text });
} else {
showDetailedError('翻译失败', res.data);
}
},
fail: (err) => showDetailedError('翻译请求失败', err)
});
}
});
|