HarmonyOS 鸿蒙Next中采用avRecord录制MP3音频进行中,突然被电话打断,注册打断监听总是audioHapticPlayerInstance.on('audioInterrupt', this.audioInterruptCallback)失败

HarmonyOS 鸿蒙Next中采用avRecord录制MP3音频进行中,突然被电话打断,注册打断监听总是audioHapticPlayerInstance.on(‘audioInterrupt’, this.audioInterruptCallback)失败

private audioUri = ‘data/audio.mp3’; // 需更改为目标音频资源的Uri

private hapticUri = ‘data/audio.mp3’; // 需更改为目标振动资源的Uri

// 同一监听事件中,on方法和off方法传入callback参数一致,off方法取消对应on方法订阅的监听

private isPlaying: boolean = false; // 标识符,表示是否正在渲染

private isDucked: boolean = false; // 标识符,表示是否被降低音量

private audioHapticManagerInstance: audioHaptic.AudioHapticManager = audioHaptic.getAudioHapticManager();

private id = 0;

private options: audioHaptic.AudioHapticPlayerOptions = {muteAudio: false, muteHaptics: false};

private audioHapticPlayerInstance: audioHaptic.AudioHapticPlayer | undefined = undefined;

createPlayerInstance(){ // this.audioHapticManagerInstance.registerSource(this.avConfig.url, this.hapticUri).then((value: number) => { this.audioHapticManagerInstance.registerSource(this.filePath, this.testJson).then((value: number) => { console.info(Promise returned to indicate that the source id of the registerd source ${value}.); this.id = value; }) .catch ((err: BusinessError) => { console.error(Failed to register source ${err}); });

let usage: audio.StreamUsage = audio.StreamUsage.STREAM_USAGE_NOTIFICATION; this.audioHapticManagerInstance.setStreamUsage(this.id, usage);

this.audioHapticManagerInstance.createPlayer(this.id, this.options).then((value: audioHaptic.AudioHapticPlayer) => { this.audioHapticPlayerInstance = value; console.info(jack Create the audio haptic player successfully.); this.audioHapticPlayerInstance.on(‘audioInterrupt’, this.audioInterruptCallback); }) .catch ((err: BusinessError) => { console.error(jack Failed to create the audio haptic player. ${err.code} .${err}); }); }

