HandleCapturerRead Wait timeout and Error in HarmonyOS 鸿蒙Next: [Read]HandleCapturerRead err -62980096 Capturer stop: ERROR system error

发布于 1周前 作者 gougou168 来自 鸿蒙OS

HandleCapturerRead Wait timeout and Error in HarmonyOS 鸿蒙Next: [Read]HandleCapturerRead err -62980096 Capturer stop: ERROR system error 求助大佬!!!!

使用AudioCapturer录制音频,AudioCapturer可以成功create并且成功start,使用事件监听readData来获取数据

问题一:

每次在readDate触发之后会出现以下两行报错,并且获取到的ArrayBuffer Uint8之后显示都是0:

[HandleCapturerRead]Wait timeout

[Read]HandleCapturerRead err : -62980096

问题二:

在stop的时候经常显示以下两行报错(有时候没有报错),显示system error

[StopAudioStream]Stop failed: timeout Operation:0 result:0.
【AudioCapturer】: Capturer stop: ERROR: Error: system error

以下是我的一些代码,是根据官方给的示例自己封装的AudioCapturer类,调用的时候确保了麦克风权限的获取,确保了capturer create成功、start成功

import { audio } from '@kit.AudioKit';
import { BusinessError } from '@kit.BasicServicesKit';

const recordChunks: ArrayBuffer[] = [];

export default class AudioCapturer {
  private audioCapturer: audio.AudioCapturer | undefined = undefined;
  private 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 // 音频编码类型
  };
  private audioCapturerInfo: audio.AudioCapturerInfo = {
    source: audio.SourceType.SOURCE_TYPE_MIC, // 音源类型
    capturerFlags: 0 // 音频采集器标志
  };
  private audioCapturerOptions: audio.AudioCapturerOptions = {
    streamInfo: this.audioStreamInfo,
    capturerInfo: this.audioCapturerInfo
  };

  // 初始化,创建实例,设置监听事件
  constructor() {
    audio.createAudioCapturer(this.audioCapturerOptions).then(data => {
      this.audioCapturer = data;
      console.info('【AudioCapturer】AudioCapturer Created : Success : Stream Type: SUCCESS');
      this.audioCapturer.on('readData', buf => {
        let view = new Uint32Array(buf);
        console.info('【AudioCapturer】: readData: SUCCESS', view)
        recordChunks.push(buf);
      })
      this.audioCapturer.on('stateChange', state => {
        switch(state) {
          case 0:
            console.info('【AudioCapturer】state is: STATE_NEW');
            break;
          case 1:
            console.info('【AudioCapturer】state is: STATE_PREPARED');
            break;
          case 2:
            console.info('【AudioCapturer】state is: STATE_RUNNING');
            break;
          case 3:
            console.info('【AudioCapturer】state is: STATE_STOPPED');
            break;
          case 4:
            console.info('【AudioCapturer】state is: STATE_RELEASED');
            break;
          case 5:
            console.info('【AudioCapturer】state is: STATE_PAUSED');
            break;
        }
      });
    }).catch(err => {
      console.error(`【AudioCapturer】AudioCapturer Created : ERROR : ${err}`);
    });
  }

  // 开始一次音频采集
  async start() {
    if (this.audioCapturer !== undefined) {
      let stateGroup = [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED];
      if (stateGroup.indexOf((this.audioCapturer as audio.AudioCapturer).state.valueOf()) === -1) { // 当且仅当状态为STATE_PREPARED、STATE_PAUSED和STATE_STOPPED之一时才能启动采集
        console.error(`【AudioCapturer】: start failed, state is ${this.audioCapturer?.state.valueOf()}`);
        return;
      }

      // 启动采集
      this.audioCapturer.start().then(() => {
        console.info('【AudioCapturer】: ---------START---------');
        console.info('【AudioCapturer】: Capturer started: SUCCESS');
        console.info(`【AudioCapturer】: AudioCapturer: STATE: ${this.audioCapturer?.state}`);
        if ((this.audioCapturer?.state == audio.AudioState.STATE_RUNNING)) {
          console.info('【AudioCapturer】: AudioCapturer is in Running State');
        }
      }).catch(err => {
        console.error(`【AudioCapturer】: Capturer start :ERROR : ${err}`);
      });
    }
  }

  // 停止采集
  async stop() {
    if (this.audioCapturer !== undefined) {
      // 只有采集器状态为STATE_RUNNING或STATE_PAUSED的时候才可以停止
      if ((this.audioCapturer as audio.AudioCapturer).state.valueOf() !== audio.AudioState.STATE_RUNNING && (this.audioCapturer as audio.AudioCapturer).state.valueOf() !== audio.AudioState.STATE_PAUSED) {
        console.info('【AudioCapturer】Capturer is not running or paused');
        return;
      }

      //停止采集
      this.audioCapturer.stop().then(() => {
        console.info('【AudioCapturer】: ---------STOP RECORD---------');
        console.info('【AudioCapturer】: Capturer stopped: SUCCESS');
        if ((this.audioCapturer?.state == audio.AudioState.STATE_STOPPED)){
          console.info('【AudioCapturer】: State is Stopped:');
        }
      }).catch(err => {
        console.error(`【AudioCapturer】: Capturer stop: ERROR: ${err}`);
      });
    }
    console.info('【AudioCapturer】: recordChunks', recordChunks)
  }
  // 销毁实例,释放资源
  async release() {
    if (this.audioCapturer !== undefined) {
      // 采集器状态不是STATE_RELEASED或STATE_NEW状态,才能release
      if ((this.audioCapturer as audio.AudioCapturer).state.valueOf() === audio.AudioState.STATE_RELEASED ||
        (this.audioCapturer as audio.AudioCapturer).state.valueOf() === audio.AudioState.STATE_NEW) {
        console.info('【AudioCapturer】Capturer already released');
        return;
      }

      //释放资源
      this.audioCapturer.release().then(() => {
        console.info('【AudioCapturer】: ---------RELEASE RECORD---------');
        console.info('【AudioCapturer】: Capturer release : SUCCESS');
        console.info(`【AudioCapturer】: AudioCapturer : STATE : ${this.audioCapturer?.state}`);
      }).catch(err => {
        console.error(`【AudioCapturer】: Capturer stop: ERROR: ${err}`);
      });
    }
  }
}

