HarmonyOS鸿蒙Next模拟器语音输入问题

HarmonyOS鸿蒙Next模拟器语音输入问题 有没有朋友跟我一样语音输入使用不了的,小艺输入法的语音识别使用不了

cke_252.png 代码里面录音功能使用报错,写入文件0kb

import { audio } from "@kit.AudioKit";
import { fileIo } from "@kit.CoreFileKit";

class Options {
  offset?: number;
  length?: number;
}
export default class AudioCapture {

  static audioCaptureInstance: audio.AudioCapturer


  static 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
  };

  static audioCapturerInfo: audio.AudioCapturerInfo = {
    source: audio.SourceType.SOURCE_TYPE_MIC, // 音源类型:Mic音频源。根据业务场景配置,参考SourceType。
    capturerFlags: 0 // 音频采集器标志。
  };

  static  audioCapturerOptions: audio.AudioCapturerOptions = {
    streamInfo: AudioCapture.audioStreamInfo,
    capturerInfo:AudioCapture.audioCapturerInfo
  }

  // 录制的状态
  static recording:boolean = false;

  // 当前录音的文件描述符
  static currentFileFd: number = -1;
  /**
   * 初始化录音管理器
   */
  static async  init () {
    if(AudioCapture.audioCaptureInstance) {
      return;
    }
    AudioCapture.audioCaptureInstance = await audio.createAudioCapturer(AudioCapture.audioCapturerOptions)
  }

  static async start(filePath: string) {
    try {
      if (!AudioCapture.audioCaptureInstance) {
        await AudioCapture.init();
      }

      console.log('[AudioCapture] 开始录音,文件路径:', filePath)

      // 打开或创建音频文件
      let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
      AudioCapture.currentFileFd = file.fd
      let bufferSize: number = 0

      console.log('[AudioCapture] 文件已打开,fd:', AudioCapture.currentFileFd)

      // 设置录音状态
      AudioCapture.recording = true

      // 启动音频采集器
      await AudioCapture.audioCaptureInstance.start()
      console.log('[AudioCapture] 音频采集器已启动')

      // 循环读取音频数据并写入文件
      while (AudioCapture.recording) {
        try {
          // 获取缓冲区大小
          let size = await AudioCapture.audioCaptureInstance.getBufferSize()
          // 读取音频数据
          let buffer = await AudioCapture.audioCaptureInstance.read(size, true)

          if (buffer && buffer.byteLength > 0) {
            // 写入文件
            let options: Options = {
              offset: bufferSize,
              length: buffer.byteLength
            }
            fileIo.writeSync(AudioCapture.currentFileFd, buffer, options)
            bufferSize += buffer.byteLength

            console.log('[AudioCapture] 写入音频数据:', buffer.byteLength, '字节,总计:', bufferSize, '字节')
          }
        } catch (err) {
          console.error('[AudioCapture] 读取或写入音频数据失败:', err)
        }
      }

      console.log('[AudioCapture] 录音循环结束,总大小:', bufferSize, '字节')

    } catch (e) {
      console.error('[AudioCapture] 启动录音失败:', e)
    }
  }


  /**
   * 结束录音的方法
   */
  static async stop() {
    console.log('[AudioCapture] 停止录音')

    // 先设置标志位,停止 while 循环
    AudioCapture.recording = false

    if (AudioCapture.audioCaptureInstance) {
      try {
        // 停止音频采集器
        await AudioCapture.audioCaptureInstance.stop()
        console.log('[AudioCapture] 音频采集器已停止')
      } catch (err) {
        console.error('[AudioCapture] 停止音频采集器失败:', err)
      }
    }

    // 关闭并刷新文件(确保数据写入磁盘)
    if (AudioCapture.currentFileFd !== -1) {
      try {
        // 刷新文件缓冲区,确保数据写入磁盘
        fileIo.fsyncSync(AudioCapture.currentFileFd)
        console.log('[AudioCapture] 文件缓冲区已刷新')

        // 关闭文件
        fileIo.closeSync(AudioCapture.currentFileFd)
        console.log('[AudioCapture] 文件已关闭')

        AudioCapture.currentFileFd = -1
      } catch (err) {
        console.error('[AudioCapture] 关闭文件失败:', err)
      }
    }
  }

  static async release() {
    console.log('[AudioCapture] 释放音频采集器资源')

    // 确保录音已停止
    if (AudioCapture.recording) {
      await AudioCapture.stop()
    }

    if (AudioCapture.audioCaptureInstance) {
      try {
        await AudioCapture.audioCaptureInstance.release()
        console.log('[AudioCapture] 音频采集器资源已释放')
      } catch (err) {
        console.error('[AudioCapture] 释放音频采集器失败:', err)
      }
    }
  }


}

