
鸿蒙5 AI语音备忘录开发实战:语音转写与多设备同步 原创
鸿蒙5 AI语音备忘录开发实战:语音转写与多设备同步
一、项目概述与架构设计
本AI语音备忘录基于鸿蒙5的AI语音识别和分布式能力实现,主要功能包括:
实时语音转文字记录
备忘录内容多设备同步
语音指令控制
智能分类与搜索
技术架构图
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
手机设备 │ │ 平板设备 │ │ 手表设备 │
┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ 语音输入 │─┼───▶│ │ 文本显示 │ │ │ │ 快速查看 │ │
└────────┘ │ │ └────────┘ │ │ └────────┘ │
└───────┬─────┘ └───────┬─────┘ └───────┬─────┘
│ │
└─────────┬────────┴─────────┬────────┘
│
┌───────▼───────┐ ┌───────▼───────┐
分布式数据服务 │ │ AI语音服务 │
└───────────────┘ └───────────────┘
二、核心代码实现
语音识别服务封装
// VoiceService.ets
import asr from ‘@ohos.ai.asr’;
import distributedData from ‘@ohos.data.distributedData’;
export class VoiceService {
private asrEngine: asr.AsrEngine;
private kvStore: distributedData.KVStore;
private readonly STORE_ID = ‘voice_memo_store’;
async init() {
// 初始化语音识别引擎
const config: asr.AsrConfig = {
language: ‘zh-CN’,
feature: asr.AsrFeature.FEATURE_WORD_FLUX,
audioFormat: {
sampleRate: 16000,
channelCount: 1,
sampleFormat: asr.AudioSampleFormat.SAMPLE_FORMAT_S16LE
};
this.asrEngine = await asr.createAsrEngine(config);
// 初始化分布式数据
const kvManager = await distributedData.createKVManager({
bundleName: 'com.example.voicememo'
});
this.kvStore = await kvManager.getKVStore(this.STORE_ID, {
createIfMissing: true,
autoSync: true
});
async startRecording(callback: (text: string) => void) {
// 设置识别结果回调
this.asrEngine.on('result', (result: asr.AsrResult) => {
if (result.text) {
callback(result.text);
this.syncTranscript(result.text);
});
await this.asrEngine.start();
async stopRecording() {
await this.asrEngine.stop();
private async syncTranscript(text: string) {
try {
await this.kvStore.put(memo_${Date.now()}, JSON.stringify({
text,
deviceId: deviceInfo.deviceId,
timestamp: new Date().getTime()
}));
catch (err) {
console.error('同步备忘录失败:', err);
}
subscribeTranscriptChanges(callback: (text: string) => void) {
this.kvStore.on(‘dataChange’, distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (changes) => {
changes.forEach(change => {
if (change.key.startsWith(‘memo_’)) {
const data = JSON.parse(change.value);
if (data.deviceId !== deviceInfo.deviceId) {
callback(data.text);
}
});
});
}
备忘录数据模型
// MemoModel.ets
export interface VoiceMemo {
id: string;
text: string;
timestamp: number;
deviceId?: string;
category?: string;
isImportant?: boolean;
export interface MemoCategory {
id: string;
name: string;
color: string;
备忘录主界面
// VoiceMemoPage.ets
@Entry
@Component
struct VoiceMemoPage {
@State memos: VoiceMemo[] = [];
@State isRecording: boolean = false;
@State currentText: string = ‘’;
private voiceService = new VoiceService();
private memoManager = new MemoManager();
aboutToAppear() {
this.voiceService.init();
this.loadMemos();
this.subscribeToUpdates();
build() {
Column() {
// 录音控制区域
RecordControl({
isRecording: this.isRecording,
onStart: this.startRecording.bind(this),
onStop: this.stopRecording.bind(this)
})
// 实时转写文本
if (this.currentText) {
Text(this.currentText)
.fontSize(16)
.padding(10)
// 备忘录列表
MemoList({
memos: this.memos,
onDelete: this.deleteMemo.bind(this),
onCategoryChange: this.changeCategory.bind(this)
})
}
private async startRecording() {
this.isRecording = true;
await this.voiceService.startRecording((text) => {
this.currentText = text;
});
private async stopRecording() {
this.isRecording = false;
await this.voiceService.stopRecording();
if (this.currentText) {
await this.memoManager.saveMemo(this.currentText);
this.currentText = '';
}
private subscribeToUpdates() {
this.voiceService.subscribeTranscriptChanges((text) => {
this.memos = […this.memos, {
id: Date.now().toString(),
text,
timestamp: Date.now()
}];
});
}
三、关键技术创新点
多设备语音指令协同
// 语音指令处理器
class VoiceCommandProcessor {
private commands = {
‘保存’: this.handleSaveCommand,
‘删除’: this.handleDeleteCommand,
‘重要’: this.handleImportantCommand
};
processCommand(text: string, memo: VoiceMemo) {
const command = this.detectCommand(text);
if (command && this.commands[command]) {
this.commandsmemo;
}
private detectCommand(text: string): string | null {
for (const cmd in this.commands) {
if (text.includes(cmd)) {
return cmd;
}
return null;
private async handleSaveCommand(memo: VoiceMemo) {
await memoManager.saveMemo(memo.text);
}
智能分类算法
// 备忘录自动分类
class MemoClassifier {
private categories: MemoCategory[] = [
id: ‘work’, name: ‘工作’, keywords: [‘会议’, ‘项目’, ‘报告’] },
id: ‘personal’, name: ‘个人’, keywords: [‘购物’, ‘家人’, ‘朋友’] },
id: ‘idea’, name: ‘想法’, keywords: [‘创意’, ‘建议’, ‘灵感’] }
];
classifyMemo(text: string): string {
for (const category of this.categories) {
if (category.keywords.some(keyword => text.includes(keyword))) {
return category.id;
}
return 'other';
}
分布式冲突解决
// 备忘录冲突解决
private resolveMemoConflict(local: VoiceMemo, remote: VoiceMemo): VoiceMemo {
// 策略1: 时间戳优先
if (remote.timestamp > local.timestamp) {
return remote;
// 策略2: 设备优先级
const devicePriority = [‘tablet’, ‘phone’, ‘watch’];
if (devicePriority.indexOf(remote.deviceId) > devicePriority.indexOf(local.deviceId)) {
return remote;
// 策略3: 内容长度优先
if (remote.text.length > local.text.length) {
return remote;
return local;
四、完整UI组件实现
录音控制组件
// RecordControl.ets
@Component
struct RecordControl {
@Prop isRecording: boolean;
@Prop onStart: () => void;
@Prop onStop: () => void;
build() {
Column() {
if (this.isRecording) {
Button(‘停止录音’, { type: ButtonType.Capsule })
.width(120)
.height(120)
.onClick(() => this.onStop())
else {
Button('开始录音', { type: ButtonType.Capsule })
.width(120)
.height(120)
.onClick(() => this.onStart())
// 录音动画
if (this.isRecording) {
Row() {
ForEach([1, 2, 3, 4, 5], (i) => {
Rect()
.width(8)
.height(20 + Math.random() * 30)
.fill(Color.Blue)
.margin(2)
.animation({
duration: 300,
iterations: -1,
delay: i * 100
})
})
.margin({ top: 20 })
}
.padding(20)
}
备忘录列表组件
// MemoList.ets
@Component
struct MemoList {
@Prop memos: VoiceMemo[];
@Prop onDelete: (id: string) => void;
@Prop onCategoryChange: (id: string, category: string) => void;
@State categories: MemoCategory[] = [
id: ‘work’, name: ‘工作’, color: ‘#FF5722’ },
id: ‘personal’, name: ‘个人’, color: ‘#2196F3’ },
id: ‘idea’, name: ‘想法’, color: ‘#4CAF50’ }
];
build() {
List() {
ForEach(this.memos, (memo) => {
ListItem() {
Column() {
Text(memo.text)
.fontSize(16)
.margin({ bottom: 5 })
Row() {
Text(this.formatDate(memo.timestamp))
.fontSize(12)
.opacity(0.6)
// 分类标签
if (memo.category) {
Text(this.getCategoryName(memo.category))
.fontSize(12)
.padding(5)
.backgroundColor(this.getCategoryColor(memo.category))
.borderRadius(10)
.margin({ left: 10 })
}
// 操作按钮
Row() {
Button('删除', { type: ButtonType.Text })
.onClick(() => this.onDelete(memo.id))
// 分类选择
Select(this.categories.map(c => ({ value: c.id, text: c.name })))
.selected(memo.category || '')
.onChange((value) => this.onCategoryChange(memo.id, value))
.margin({ left: 10 })
.margin({ top: 5 })
.padding(15)
})
.height(‘60%’)
private formatDate(timestamp: number): string {
return new Date(timestamp).toLocaleString();
}
五、项目部署与测试
权限配置
在module.json5中添加:
“requestPermissions”: [
“name”: “ohos.permission.MICROPHONE”
},
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”
},
“name”: “ohos.permission.ACCESS_AI”
]
测试方案
// 语音识别测试
describe(‘VoiceRecognition’, () => {
it(‘should convert speech to text’, async () => {
const service = new VoiceService();
await service.init();
let result = '';
await service.startRecording((text) => {
result = text;
});
// 模拟音频输入
simulateVoiceInput('测试语音识别');
await service.stopRecording();
expect(result).toContain('测试');
});
});
// 数据同步测试
describe(‘MemoSync’, () => {
it(‘should sync memos between devices’, async () => {
const device1 = new MockDevice(‘device1’);
const device2 = new MockDevice(‘device2’);
await device1.addMemo('测试备忘录');
await device2.waitForSync();
expect(device2.getMemos()).toContainEqual(
expect.objectContaining({ text: '测试备忘录' })
);
});
});
六、总结与扩展
本方案实现了:
基于鸿蒙AI的实时语音转文字
备忘录内容多设备同步
智能分类与语音指令
分布式冲突解决机制
扩展方向:
添加语音情感分析
开发备忘录智能摘要
集成云端备份恢复
支持多语言语音识别
鸿蒙的AI能力与分布式技术结合,为语音类应用开发提供了强大支持。开发者可基于此项目框架探索更多语音交互的创新应用场景。