更多关于HandleCapturerRead Wait timeout and Error in HarmonyOS 鸿蒙Next: [Read]HandleCapturerRead err -62980096 Capturer stop: ERROR system error的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

20 回复

我遇到了一模一样的问题,请问楼主最后的问题解决否?

更多关于HandleCapturerRead Wait timeout and Error in HarmonyOS 鸿蒙Next: [Read]HandleCapturerRead err -62980096 Capturer stop: ERROR system error的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


cke_168.png

我用你的代码,模拟器直接跑的,但是看着是没问题的。而且你上面说的,start和stop时的日志,我这边和你的也不一样,不会出现你上面日志。IDE 5.0.3.906版本,模拟器配套模拟器,和你的一样

这确实是很奇怪,提了工单,技术人员好像也复现不了,不知道是不是我的电脑有问题,我用AudioRecorder捕获音频stop的时候也会发生错误,不知道是不是因为同一个原因导致的录制失败QAQ,

项目简介

  • 名称:AVRecorder
  • 作者:未知
  • 编程语言:Swift
  • 开源许可:MIT
  • 功能:录制音频和视频

使用说明

  1. 初始化AVRecorder对象。
  2. 配置录制参数。
  3. 开始录制。
  4. 停止录制并保存文件。

这里也附上报错的代码的网盘链接:链接 提取码: s8p5

操作流程是:初始化录音器、开始录制、停止录制、销毁录音器,可以用[AudioCapturer]来统一查看audioCaputrer的日志输出

  1. start函数调试过程,在read函数的地方触发错误并被捕获,没有buffer数据返回

cke_142.png

改造之后,有问题的demo可以发下吗?

