
鸿蒙实时翻译器应用开发指南 原创
鸿蒙实时翻译器应用开发指南
一、系统架构设计
基于HarmonyOS的分布式能力和AI技术,我们设计了一套实时翻译系统,主要功能包括:
语音识别:实时识别用户语音输入
文本翻译:调用翻译API进行多语言互译
多设备协同:跨设备同步翻译记录和设置
历史记录:保存翻译历史方便查阅
离线模式:支持基础离线翻译功能
!https://example.com/harmony-translator-arch.png
二、核心代码实现
语音识别服务
// SpeechRecognitionService.ets
import audio from ‘@ohos.multimedia.audio’;
import speech from ‘@ohos.multimedia.speech’;
class SpeechRecognitionService {
private static instance: SpeechRecognitionService;
private audioCapturer: audio.AudioCapturer | null = null;
private speechRecognizer: speech.SpeechRecognizer | null = null;
private isRecognizing: boolean = false;
private constructor() {}
public static getInstance(): SpeechRecognitionService {
if (!SpeechRecognitionService.instance) {
SpeechRecognitionService.instance = new SpeechRecognitionService();
return SpeechRecognitionService.instance;
public async startRecognition(language: string, callback: (text: string) => void): Promise<void> {
if (this.isRecognizing) return;
await this.initAudioCapturer();
await this.initSpeechRecognizer(language);
this.isRecognizing = true;
this.speechRecognizer!.on('result', (result) => {
callback(result.text);
});
await this.speechRecognizer!.start();
public async stopRecognition(): Promise<void> {
if (!this.isRecognizing) return;
await this.speechRecognizer!.stop();
await this.audioCapturer!.release();
this.isRecognizing = false;
private async initAudioCapturer(): Promise<void> {
const audioStreamInfo: audio.AudioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
};
const audioCapturerInfo: audio.AudioCapturerInfo = {
source: audio.SourceType.SOURCE_TYPE_MIC,
capturerFlags: 0
};
this.audioCapturer = await audio.createAudioCapturer({
audioStreamInfo,
audioCapturerInfo
});
await this.audioCapturer.start();
private async initSpeechRecognizer(language: string): Promise<void> {
this.speechRecognizer = speech.createSpeechRecognizer();
const config: speech.SpeechRecognizerConfig = {
language: this.getLanguageCode(language),
feature: speech.SpeechRecognizerFeature.FEATURE_WORD_FLUX
};
await this.speechRecognizer.setConfig(config);
private getLanguageCode(language: string): string {
const languageMap: Record<string, string> = {
'中文': 'zh-CN',
'English': 'en-US',
'日本語': 'ja-JP',
'한국어': 'ko-KR',
'Français': 'fr-FR',
'Español': 'es-ES'
};
return languageMap[language] || 'en-US';
}
export const speechRecognitionService = SpeechRecognitionService.getInstance();
翻译服务
// TranslationService.ets
import http from ‘@ohos.net.http’;
class TranslationService {
private static instance: TranslationService;
private httpClient: http.HttpRequest;
private apiKey = ‘YOUR_TRANSLATION_API_KEY’;
private constructor() {
this.httpClient = http.createHttp();
public static getInstance(): TranslationService {
if (!TranslationService.instance) {
TranslationService.instance = new TranslationService();
return TranslationService.instance;
public async translateText(text: string, sourceLang: string, targetLang: string): Promise<TranslationResult> {
return new Promise((resolve, reject) => {
this.httpClient.request(
'https://translation-api.example.com/translate',
method: ‘POST’,
header: { 'Content-Type': 'application/json' },
extraData: JSON.stringify({
text,
source_lang: sourceLang,
target_lang: targetLang,
api_key: this.apiKey
})
},
(err, data) => {
if (err) {
reject(err);
else {
const result = JSON.parse(data.result);
resolve(this.processTranslationResult(result));
}
);
});
private processTranslationResult(rawData: any): TranslationResult {
return {
originalText: rawData.original_text,
translatedText: rawData.translated_text,
sourceLanguage: rawData.source_lang,
targetLanguage: rawData.target_lang,
confidence: rawData.confidence || 0,
timestamp: Date.now()
};
public getSupportedLanguages(): Language[] {
return [
code: ‘zh’, name: ‘中文’ },
code: ‘en’, name: ‘English’ },
code: ‘ja’, name: ‘日本語’ },
code: ‘ko’, name: ‘한국어’ },
code: ‘fr’, name: ‘Français’ },
code: ‘es’, name: ‘Español’ },
code: ‘de’, name: ‘Deutsch’ },
code: ‘ru’, name: ‘Русский’ }
];
}
export const translationService = TranslationService.getInstance();
多设备同步服务
// TranslationSyncService.ets
import distributedData from ‘@ohos.data.distributedData’;
class TranslationSyncService {
private static instance: TranslationSyncService;
private kvManager: distributedData.KVManager;
private kvStore: distributedData.KVStore;
private constructor() {
this.initKVStore();
private async initKVStore(): Promise<void> {
const config = {
bundleName: 'com.example.realTimeTranslator',
userInfo: { userId: 'currentUser' }
};
this.kvManager = distributedData.createKVManager(config);
this.kvStore = await this.kvManager.getKVStore('translation_store', {
createIfMissing: true
});
this.kvStore.on('dataChange', (data) => {
this.handleRemoteUpdate(data);
});
public static getInstance(): TranslationSyncService {
if (!TranslationSyncService.instance) {
TranslationSyncService.instance = new TranslationSyncService();
return TranslationSyncService.instance;
public async syncTranslation(record: TranslationRecord): Promise<void> {
await this.kvStore.put(translation_${record.id}, JSON.stringify(record));
public async getTranslationHistory(): Promise<TranslationRecord[]> {
const entries = await this.kvStore.getEntries('translation_');
return Array.from(entries)
.map(([_, value]) => JSON.parse(value))
.sort((a, b) => b.timestamp - a.timestamp);
public async syncSettings(settings: AppSettings): Promise<void> {
await this.kvStore.put('app_settings', JSON.stringify(settings));
public async getSettings(): Promise<AppSettings> {
const value = await this.kvStore.get('app_settings');
return value ? JSON.parse(value) : this.getDefaultSettings();
private getDefaultSettings(): AppSettings {
return {
sourceLanguage: 'zh',
targetLanguage: 'en',
voiceOutput: true,
autoCopy: false,
theme: 'light'
};
private handleRemoteUpdate(data: distributedData.ChangeInfo): void {
if (data.deviceId === deviceInfo.deviceId) return;
const key = data.key as string;
if (key.startsWith('translation_')) {
const record = JSON.parse(data.value);
EventBus.emit('translationRecordUpdated', record);
else if (key === ‘app_settings’) {
const settings = JSON.parse(data.value);
EventBus.emit('appSettingsUpdated', settings);
}
export const translationSyncService = TranslationSyncService.getInstance();
三、主界面实现
实时翻译界面
// RealTimeTranslationView.ets
@Component
struct RealTimeTranslationView {
@State sourceLanguage: string = ‘中文’;
@State targetLanguage: string = ‘English’;
@State inputText: string = ‘’;
@State outputText: string = ‘’;
@State isListening: boolean = false;
@State isLoading: boolean = false;
@State history: TranslationRecord[] = [];
aboutToAppear() {
this.loadSettings();
this.loadHistory();
build() {
Column() {
// 语言选择
Row() {
Picker({ range: this.getLanguageOptions(), selected: this.getLanguageIndex(this.sourceLanguage) })
.onChange((index: number) => {
this.sourceLanguage = this.getLanguageOptions()[index];
this.saveSettings();
})
.width('40%')
Image('resources/swap.png')
.width(30)
.height(30)
.onClick(() => this.swapLanguages())
.margin({ left: 8, right: 8 })
Picker({ range: this.getLanguageOptions(), selected: this.getLanguageIndex(this.targetLanguage) })
.onChange((index: number) => {
this.targetLanguage = this.getLanguageOptions()[index];
this.saveSettings();
})
.width('40%')
.margin({ top: 16 })
// 输入区域
TextArea({ placeholder: '输入要翻译的文本...' })
.onChange((value: string) => this.inputText = value)
.height(120)
.margin({ top: 16 })
// 语音输入按钮
Button(this.isListening ? '停止录音' : '语音输入')
.onClick(() => this.toggleVoiceInput())
.width('80%')
.margin({ top: 8 })
// 翻译按钮
Button('翻译')
.onClick(() => this.translateText())
.width('80%')
.margin({ top: 8 })
.enabled(this.inputText.length > 0)
// 加载状态
if (this.isLoading) {
LoadingProgress()
.width(50)
.height(50)
.margin({ top: 16 })
// 翻译结果
if (this.outputText) {
Text(this.outputText)
.fontSize(18)
.margin({ top: 16 })
.padding(16)
.backgroundColor('#F5F5F5')
.borderRadius(8)
.width('100%')
}
.padding(16)
private getLanguageOptions(): string[] {
return translationService.getSupportedLanguages().map(lang => lang.name);
private getLanguageIndex(language: string): number {
return this.getLanguageOptions().indexOf(language);
private async toggleVoiceInput(): Promise<void> {
if (this.isListening) {
await speechRecognitionService.stopRecognition();
else {
await speechRecognitionService.startRecognition(this.sourceLanguage, (text) => {
this.inputText = text;
this.translateText();
});
this.isListening = !this.isListening;
private async translateText(): Promise<void> {
if (!this.inputText.trim()) return;
this.isLoading = true;
try {
const sourceLangCode = translationService.getSupportedLanguages()
.find(l => l.name === this.sourceLanguage)?.code || 'zh';
const targetLangCode = translationService.getSupportedLanguages()
.find(l => l.name === this.targetLanguage)?.code || 'en';
const result = await translationService.translateText(
this.inputText,
sourceLangCode,
targetLangCode
);
this.outputText = result.translatedText;
// 保存记录
const record: TranslationRecord = {
id: generateId(),
sourceText: this.inputText,
translatedText: this.outputText,
sourceLanguage: this.sourceLanguage,
targetLanguage: this.targetLanguage,
timestamp: Date.now()
};
await translationSyncService.syncTranslation(record);
this.history.unshift(record);
catch (error) {
console.error('翻译失败:', error);
this.outputText = '翻译失败,请重试';
finally {
this.isLoading = false;
}
private swapLanguages(): void {
[this.sourceLanguage, this.targetLanguage] = [this.targetLanguage, this.sourceLanguage];
this.saveSettings();
private async loadSettings(): Promise<void> {
const settings = await translationSyncService.getSettings();
this.sourceLanguage = settings.sourceLanguage;
this.targetLanguage = settings.targetLanguage;
private async saveSettings(): Promise<void> {
const settings = await translationSyncService.getSettings();
settings.sourceLanguage = this.sourceLanguage;
settings.targetLanguage = this.targetLanguage;
await translationSyncService.syncSettings(settings);
private async loadHistory(): Promise<void> {
this.history = await translationSyncService.getTranslationHistory();
}
function generateId(): string {
return Math.random().toString(36).substring(2) + Date.now().toString(36);
翻译历史界面
// TranslationHistoryView.ets
@Component
struct TranslationHistoryView {
@State history: TranslationRecord[] = [];
@State searchText: string = ‘’;
aboutToAppear() {
this.loadHistory();
EventBus.on(‘translationRecordUpdated’, () => this.loadHistory());
build() {
Column() {
// 搜索框
TextInput({ placeholder: '搜索历史记录...' })
.onChange((value: string) => {
this.searchText = value;
this.filterHistory();
})
.margin({ top: 16 })
if (this.history.length === 0) {
Text('暂无翻译历史')
.fontSize(16)
.margin({ top: 32 })
else {
List({ space: 10 }) {
ForEach(this.filteredHistory, (record) => {
ListItem() {
TranslationRecordItem({ record })
})
.layoutWeight(1)
}
.padding(16)
private async loadHistory(): Promise<void> {
this.history = await translationSyncService.getTranslationHistory();
this.filteredHistory = [...this.history];
private filterHistory(): void {
if (!this.searchText) {
this.filteredHistory = [...this.history];
return;
const searchLower = this.searchText.toLowerCase();
this.filteredHistory = this.history.filter(record =>
record.sourceText.toLowerCase().includes(searchLower) ||
record.translatedText.toLowerCase().includes(searchLower)
);
}
@Component
struct TranslationRecordItem {
private record: TranslationRecord;
build() {
Column() {
Text(this.record.sourceText)
.fontSize(16)
.fontWeight(FontWeight.Bold)
Text(this.record.translatedText)
.fontSize(14)
.fontColor('#666666')
.margin({ top: 4 })
Row() {
Text({this.record.sourceLanguage} → {this.record.targetLanguage})
.fontSize(12)
.fontColor('#999999')
Text(formatDate(this.record.timestamp))
.fontSize(12)
.fontColor('#999999')
.margin({ left: 16 })
.margin({ top: 8 })
Divider()
.margin({ top: 8 })
.padding(12)
.onClick(() => {
EventBus.emit('showTranslationDetail', this.record);
})
}
function formatDate(timestamp: number): string {
const date = new Date(timestamp);
return {date.getFullYear()}-{date.getMonth() + 1}-{date.getDate()} {date.getHours()}:${date.getMinutes()};
设置界面
// SettingsView.ets
@Component
struct SettingsView {
@State settings: AppSettings = {
sourceLanguage: ‘zh’,
targetLanguage: ‘en’,
voiceOutput: true,
autoCopy: false,
theme: ‘light’
};
aboutToAppear() {
this.loadSettings();
build() {
Column() {
Text('设置')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 16 })
// 语言设置
Text('默认源语言')
.fontSize(16)
.margin({ top: 24 })
Picker({ range: this.getLanguageOptions(), selected: this.getLanguageIndex(this.settings.sourceLanguage) })
.onChange((index: number) => {
this.settings.sourceLanguage = this.getLanguageCodes()[index];
this.saveSettings();
})
.width('100%')
.margin({ top: 8 })
Text('默认目标语言')
.fontSize(16)
.margin({ top: 16 })
Picker({ range: this.getLanguageOptions(), selected: this.getLanguageIndex(this.settings.targetLanguage) })
.onChange((index: number) => {
this.settings.targetLanguage = this.getLanguageCodes()[index];
this.saveSettings();
})
.width('100%')
.margin({ top: 8 })
// 功能设置
Text('功能设置')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ top: 24 })
Row() {
Text('语音输出')
.fontSize(16)
.layoutWeight(1)
Toggle({ type: ToggleType.TOGGLE_TYPE_SWITCH, isOn: this.settings.voiceOutput })
.onChange((isOn: boolean) => {
this.settings.voiceOutput = isOn;
this.saveSettings();
})
.margin({ top: 16 })
Row() {
Text('自动复制结果')
.fontSize(16)
.layoutWeight(1)
Toggle({ type: ToggleType.TOGGLE_TYPE_SWITCH, isOn: this.settings.autoCopy })
.onChange((isOn: boolean) => {
this.settings.autoCopy = isOn;
this.saveSettings();
})
.margin({ top: 8 })
// 主题设置
Text('主题')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ top: 24 })
Row() {
ForEach(['light', 'dark', 'system'], (theme) => {
Column() {
Image(resources/theme_${theme}.png)
.width(60)
.height(60)
.borderRadius(30)
.borderWidth(this.settings.theme === theme ? 2 : 0)
.borderColor('#2196F3')
Text(theme = 'system' ? '系统' : theme = 'light' ? '浅色' : '深色')
.fontSize(14)
.margin({ top: 4 })
.margin({ right: 16 })
.onClick(() => {
this.settings.theme = theme;
this.saveSettings();
})
})
.margin({ top: 8 })
.padding(16)
private getLanguageOptions(): string[] {
return translationService.getSupportedLanguages().map(lang => lang.name);
private getLanguageCodes(): string[] {
return translationService.getSupportedLanguages().map(lang => lang.code);
private getLanguageIndex(languageCode: string): number {
return this.getLanguageCodes().indexOf(languageCode);
private async loadSettings(): Promise<void> {
this.settings = await translationSyncService.getSettings();
private async saveSettings(): Promise<void> {
await translationSyncService.syncSettings(this.settings);
}
四、高级功能实现
多设备协同翻译
// CollaborativeTranslationService.ets
class CollaborativeTranslationService {
private static instance: CollaborativeTranslationService;
private constructor() {}
public static getInstance(): CollaborativeTranslationService {
if (!CollaborativeTranslationService.instance) {
CollaborativeTranslationService.instance = new CollaborativeTranslationService();
return CollaborativeTranslationService.instance;
public async shareTranslation(deviceId: string, record: TranslationRecord): Promise<void> {
const ability = await featureAbility.startAbility({
bundleName: 'com.example.realTimeTranslator',
abilityName: 'TranslationSharingAbility',
deviceId
});
await ability.call({
method: 'receiveTranslation',
parameters: [record]
});
public async syncAllTranslations(deviceId: string): Promise<void> {
const history = await translationSyncService.getTranslationHistory();
const ability = await featureAbility.startAbility({
bundleName: 'com.example.realTimeTranslator',
abilityName: 'TranslationSyncAbility',
deviceId
});
await ability.call({
method: 'receiveMultipleTranslations',
parameters: [history]
});
public async syncSettingsToDevice(deviceId: string): Promise<void> {
const settings = await translationSyncService.getSettings();
const ability = await featureAbility.startAbility({
bundleName: 'com.example.realTimeTranslator',
abilityName: 'SettingsSyncAbility',
deviceId
});
await ability.call({
method: 'receiveSettings',
parameters: [settings]
});
}
export const collaborativeTranslationService = CollaborativeTranslationService.getInstance();
离线翻译功能
// OfflineTranslationService.ets
class OfflineTranslationService {
private static instance: OfflineTranslationService;
private offlineModels: Record<string, any> = {};
private constructor() {
this.initDefaultModels();
private initDefaultModels(): void {
// 加载基础离线模型
this.offlineModels['zh-en'] = require('resources/models/zh_en.json');
this.offlineModels['en-zh'] = require('resources/models/en_zh.json');
public static getInstance(): OfflineTranslationService {
if (!OfflineTranslationService.instance) {
OfflineTranslationService.instance = new OfflineTranslationService();
return OfflineTranslationService.instance;
public isLanguagePairAvailable(source: string, target: string): boolean {
return !!this.offlineModels[{source}-{target}];
public translateOffline(text: string, source: string, target: string): TranslationResult {
const model = this.offlineModels[{source}-{target}];
if (!model) {
throw new Error('离线翻译模型不可用');
// 简化的离线翻译实现
const words = text.split(' ');
const translatedWords = words.map(word =>
model.dictionary[word.toLowerCase()] || word
);
return {
originalText: text,
translatedText: translatedWords.join(' '),
sourceLanguage: source,
targetLanguage: target,
confidence: 0.7, // 离线翻译置信度较低
timestamp: Date.now()
};
public async downloadModel(source: string, target: string): Promise<void> {
const modelKey = {source}-{target};
if (this.offlineModels[modelKey]) return;
try {
const model = await this.downloadModelFromServer(source, target);
this.offlineModels[modelKey] = model;
await this.saveModelToLocal(modelKey, model);
catch (error) {
console.error('下载模型失败:', error);
throw error;
}
private async downloadModelFromServer(source: string, target: string): Promise<any> {
return new Promise((resolve) => {
// 模拟下载
setTimeout(() => {
resolve({
dictionary: {},
rules: {}
});
}, 1000);
});
private async saveModelToLocal(key: string, model: any): Promise<void> {
// 简化实现,实际应使用文件系统API保存
console.log(模型 ${key} 已保存);
}
export const offlineTranslationService = OfflineTranslationService.getInstance();
语音合成服务
// TextToSpeechService.ets
import speech from ‘@ohos.multimedia.speech’;
class TextToSpeechService {
private static instance: TextToSpeechService;
private speechSynthesizer: speech.SpeechSynthesizer | null = null;
private constructor() {}
public static getInstance(): TextToSpeechService {
if (!TextToSpeechService.instance) {
TextToSpeechService.instance = new TextToSpeechService();
return TextToSpeechService.instance;
public async speak(text: string, language: string): Promise<void> {
if (!text.trim()) return;
await this.initSpeechSynthesizer(language);
await this.speechSynthesizer!.speak(text);
public async stopSpeaking(): Promise<void> {
if (this.speechSynthesizer) {
await this.speechSynthesizer.stop();
}
private async initSpeechSynthesizer(language: string): Promise<void> {
if (!this.speechSynthesizer) {
this.speechSynthesizer = speech.createSpeechSynthesizer();
const config: speech.SpeechSynthesizerConfig = {
language: this.getLanguageCode(language),
voice: this.getVoiceForLanguage(language),
speed: 1.0,
volume: 1.0
};
await this.speechSynthesizer.setConfig(config);
private getLanguageCode(language: string): string {
const languageMap: Record<string, string> = {
'中文': 'zh-CN',
'English': 'en-US',
'日本語': 'ja-JP',
'한국어': 'ko-KR',
'Français': 'fr-FR',
'Español': 'es-ES'
};
return languageMap[language] || 'en-US';
private getVoiceForLanguage(language: string): string {
// 简化实现,实际应根据语言选择合适的声音
return 'default';
}
export const ttsService = TextToSpeechService.getInstance();
五、总结
本实时翻译器应用实现了以下核心价值:
实时翻译:语音和文本的即时翻译
多语言支持:支持主流语言的互译
多设备协同:跨设备同步翻译记录和设置
离线功能:无网络时基础翻译能力
语音交互:支持语音输入和输出
扩展方向:
增加AR实时视觉翻译
开发专业领域翻译模型
集成更多社交分享功能
增加翻译质量反馈机制
注意事项:
需要申请ohos.permission.MICROPHONE权限
在线翻译需要网络连接
语音识别准确率受环境噪音影响
部分高级功能可能需要订阅服务
首次使用建议完成引导教程