audioInterruptCallback = (interruptEvent: audio.InterruptEvent) => { // 在发生音频打断事件时,audioHapticPlayerInstance收到interruptEvent回调,此处根据其内容做相应处理。 // 1、可选:读取interruptEvent.forceType的类型,判断系统是否已强制执行相应操作。 // 注:默认焦点策略下,INTERRUPT_HINT_RESUME为INTERRUPT_SHARE类型,其余hintType均为INTERRUPT_FORCE类型。因此对forceType可不做判断。 // 2、必选:读取interruptEvent.hintType的类型,做出相应的处理。 if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_FORCE) { // 音频焦点事件已由系统强制执行,应用需更新自身状态及显示内容等 switch (interruptEvent.hintType) { case audio.InterruptHint.INTERRUPT_HINT_PAUSE: // 音频流已被暂停,临时失去焦点,待可重获焦点时会收到resume对应的interruptEvent console.info(‘jack Force paused. Update playing status and stop writing’); this.isPlaying = false; // 简化处理,代表应用切换至暂停状态的若干操作 break; case audio.InterruptHint.INTERRUPT_HINT_STOP: // 音频流已被停止,永久失去焦点,若想恢复渲染,需用户主动触发 console.info(‘jack Force stopped. Update playing status and stop writing’); this.isPlaying = false; // 简化处理,代表应用切换至暂停状态的若干操作 break; case audio.InterruptHint.INTERRUPT_HINT_DUCK: // 音频流已被降低音量渲染 console.info(‘jack Force ducked. Update volume status’); this.isDucked = true; // 简化处理,代表应用更新音量状态的若干操作 break; case audio.InterruptHint.INTERRUPT_HINT_UNDUCK: // 音频流已被恢复正常音量渲染 console.info(‘jack Force ducked. Update volume status’); this.isDucked = false; // 简化处理,代表应用更新音量状态的若干操作 break; default: break; } } else if (interruptEvent.forceType == audio.InterruptForceType.INTERRUPT_SHARE) { // 音频焦点事件需由应用进行操作,应用可以自主选择如何处理该事件,建议应用遵从InterruptHint提示处理 switch (interruptEvent.hintType) { case audio.InterruptHint.INTERRUPT_HINT_RESUME: // 建议应用继续渲染(说明音频流此前被强制暂停,临时失去焦点,现在可以恢复渲染) // 由于INTERRUPT_HINT_RESUME操作需要应用主动执行,系统无法强制,故INTERRUPT_HINT_RESUME事件一定为INTERRUPT_SHARE类型 console.info(‘jack Force Resume force paused renderer or ignore’); // 若选择继续渲染,需在此处主动执行开始渲染的若干操作 break; default: break; } } };


更多关于HarmonyOS 鸿蒙Next中采用avRecord录制MP3音频进行中,突然被电话打断,注册打断监听总是audioHapticPlayerInstance.on('audioInterrupt', this.audioInterruptCallback)失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复
  1. 监听器注册需确保在AudioHapticPlayer实例创建成功后执行。代码中通过Promise异步创建实例时,若未正确处理异步流程可能导致监听未生效。建议在Promise链中确认实例创建完成后再绑定回调。

  2. 录制音频需申请ohos.permission.MICROPHONE权限,若未正确声明或动态申请,会导致实例创建失败。需检查应用配置和运行时权限状态。

  3. 当使用SOURCE_TYPE_VOICE_COMMUNICATION类型进行通话录音时,需特别注意系统对音频焦点的强制管理策略,普通录制场景建议采用STREAM_USAGE_MEDIA避免冲突。

// 确保在createPlayer成功回调中注册监听
private createPlayerInstance() {
  this.audioHapticManagerInstance.registerSource(this.filePath, this.testJson)
    .then((id: number) => {
      this.id = id;
      return this.audioHapticManagerInstance.createPlayer(id, this.options);
    })
    .then((player: audioHaptic.AudioHapticPlayer) => {
      this.audioHapticPlayerInstance = player;
      // 绑定监听前检查实例有效性
      if (this.audioHapticPlayerInstance) {
        this.audioHapticPlayerInstance.on('audioInterrupt', this.audioInterruptCallback);
        console.info('监听器注册成功');
      }
    })
    .catch((err: BusinessError) => {
      console.error(`实例创建失败: ${err.code} ${err.message}`);
    });
}

// 使用箭头函数避免this指向问题
private audioInterruptCallback = (interruptEvent: audio.InterruptEvent) => {
  // 处理INTERRUPT_HINT_STOP事件(通话强制停止)
  if (interruptEvent.hintType === audio.InterruptHint.INTERRUPT_HINT_STOP) {
    this.releaseResources();
    console.info('通话中断导致录制停止');
  }
};

// 释放资源后需重建实例
private async restartRecording() {
  await this.releaseResources();
  this.createPlayerInstance();
  await this.avRecorder.start();
}

更多关于HarmonyOS 鸿蒙Next中采用avRecord录制MP3音频进行中,突然被电话打断,注册打断监听总是audioHapticPlayerInstance.on('audioInterrupt', this.audioInterruptCallback)失败的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,当使用avRecord录制MP3音频时被电话打断,audioInterrupt监听失败可能是由于以下原因:

  1. audioHapticPlayerInstance未正确初始化
  2. this.audioInterruptCallback未正确定义
  3. 音频焦点管理策略冲突

确保:

  1. 已导入@ohos.multimedia.audio接口
  2. 在onBeforeDestroy中注销监听
  3. 检查系统权限是否完整

替代方案可直接监听系统中断事件:

audioManager.on('interrupt', (interruptEvent) => {
  if(interruptEvent.forceType === INTERRUPT_FORCE){
    // 处理中断逻辑
  }
});

从代码来看,您在使用audioHapticPlayerInstance.on('audioInterrupt')注册打断监听时遇到问题。以下是可能的原因和解决方案:

  1. 确保audioHapticPlayerInstance已正确初始化。从代码看,createPlayer是异步操作,要确保在调用on方法前player实例已创建完成。

  2. 检查this绑定问题。您的audioInterruptCallback使用了箭头函数语法,this绑定是正确的,但建议在注册监听时添加错误处理:

    try {
      this.audioHapticPlayerInstance.on('audioInterrupt', this.audioInterruptCallback);
    } catch (err) {
      console.error('Failed to register interrupt listener:', err);
    }
    
  3. 确认音频流使用类型(StreamUsage)是否合适。您设置了STREAM_USAGE_NOTIFICATION,这可能会影响打断行为,对于录音场景建议使用STREAM_USAGE_MEDIA

  4. 检查打断事件是否被系统正确处理。在HarmonyOS中,电话打断属于高优先级中断,系统可能会直接停止而非暂停当前音频。

  5. 确保在适当时候取消注册监听,避免内存泄漏:

    this.audioHapticPlayerInstance.off('audioInterrupt', this.audioInterruptCallback);
    

如果问题仍然存在,建议检查系统日志获取更详细的错误信息。

回到顶部