HarmonyOS NEXT 语音搜索场景学习和总结

在HarmonyOS中实现语音搜索功能时,涉及到麦克风权限的申请、音频数据的采集、编码和传输等多个步骤。以下是对上述代码的详细解析和补充说明:

1. 麦克风权限的申请与检查

在HarmonyOS中,使用麦克风需要申请ohos.permission.MICROPHONE权限。在代码中,通过GRPermissionsUtils.checkPermissions方法来检查和申请权限。如果权限被授予,则可以继续进行音频采集操作。

GRPermissionsUtils.checkPermissions(permission).then((grantStatus: abilityAccessCtrl.GrantStatus) => {
    GRLog.info(this.TAG, 'startRecord checkPermissions then: ${grantStatus}');
    if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
        // 权限已授予,继续音频采集操作
    }
}).catch((error: BusinessError) => {
    // 处理权限申请失败的情况
});

2. 音频采集配置

在权限授予后,需要配置音频采集的参数,包括采样率、声道数、采样格式等。这些参数决定了音频数据的质量和格式。

let audioStreamInfo: audio.AudioStreamInfo = {
    samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000, // 采样率16kHz
    channels: audio.AudioChannel.CHANNEL_1, // 单声道
    sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 16位采样格式
    encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 原始编码类型
};

let audioCaptureInfo: audio.AudioCapturerInfo = {
    source: audio.SourceType.SOURCE_TYPE_MIC, // 音频源为麦克风
    capturerFlags: 0
};

let audioCaptureOptions: audio.AudioCapturerOptions = {
    streamInfo: audioStreamInfo,
    capturerInfo: audioCaptureInfo
};

3. 创建音频采集器并开始采集

通过audio.createAudioCapturer方法创建音频采集器,并开始采集音频数据。采集到的音频数据会通过回调函数audioCaptureStartReceiver进行处理。

audio.createAudioCapturer(audioCaptureOptions, (error: BusinessError, capture: audio.AudioCapturer) => {
    if (error) {
        GRLog.info(this.TAG, 'startRecord createAudioCapturer error: ${JSON.stringify(error)}');
        // 处理麦克风权限被拒绝或采集器创建失败的情况
    } else {
        this.audioRecord = capture;
        this.audioRecord.off('readData', this.audioCaptureStartReceiver);
        this.audioRecord.on('readData', this.audioCaptureStartReceiver);
        this.audioRecord.start();
        this.mStartTime = systemDateTime.getTime(false);
    }
});

4. 音频数据处理

audioCaptureStartReceiver回调函数中,处理采集到的音频数据。每0.1秒发送一个数据包,并将音频数据进行Base64编码后发送到服务端进行解码和敏感词检测。

private audioCaptureStartReceiver = (result: ArrayBuffer) => {
    GRLog.info(this.TAG, 'audioCaptureStartReceiver result:${result.byteLength}');
    try {
        // 计算录音时长
        let durationTime = systemDateTime.getTime(false) - this.mStartTime;
        if (durationTime > this.mMaxRecordTime) {
            this.isRecordTimeOut = true;
            // 提示用户录音时间过长
            return;
        }

        // 将音频数据添加到缓冲区
        this.tmpRecordBuffers.push(buffer.from(result.slice(0, result.byteLength)));
        this.tmpBufsize += result.byteLength;

        // 当缓冲区达到一定大小或录音结束时,发送数据
        if (this.tmpBufsize >= this.recordBufsize || 
            (this.isStopRecord && this.tmpBufsize > 0 && this.tmpBufsize < this.recordBufsize && this.tmpRecordBuffers.length > 0)) {
            let tmpResult = buffer.concat(this.tmpRecordBuffers).buffer;
            let read: number = tmpResult.byteLength;
            // 将音频数据添加到发送队列
            this.addAudio(tmpResult, read);
            this.tmpRecordBuffers = [];
            this.tmpBufsize = 0;
        }
    } catch (e) {
        // 处理异常
    }
}

5. PCM文件每帧容量的计算

PCM文件的每帧容量(单位:字节数)可以通过以下公式计算:

采样频率 * 采样位数 * 声道数 * 时间 / 8

例如,采样频率为16kHz,采样位数为16位,声道数为1,时间为0.1秒时,每帧容量为:

16000 * 16 * 1 * 0.1 / 8 = 3200字节

6. 音频数据的Base64编码与传输

在发送音频数据之前,通常会将音频数据进行Base64编码,以确保数据在传输过程中不会丢失或损坏。编码后的数据可以通过HTTP请求发送到服务端进行解码和进一步处理。

7. 敏感词检测

服务端在接收到音频数据后,会进行解码并检测是否存在敏感词。如果检测到敏感词,服务端可以返回相应的提示信息,客户端可以根据返回结果进行相应的处理。

8. 补充与优化

  • 错误处理:在实际应用中,需要增加更多的错误处理逻辑,例如网络请求失败、服务端解码失败等情况。
  • 性能优化:对于长时间录音的场景,可以考虑对音频数据进行压缩,以减少数据传输量。
  • 用户体验:可以在录音过程中增加实时反馈,例如显示录音时长、音量大小等,提升用户体验。

总结

HarmonyOS提供了丰富的API来支持语音搜索功能的开发。通过合理的权限管理、音频采集配置、数据处理和传输,可以实现高效、稳定的语音搜索功能。后续可以根据实际需求进一步优化和扩展功能。

#商务##Ark-TS语言#
全部评论

相关推荐

头像 会员标识
2025-12-08 16:04
门头沟学院 Java
本人本科末9,今年大三。大一大二一直玩,什么都没学到,在大学混日子混了两年,每天不是在打农就是在steam。大三开学时一个和自己玩的好的同学去实习了,才发现自己白白浪费了两年的时间,如果真不冲一下就真去京东,阿里,美团送外卖了今年9月份开始学Java,一开始一直跟着黑马视频看,后面发现看视频效率太低了,时间根本不够,就开始主要看文档和看书了。这几个月一直在学,真的尽力了,希望暑期前能找一份好点的实习。我简历上面的项目大多没有指标,但是实际上我是真没多少时间去做项目,我基本主要是动手只做了外卖和天机,黑马点评和12306我都是只是看了项目。主要是自己的时间真的不多,但是这样子自己的代码能力确实比较差。而且自己也没有做过实际的工程,我顶多用jmeter测试一下接口tps啥的,比如使用Redis管道提升了一点性能,减少Redis交互,这种值得写上去吗?需不需要具体到某些数字求求各位佬给一些建议,看看简历怎么优化?项目介绍是不是不够详细?没有具体到业务方面。项目会不会提到大致实现原理导致面试官一看简历就知道怎么实现就没有问的欲望?专业技能一些字段是不是要加粗,是不是写太啰嗦了?有没有必要压缩内容变成一页?两页的话是不是都要把两页填地满满的。
给秋招一个交代:一页简历最好,网上做的项目放面试官眼里都是玩具,简历上不需要强调有什么难点,记住就行防止真的问。然后背八股,多投多面试就行
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务