HarmonyOS 鸿蒙Next 封装音乐播放器组件过程遇到的问题(AvPlayer)

HarmonyOS 鸿蒙Next 封装音乐播放器组件过程遇到的问题(AvPlayer)

import { Log } from @abner/log/Index’;
import media from ‘@ohos.multimedia.media’;
import { BusinessError } from ‘@kit.BasicServicesKit’;
import { BlhAudioMediaModel } from ‘…/model/BlhAudioMediaModel’;

@Component export struct BlhAudioPlayer { @Prop blhAudioMedia: BlhAudioMediaModel | null = null; private controller: BlhAudioPlayerController = new BlhAudioPlayerController(); @State state: string = ‘’ private avPlayer: media.AVPlayer | null = null

aboutToAppear(): void { if (this.controller) { this.controller.startPlay = this.startPlay this.controller.resumePlay = this.resumePlay this.controller.pausePlay = this.pausePlay this.controller.stopPlay = this.stopPlay this.controller.getState = this.getState } }

aboutToDisappear(): void { Log.info(“销毁”) this.controller.stopPlay() }

build() { RelativeContainer() { Column() { Stack() { Text(this.blhAudioMedia?.item_title) Image(this.blhAudioMedia?.class_coverimg) .width(120) .height(120) .borderRadius(120) .borderWidth(10) .borderColor($r(‘app.color.color_C6E0FD’)) .alignSelf(ItemAlign.Center) }.width(360).height(191).backgroundColor($r(‘app.color.color_E9F3FF’)).borderRadius(52) } .width(360) .height(199) .id(“blhaudio_player_pic”) .alignRules({ middle: { anchor: container, align: HorizontalAlign.Center } }) .margin({ top: 58 }) .justifyContent(FlexAlign.Center) .borderRadius(52) .linearGradient({ angle: 0, colors: [[$r(‘app.color.color_3C97FF’), 0.0], [$r(‘app.color.color_A8D1FF’), 1.0]] })

  Image(<span class="hljs-keyword">this</span>.state == <span class="hljs-string">'playing'</span> ? $r(<span class="hljs-string">'app.media.blh_pad_ui_zhengzaibofangjian'</span>) :
  $r(<span class="hljs-string">'app.media.blh_pad_ui_bofangjian'</span>))
    .width(<span class="hljs-number">94</span>)
    .height(<span class="hljs-number">72</span>)
    .id(<span class="hljs-string">"blhaudio_player_play"</span>)
    .alignRules({
      top: { anchor: <span class="hljs-string">"blhaudio_player_pic"</span>, align: VerticalAlign.Bottom },
      middle: { anchor: <span class="hljs-string">"blhaudio_player_pic"</span>, align: HorizontalAlign.Center }
    })
    .margin({ top: <span class="hljs-number">4</span> })
    .onClick(() =&gt; {
      Log.info(<span class="hljs-string">"state:"</span> + <span class="hljs-keyword">this</span>.controller.getState() + <span class="hljs-string">"---"</span> + <span class="hljs-keyword">this</span>.state)
      <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.controller.getState() == <span class="hljs-string">'playing'</span>) {
        <span class="hljs-keyword">this</span>.controller.pausePlay()
        <span class="hljs-keyword">this</span>.state = <span class="hljs-string">'pause'</span>
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">this</span>.state = <span class="hljs-string">'playing'</span>
        <span class="hljs-keyword">this</span>.controller.resumePlay()
      }
    })
}
.width(<span class="hljs-number">550</span>)
.height(<span class="hljs-string">"100%"</span>)
.backgroundImage($r(<span class="hljs-string">'app.media.dsw_pad_ui_xiaoqi'</span>))
.backgroundImageSize({ width: <span class="hljs-string">"100%"</span>, height: <span class="hljs-string">"100%"</span> })

}