项目名称

  • 项目状态:进行中
  • 项目周期:2023-01-01到2023-12-31

项目描述

这是项目的详细描述。

团队成员

  • 成员A
  • 成员B
  • 成员C

联系方式

  • 邮箱:example@example.com
  • 电话:1234567890

我将改造后的整个项目都打包放到云盘方便下载了,辛苦您了!

https://pan.baidu.com/s/1Sefu9JydgcvIPwormXjeMA?pwd=5f9e

提取码: 5f9e

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

我这边使用模拟器,把asrEngine都注释了,没有出现你说的报错。

操作步骤和你也一样,

  1. 点击startRecording(这个时候audioCapturer init)
  2. 点击audioToText(这个时候audioCapturer start)

IDE版本:5.0.3.906

模拟器 :HarmonyOS 5.0.0 x86

模拟器重装一个试试呢,我的模拟器配置和你一样,刚安装的,

图片

  1. 已尝试重新安装模拟器
  2. 已确认模拟器可以获取到麦克风(通过audioRoutingManager API)
  3. 获取输入设备信息如下:
【AudioCapturer】deviceRole: 1, deviceType: 15, id: 2, name: 
【AudioCapturer】address: , sampleRates: 48000, channelCounts: 2, channelMasks: 0
【AudioCapturer】displayName: emulator, encodingTypes: 0
  1. 获取输入设备的代码如下:
