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(() => {
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
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