private async startPlay(blhAudioMedia: BlhAudioMediaModel) { this.avPlayer?.release(() => { Log.info(“销毁3”) }) this.avPlayer = await media.createAVPlayer() // seek操作结果回调函数 this.avPlayer.on(‘seekDone’, (seekDoneTime: number) => { Log.info(AVPlayer seek succeeded, seek time is ${seekDoneTime}); }) // error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程 this.avPlayer.on(‘error’, (err: BusinessError) => { Log.error(Invoke avPlayer failed, code is ${err.code}, message is ${err.message}); this.avPlayer?.reset(); // 调用reset重置资源,触发idle状态 }) // 状态机变化回调函数 this.avPlayer.on(‘stateChange’, async (state: string, reason: media.StateChangeReason) => { this.state = state switch (state) { case ‘idle’: // 成功调用reset接口后触发该状态机上报 Log.info(‘AVPlayer state idle called.’); this.avPlayer?.release(); // 调用release接口销毁实例对象 break; case ‘initialized’: // avplayer 设置播放源后触发该状态上报 Log.info(‘AVPlayer state initialized called.’); this.avPlayer?.prepare(); break; case ‘prepared’: // prepare调用成功后上报该状态机 Log.info(‘AVPlayer state prepared called.’); this.avPlayer?.play(); // 调用播放接口开始播放 break; case ‘playing’: // play成功调用后触发该状态机上报 Log.info(‘AVPlayer state playing called.’); break; case ‘paused’: // pause成功调用后触发该状态机上报 Log.info(‘AVPlayer state paused called.’); break; case ‘completed’: // 播放结束后触发该状态机上报 Log.info(‘AVPlayer state completed called.’); this.avPlayer?.stop(); //调用播放结束接口 break; case ‘stopped’: // stop接口成功调用后触发该状态机上报 Log.info(‘AVPlayer state stopped called.’); this.avPlayer?.reset(); // 调用reset接口初始化avplayer状态 break; case ‘released’: Log.info(‘AVPlayer state released called.’); break; default: Log.info(‘AVPlayer state unknown called.’); break; } }) this.avPlayer.url = blhAudioMedia.item_url }

private resumePlay() { this.avPlayer?.play(() => { Log.info(“播放”) }) }

private pausePlay() { this.avPlayer?.pause(() => { Log.info(“暂停”) }) }

private stopPlay() { this.avPlayer?.release(() => { Log.info(“销毁4”) }) }

private getState(): string | undefined { return this.avPlayer?.state } }

export class BlhAudioPlayerController { startPlay = (blhAudioMedia: BlhAudioMediaModel) => { } resumePlay = () => { } pausePlay = () => { } stopPlay = () => { } getState = (): string | undefined => { return “” } }

上面是代码,在封装的过程中遇到一些问题没有理解原因,前来提问。

问题1: aboutToDisappear(): void { Log.info(“销毁”) this.controller.stopPlay() } 不太清楚为什么通过this.controller.stopPlay()的方式可以生效,直接调用this.stopPlay()不行,或者说直接写成this.avPlayer?.release()不生效。其他方法也是如此。  

问题2: this.avPlayer.on(‘stateChange’, async (state: string, reason: media.StateChangeReason) => { this.state = state } 这里赋完值后不起作用,但是上面点击事件中的this.state = 'pause’和this.state = 'playing’可以生效。


更多关于HarmonyOS 鸿蒙Next 封装音乐播放器组件过程遇到的问题(AvPlayer)的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复
看起来一切问题都出在startPlay这个方法,改成下面写法似乎就可以了 
aboutToAppear(): void {
    if(this.controller) {
      this.controller.startPlay = (blhAudioMedia: BlhAudioMediaModel): void=>{this.startPlay(blhAudioMedia)}
    }
  }

更多关于HarmonyOS 鸿蒙Next 封装音乐播放器组件过程遇到的问题(AvPlayer)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


对于HarmonyOS 鸿蒙Next封装音乐播放器组件过程中遇到的AvPlayer问题,这里提供一些专业解答:

在封装音乐播放器组件时,AvPlayer的使用是核心环节。如果遇到问题,首先要确保AvPlayer实例已经正确创建。通过createAVPlayer()方法创建实例,并绑定必要的回调函数,以获取播放器的状态变化和错误信息。

在设置播放资源时,需确保提供的媒体文件路径或URL是有效且可访问的。如果资源地址有误,AvPlayer可能无法正确进入prepared状态,从而导致播放失败。此时,可以通过监听stateChange事件来实时了解播放器的状态,以便在必要时调用reset()方法重置播放器。

在播放控制方面,AvPlayer支持播放、暂停、跳转和停止等操作。但需要注意的是,在调用这些操作前,要确保播放器处于可操作状态。例如,在暂停播放时,如果播放器当前处于停止或未初始化状态,则暂停操作将无效。

此外,如果在封装过程中遇到AvPlayer换源播放问题,如首次播放直播地址有误时播放状态卡在initialized,且reset方法无法触发idle状态的情况,可以尝试重新检查资源地址的有效性,并确保在调用reset方法前播放器实例已经正确创建且处于可操作状态。

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

回到顶部