目录

开启倒计时铃声播放,后台音乐播放不流畅

问题现象

后台播放音乐时,开启应用的倒计时功能并打开铃声播放,后台音乐播放不流畅。

背景知识

问题定位

  1. 在日志中搜索Renderer::Start|Renderer::Stop关键字查看应用播放音频的情况,可看到应用有频繁播放、暂停音频播放,streamType值为7,对应的音频流使用类型为通知音STREAM_USAGE_NOTIFICATION。
    07-29 11:43:35.646   29512-29730  C02B87/com.hm...AudioRenderer com.hm.example  I     [Start]StreamClientState for Renderer::Start. id: 100446, streamType: 7, volume: 1.000000, interruptMode: 0
    07-29 11:43:35.710   29512-29734  C02B87/com.hm...AudioRenderer com.hm.example  I     [Stop]StreamClientState for Renderer::Stop. id: 100446
    07-29 11:43:36.650   29512-29731  C02B87/com.hm...AudioRenderer com.hm.example  I     [Start]StreamClientState for Renderer::Start. id: 100446, streamType: 7, volume: 1.000000, interruptMode: 0
    07-29 11:43:36.727   29512-29734  C02B87/com.hm...AudioRenderer com.hm.example  I     [Stop]StreamClientState for Renderer::Stop. id: 100446
    07-29 11:43:37.649   29512-29732  C02B87/com.hm...AudioRenderer com.hm.example  I     [Start]StreamClientState for Renderer::Start. id: 100446, streamType: 7, volume: 1.000000, interruptMode: 0
    07-29 11:43:37.731   29512-29734  C02B87/com.hm...AudioRenderer com.hm.example  I     [Stop]StreamClientState for Renderer::Stop. id: 100446
    07-29 11:43:38.650   29512-29733  C02B87/com.hm...AudioRenderer com.hm.example  I     [Start]StreamClientState for Renderer::Start. id: 100446, streamType: 7, volume: 1.000000, interruptMode: 0
    07-29 11:43:38.729   29512-29734  C02B87/com.hm...AudioRenderer com.hm.example  I     [Stop]StreamClientState for Renderer::Stop. id: 100446
    07-29 11:43:39.650   29512-29729  C02B87/com.hm...AudioRenderer com.hm.example  I     [Start]StreamClientState for Renderer::Start. id: 100446, streamType: 7, volume: 1.000000, interruptMode: 0
    07-29 11:43:39.730   29512-29734  C02B87/com.hm...AudioRenderer com.hm.example  I     [Stop]StreamClientState for Renderer::Stop. id: 100446
    07-29 11:43:40.651   29512-29730  C02B87/com.hm...AudioRenderer com.hm.example  I     [Start]StreamClientState for Renderer::Start. id: 100446, streamType: 7, volume: 1.000000, interruptMode: 0
    07-29 11:43:40.730   29512-29734  C02B87/com.hm...AudioRenderer com.hm.example  I     [Stop]StreamClientState for Renderer::Stop. id: 100446
  2. .在日志中搜索SoundPool::Play看到有相关日志打印,应用有使用SoundPool播放音频,同时从上述分析得知音频流类型为通知音,可知打开铃声播放时,应用有频繁播放通知短音频,导致后台播放的音乐音量频繁降低、升高,播放不流畅。
    07-29 11:43:35.642   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #106 SoundPool::Play soundID::1 ,priority::0
    07-29 11:43:35.644   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #117 SoundPool::Play streamID::2
    07-29 11:43:36.643   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #106 SoundPool::Play soundID::1 ,priority::0
    07-29 11:43:36.650   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #117 SoundPool::Play streamID::2
    07-29 11:43:37.646   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #106 SoundPool::Play soundID::1 ,priority::0
    07-29 11:43:37.648   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #117 SoundPool::Play streamID::2
    07-29 11:43:38.646   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #106 SoundPool::Play soundID::1 ,priority::0
    07-29 11:43:38.649   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #117 SoundPool::Play streamID::2
    07-29 11:43:39.647   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #106 SoundPool::Play soundID::1 ,priority::0
    07-29 11:43:39.650   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #117 SoundPool::Play streamID::2
    07-29 11:43:40.647   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #106 SoundPool::Play soundID::1 ,priority::0
    07-29 11:43:40.651   29512-49188  C02B2F/com.hm...ple/SoundPool com.hm.example  I     #117 SoundPool::Play streamID::2

分析结论

使用SoundPool频繁播放通知流类型短音频实现倒计时铃声提示音效,导致后台播放的音乐音量频繁降低、升高,播放不流畅。

修改建议

创建SoundPool实例时设置音频流使用类型为音乐。

import { media } from '@kit.MediaKit';
import { audio } from '@kit.AudioKit';
import { BusinessError } from '@kit.BasicServicesKit';
import common from '@ohos.app.ability.common';

@Entry
@Component
struct SoundPoolDemoPage {
  mediaSoundPool : media.SoundPool | undefined = undefined;

  soundId: number = 0;

  intervalNum: number = 0;

  playParameters: media.PlayParameters = {
    loop: 0, // 仅播放一次
    rate: audio.AudioRendererRate.RENDER_RATE_NORMAL, //正常倍速
    leftVolume: 0.5, // 左声道音量
    rightVolume: 0.5, // 右声道音量
    priority: 1, // 优先级
  };

  initSound(): void {
    // 创建音频池实例
    media.createSoundPool(8, {
      usage: audio.StreamUsage.STREAM_USAGE_MUSIC,
      rendererFlags: 0
    }, async (error: BusinessError, soundPool: media.SoundPool) => {
      if (error) {
        return;
      }
      this.mediaSoundPool = soundPool;
      let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
      let fileDescriptor = await context.resourceManager.getRawFd('1.AAC'); // 测试需要替换成可引用到的资源
      // 加载音频资源
      this.mediaSoundPool.load(fileDescriptor.fd, fileDescriptor.offset, fileDescriptor.length,
        (error: BusinessError, soundId: number) => {
          if (error) {
            console.error(`Failed to load soundPool: errCode is ${error.code}, errMessage is ${error.message}`);
          } else {
            this.soundId = soundId;
            console.info('Succeeded in loading soundId:' + soundId);
          }
        });
    });
  }

  releaseSound(): void {
    if (!this.mediaSoundPool) {
      return;
    }
    // 卸载音频资源
    this.mediaSoundPool.unload(this.soundId, (error: BusinessError) => {
      if (error) {
        console.error(`Failed to unload ${this.soundId}: errCode is ${error.code}, errMessage is ${error.message}`);
      } else {
        console.info(`Succeeded in unloading ${this.soundId}`);
      }
    });
    // 释放音频池实例
    this.mediaSoundPool.release((error: BusinessError) => {
      if (error) {
        console.error(`Failed to release soundPool: errCode is ${error.code}, errMessage is ${error.message}`);
      } else {
        console.info(`Succeeded in releasing soundPool`);
      }
    });
  }

  aboutToAppear(): void {
    this.initSound(); // 创建音频池实例、加载音频资源
  }

  aboutToDisappear(): void {
    this.releaseSound(); // 卸载音频资源、释放音频池实例
  }

  build() {
    RelativeContainer() {
      Button('播放声音')
        .onClick(() => {
          this.mediaSoundPool?.play(this.soundId, this.playParameters, (error: BusinessError, streamId: number) => {
            if (error) {
              console.error('play error');
              return;
            }
            console.info('play streamId:' + streamId);
          });
        })
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}