鸿蒙实时翻译器应用开发指南 原创

进修的泡芙
发布于 2025-6-22 17:20
浏览
0收藏

鸿蒙实时翻译器应用开发指南

一、系统架构设计

基于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权限

在线翻译需要网络连接

语音识别准确率受环境噪音影响

部分高级功能可能需要订阅服务

首次使用建议完成引导教程

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