报错信息 cke_75648.png

写入文件大小0KB


更多关于HarmonyOS鸿蒙Next模拟器语音输入问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

12 回复

【解决方案】

模拟器当前仅支持Audio Kit(音频服务)提供的音频输入能力,您可以使用本地计算机上的麦克风设备向模拟器中传输音频数据。参考音频输入使用步骤如下:

  1. 首先,请确保本地计算机已连接上麦克风设备。
  2. 应用调用Audio Kit提供的API接口(如AudioCapturer、OHAudio)开始接收音频数据。
  3. 使用本地麦克风进行语音输入。

更多关于HarmonyOS鸿蒙Next模拟器语音输入问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


目前DevEco Studio中的音频输入仅支持通过PC设备麦克风进行,检查麦克风是否可以正常使用,也可以通过耳机等其他音频设备进行调试,可能受限于系统架构原因,目前不支持小艺输入法的音频输入

核心原因分析 在鸿蒙模拟器环境中,由于硬件和权限限制,小艺输入法的语音识别功能可能无法正常调用。模拟器缺乏物理麦克风设备,且未开放完整的语音输入权限,导致语音输入失效。


✅ 解决方案

1. 启用虚拟麦克风(推荐尝试)

  • 在模拟器设置中开启虚拟音频设备:
    • 打开DevEco Studio → 进入Device Manager → 选择模拟器设备 → 点击 “Edit” 按钮
    • “Hardware” 选项卡中勾选 “Microphone” 启用虚拟麦克风
  • 注意:部分模拟器版本可能仍需物理设备支持,此方法仅解决基础权限问题。

尝试一下拿耳机有线或者蓝牙耳机 都行,甚至可以用音响试试

在win环境下,模拟器还不支持小艺上的语音功能,目前只在arm电脑上支持该功能

【解决方案】

目前模拟器上没有实际的麦克风,需要调用主机的麦克风,模拟器当前仅支持Audio Kit(音频服务)提供的音频输入能力,可以使用本地计算机上的麦克风设备向模拟器中传输音频数据。使用步骤如下:

  1. 首先,请确保本地计算机已连接上麦克风设备。
  2. 应用调用Audio Kit提供的API接口(如AudioCapturer、OHAudio)开始接收音频数据。
  3. 使用本地麦克风进行语音输入。

【背景知识】

音频输入

有试过切换麦克风设备排查过吗,也可能是当前系统的驱动和模拟器不兼容。

是 6.0.0 Beta1 以上的 deveco studio 吗?如果是的话检查电脑的麦克风隐私设置有没有打开。

DevEco Studio 6.0.0 Beta1

以下Kit支持在模拟器上使用:

  • Core Speech Kit(基础语音服务)

你好,电脑麦克风权限开着的,但是模拟器似乎是用不了,直接使用模拟器的小艺输入法的空格长按语音输入功能,提示声音识别失败,长按的时候电脑下面也没有麦克风输入的提示,但是其他应用正常使用麦克风没问题……

什么系统中运行的模拟器?模拟器开了录音权限了吗?

