HarmonyOS 鸿蒙Next应用中如何使用avplayer同时播放两个音频

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

HarmonyOS 鸿蒙Next应用中如何使用avplayer同时播放两个音频

项目中需求需要在播放题目的使用时候,用户可以点击喇叭播放单词。也就是说在播放某个音频的同时,支持同时播放其他的音频。目前的问题是,当我播放音频1的时候,用另一个AVPlayer播放音频2,会导致音频1停止播放,而且不走回调方法。 初始化的时候,已设置音频打断模式: //设置音频打断模式为独占模式 this.avPlayer.audioInterruptMode = audio.InterruptMode.INDEPENDENT_MODE

2 回复

我这边测试创建2个avplayer实例,可以同时播放。您提供下您那边的代码,方便我们排查问题,以下是我的代码您参考。

import { media } from '@kit.MediaKit';
import { BusinessError } from '@kit.BasicServicesKit';

const TAG = 'AVPlayerDemo';

@Component
struct AVPlayerDemo {
  private surfaceId: string = ''; // surfaceId,用于关联XComponent与视频播放器
  private mXComponentController: XComponentController = new XComponentController();
  private avPlayer: media.AVPlayer | undefined = undefined;
  private surfaceId1: string = ''; // surfaceId,用于关联XComponent与视频播放器
  private mXComponentController1: XComponentController = new XComponentController();
  private avPlayer1: media.AVPlayer | undefined = undefined;

  aboutToAppear(): void {
    //创建avplayer
    this.initAvPlayer()
    //创建avplayer
    this.initAvPlayer1()
  }

  initAvPlayer() {
    media.createAVPlayer().then((avPlayer: media.AVPlayer) => {
      this.avPlayer = avPlayer;
      this.playerCallback(this.avPlayer);
      this.avPlayer.url = 'https://mmslivef.scgchc.com/live/1219.m3u8?auth_key=1735893693-0-0-0d1a6d5f60e5d9105497f7a344b7ca59';
    })
  }

  initAvPlayer1() {
    media.createAVPlayer().then((avPlayer: media.AVPlayer) => {
      this.avPlayer1 = avPlayer;
      this.playerCallback(this.avPlayer1);
      this.avPlayer1.url = 'https://www.w3school.com.cn/example/html5/mov_bbb.mp4';
    })
  }

  // 注册avplayer回调函数
  playerCallback(avPlayer: media.AVPlayer) {
    avPlayer.on('timeUpdate', (time: number) => {
      console.info(TAG, 'AVPlayer timeUpdate. time = ' + time / 1000);
    })
    // error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程
    avPlayer.on('error', (err: BusinessError) => {
      console.error(TAG, `Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
      avPlayer.reset(); // 调用reset重置资源,触发idle状态
    })
    // 状态机变化回调函数
    avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
      switch (state) {
        case 'idle': // 成功调用reset接口后触发该状态机上报
          console.info(TAG, 'AVPlayer state idle called.');
          break;
        case 'initialized': // avplayer 设置播放源后触发该状态上报
          console.info(TAG, 'AVPlayer state initialized called.');
          if (avPlayer == this.avPlayer) {
            avPlayer.surfaceId = this.surfaceId;
            avPlayer.prepare();
          } else {
            avPlayer.surfaceId = this.surfaceId1;
            avPlayer.prepare();
          }
          break;
        case 'prepared': // prepare调用成功后上报该状态机
          console.info(TAG, 'AVPlayer state prepared called.');
          break;
        case 'completed': // prepare调用成功后上报该状态机
          console.info(TAG, 'AVPlayer state completed called.');
          break;
        case 'playing': // play成功调用后触发该状态机上报
          console.info(TAG, 'AVPlayer state playing called.');
          break;
        case 'paused': // pause成功调用后触发该状态机上报
          console.info(TAG, 'AVPlayer state paused called.');
          break;
        case 'stopped': // stop接口成功调用后触发该状态机上报
          console.info(TAG, 'AVPlayer state stopped called.');
          break;
        case 'released':
          console.info(TAG, 'AVPlayer state released called.');
          break;
        default:
          console.info(TAG, 'AVPlayer state unknown called.');
          break;
      }
    })
  }

  build() {
    Column({ space: 20 }) {
      XComponent({
        id: 'xComponent',
        type: XComponentType.SURFACE,
        controller: this.mXComponentController
      })
        .onLoad(() => {
          this.mXComponentController.setXComponentSurfaceRect({
            offsetX: 0,
            offsetY: 0,
            surfaceWidth: 1920,
            surfaceHeight: 1080
          });
          this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
        })
        .width('100%')
        .height('800px')
      Button("播放")
        .onClick(() => {
          this.avPlayer?.play()
        })
      XComponent({
        id: 'xComponent1',
        type: XComponentType.SURFACE,
        controller: this.mXComponentController1
      })
        .onLoad(() => {
          this.mXComponentController1.setXComponentSurfaceRect({
            offsetX: 0,
            offsetY: 0,
            surfaceWidth: 1920,
            surfaceHeight: 1080
          });
          this.surfaceId1 = this.mXComponentController1.getXComponentSurfaceId()
        })
        .width('100%')
        .height('800px')
      Button("播放")
        .onClick(() => {
          this.avPlayer1?.play()
        })
    }
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next应用中如何使用avplayer同时播放两个音频的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next应用中,若要使用avplayer同时播放两个音频,可以通过以下方式实现:

首先,需要确保你的项目中已经正确引入了音频播放相关的库和模块。在鸿蒙系统中,音频播放通常依赖于系统提供的多媒体框架。

  1. 创建两个AVPlayer实例: 为每个音频文件创建一个AVPlayer实例。这样可以确保两个音频文件可以独立控制。

  2. 设置音频源: 为每个AVPlayer实例设置相应的音频源,即音频文件的URI或本地路径。

  3. 准备并播放音频: 调用prepare方法准备音频播放,随后调用start方法开始播放。由于有两个AVPlayer实例,因此需要分别对它们进行上述操作。

  4. 管理音频播放: 你可以通过监听播放状态、控制播放进度、调整音量等方式来管理两个音频的播放。需要注意的是,同时播放两个音频时,可能会遇到音量叠加、音频焦点等问题,这些需要根据具体需求进行处理。

如果在实现过程中遇到具体问题,如音频无法同时播放、播放控制异常等,可以检查以下几个方面:

  • 确保音频文件格式和系统支持的格式一致。
  • 检查音频文件的路径或URI是否正确。
  • 确认AVPlayer实例是否正确创建和初始化。

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

回到顶部