import { audio } from '@kit.AudioKit';
let audioManager = audio.getAudioManager();  
let audioRoutingManager = audioManager.getRoutingManager();  
audioRoutingManager.getDevices(audio.DeviceFlag.INPUT_DEVICES_FLAG).then((data: audio.AudioDeviceDescriptors) => {
  console.info('【AudioCapturer】device list');
  data.forEach(v => {
    // 1 15 输入设备 麦克风类型
    console.info(`【AudioCapturer】deviceRole: ${v.deviceRole}, deviceType: ${v.deviceType}, id: ${v.id}, name: ${v.name}`);
    console.info(`【AudioCapturer】address: ${v.address}, sampleRates: ${v.sampleRates}, channelCounts: ${v.channelCounts}, channelMasks: ${v.channelMasks}`);
    console.info(`【AudioCapturer】displayName: ${v.displayName}, encodingTypes: ${v.encodingTypes}`);
  })

https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/tutorials_Next-CoreSpeechKit

参考下这个示例代码里面的录音获取数据吧。核心代码:

public async start() {
  console.error(TAG, `AudioCapturerUtil start`);
  let stateGroup = [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED];
  if (stateGroup.indexOf(this.mAudioCapturer.state) === -1) {
    console.error(TAG, `AudioCapturerUtil start failed`);
    return;
  }
  this.mCanWrite = true;
  await this.mAudioCapturer.start();
  while (this.mCanWrite) {
    let bufferSize = await this.mAudioCapturer.getBufferSize();
    let buffer = await this.mAudioCapturer.read(bufferSize, true);
    this.mDataCallBack(buffer)
  }
}

如果想触发这段代码,需要在index中注释代码:

// Audio to text
private async writeAudio() {
  this.setListener();
  // Set the parameters related to the start of identification.
  let audioParam: speechRecognizer.AudioInfo = { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 }
  let recognizerParams: speechRecognizer.StartParams = {
    sessionId: this.sessionId,
    audioInfo: audioParam
  }
  // Invoke the start recognition method.
  asrEngine.startListening(recognizerParams);

  // Get Audio from File
  let data: ArrayBuffer;
  let ctx = getContext(this);
  let filenames: string[] = fileIo.listFileSync(ctx.filesDir);
  // if (filenames.length <= 0) {
  //   console.error('length is null');
  //   return;
  // }
  // let filePath: string = ctx.filesDir + '/' + filenames[0];
  // (this.mFileCapturer as FileCapturer).setFilePath(filePath);
  // this.mFileCapturer.init((dataBuffer: ArrayBuffer) => {
  //   data = dataBuffer
  //   let unit8Array: Uint8Array = new Uint8Array(data);
  //   asrEngine.writeAudio("123456", unit8Array);
  // });
  await this.mFileCapturer.start();
}

点击startRecording就可以触发,获取到录音的buffer。

开始监听,放在start后面试试

在index里面按照您的方式注释了相关代码

在index里面注释了asrEngine相关的代码(因为我只能模拟器调试,模拟器不支持AI)

结果:
结果跟之前的效果差不多,我打印了一下,问题是出在read buffer的时候,以下是我改造后的start函数(只加了一些log),在输出的时候可以看到 `AudioCapturerUtil start`、`bufferSize 640` 都被打印出来,但是buffer没有被打印出来,接着就是报错:

[HandleCapturerRead]Wait timeout [Read]HandleCapturerRead err : -62980096


```javascript
public async start() {
  let stateGroup = [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED];
  if (stateGroup.indexOf(this.mAudioCapturer.state) === -1) {
    console.error(TAG, `AudioCapturerUtil start failed`);
    return;
  }
  this.mCanWrite = true;
  await this.mAudioCapturer.start();
  console.info(TAG, `AudioCapturerUtil start`);
  while (this.mCanWrite) {
    let bufferSize = await this.mAudioCapturer.getBufferSize();
    console.info(TAG, `bufferSize`, bufferSize);
    let buffer = await this.mAudioCapturer.read(bufferSize, true);
    console.info(TAG, `buffer`, buffer);
    const view = new Uint8Array(buffer);
    console.log(TAG, 'buffer view', view)
    this.mDataCallBack(buffer)
  }
}

分析:

  1. 我之前用的是新API on(‘readData’)
  2. 案例中用的是旧API read(这个方法在API 11中被废弃,不建议使用)
  3. 但是两者的结果是相同的,都是在read buffer的时候报错

我的操作步骤是:

  1. 点击startRecording(这个时候audioCapturer init)
  2. 点击audioToText(这个时候audioCapturer start),

改造了以下read所在行的代码,加上了错误捕获,代码以及捕获到的错误如下所示:

代码:

let buffer = await this.mAudioCapturer.read(bufferSize, true).catch(err => {
  console.error(TAG, `AudioCapturerUtil read failed, code is ${err.code}, message is ${err.message}`);
});

错误:错误码6800301,message是system error

AudioCapturerUtil read failed, code is 6800301, message is system error

补充一下:

  1. API 版本:12

  2. IDE:DevEco Studio 5.0.0 Release

  3. 模拟器:HarmonyOS 5.0.0 x86 RAM:4096MB CPU:4核

补充以下PC的信息:

  1. Window版本:Windows 11 家庭中文版
  2. 型号:ThinkBook 14 G6 IRL
  3. 处理器:13th Gen Intel® Core™ i5-13500H 2.60 GHz
  4. 机带RAM:16.0 GB (15.5 GB 可用)

在HarmonyOS(鸿蒙)系统中遇到“HandleCapturerRead Wait timeout and Error”以及具体的错误码“-62980096 Capturer stop: ERROR system error”时,这通常指示着媒体捕获(如摄像头或麦克风)过程中发生了系统级错误或超时。

错误码“-62980096”是一个特定的系统错误码,它可能代表了资源访问冲突、设备不可用、权限问题或系统资源限制等。在鸿蒙系统中,媒体捕获设备(如摄像头)的访问受到严格的管理,以确保系统安全和用户隐私。

解决这类问题的一般步骤包括:

  • 检查权限:确保应用已正确声明并获得了使用相关媒体设备的权限。
  • 设备状态:确认媒体设备(如摄像头)未被其他应用占用,且处于可用状态。
  • 系统资源:检查系统资源是否充足,避免资源耗尽导致的错误。
  • 重启设备:尝试重启设备以恢复系统状态。

如果以上步骤无法解决问题,可能是系统或硬件层面的深层问题。此时,建议联系鸿蒙系统的官方客服以获取更专业的帮助。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部