你好,电脑麦克风权限开着的,但是模拟器似乎是用不了,直接使用模拟器的小艺输入法的空格长按语音输入功能,提示声音识别失败,长按的时候电脑下面也没有麦克风输入的提示,但是其他应用正常使用麦克风没问题……win11似乎没找到单独开某个应用的麦克风权限,只看到开桌面应用,也就是所有应用都能使用……

鸿蒙Next模拟器语音输入问题通常涉及权限配置或模拟器功能限制。请检查开发工具中的模拟器设置,确保已启用麦克风权限。若问题持续,可尝试更新模拟器版本或重启开发环境。部分情况下需确认系统音频驱动正常。

根据您提供的代码和错误信息,问题核心在于HarmonyOS Next模拟器(Simulator)不支持真实的麦克风硬件访问。这与您遇到的小艺输入法语音识别无法使用是同一类问题。

根本原因分析:

  1. 模拟器限制:HarmonyOS Next Simulator 是一个纯软件仿真环境,没有物理麦克风设备。当应用通过 @kit.AudioKit 请求 SOURCE_TYPE_MIC 音频源时,系统无法提供真实的音频输入流。
  2. 代码表现:您的 AudioCapturer 成功创建并启动,但在执行 read(size, true) 时,由于没有实际音频数据,该方法会等待直至超时,最终抛出 BusinessError 401(表示操作超时)。这导致 buffer 为空或无效,后续写入文件的数据长度为0,生成0KB文件。
  3. 小艺输入法问题:同理,系统级语音识别服务在模拟器环境下也无法获取音频输入,导致功能不可用。

解决方案与验证步骤:

方案一:使用真机进行语音功能开发与测试 这是最直接、最可靠的解决方案。HarmonyOS Next 的许多硬件相关特性(如麦克风、听筒、蓝牙、NFC等)都必须在真实设备上才能完整运行和调试。

  • 将您的应用安装到HarmonyOS Next开发者预览版真机上。
  • 在项目中配置真机调试签名。
  • 使用DevEco Studio的真机调试功能运行应用,语音输入功能应能正常工作。

方案二:在模拟器中模拟音频输入(用于测试非录音核心逻辑) 如果仅需测试应用除录音外的其他逻辑(如UI交互、文件处理流程),可以修改代码,绕过对真实麦克风的依赖。

  • 修改音频源:将 audioCapturerInfo 中的 sourceSOURCE_TYPE_MIC 暂时改为 SOURCE_TYPE_VOICE_RECOGNITION。此源在模拟器中可能更容易初始化,但仍可能无法获取有效数据
    static audioCapturerInfo: audio.AudioCapturerInfo = {
        source: audio.SourceType.SOURCE_TYPE_VOICE_RECOGNITION, // 修改音源类型
        capturerFlags: 0
    };
    
  • 注入模拟数据:更可行的方法是在模拟器环境下,不启动真正的 AudioCapturer,而是通过一个定时器模拟生成或从本地资源文件读取一段音频数据(PCM格式),并调用后续的文件写入逻辑。这需要您区分运行环境(模拟器/真机)。

代码调试建议:

start 方法的 while 循环内,read 调用前后添加更详细的日志:

console.log('[AudioCapture] 准备读取,缓冲区大小:', size);
let buffer = await AudioCapture.audioCaptureInstance.read(size, true);
console.log('[AudioCapture] 读取完成,buffer状态:', buffer, 'byteLength:', buffer?.byteLength);

在模拟器上,您很可能会看到 read 操作长时间挂起后报错,bufferundefinedbyteLength 为 0。

结论: 您遇到的语音输入失效和录音生成0KB文件的问题,是HarmonyOS Next 模拟器环境的已知限制。要完整开发并测试语音相关功能,必须使用HarmonyOS Next真机。请将开发与测试环境切换至已升级至开发者预览版的真机设备。

回到顶部