HarmonyOS 鸿蒙Next AVPlayer切换surfaceId 异常
HarmonyOS 鸿蒙Next AVPlayer切换surfaceId 异常
1、AVPlayer先绑定竖屏surfaceId显示正常,
2、点击态全屏模态转场的XComponent 切换AVPlayer的surfaceId显示异常(屏幕花屏什么的)
2 回复
1.surfaceId支持在initialized状态下设置。也支持在prepared/playing/paused/completed/stopped状态下重新设置,重新设置时确保已经在initialized状态下进行设置,否则重新设置失败,重新设置后视频播放在新的窗口渲染。
2.切换不需要调用avPlayer.reset(),以下是切换的简单示例,请参考:
import { media } from '[@kit](/user/kit).MediaKit';
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
const TAG = 'AVPlayerDemo';
[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index {
private surfaceId: string = ''; // surfaceId,用于关联XComponent与视频播放器
private mXComponentController: XComponentController = new XComponentController();
private avPlayer: media.AVPlayer | undefined = undefined;
private surfaceId2: string = ''; // surfaceId,用于关联XComponent2与视频播放器
private mXComponentController2: XComponentController = new XComponentController();
aboutToAppear(): void {
//创建avplayer
this.createAVPlayer()
}
createAVPlayer() {
media.createAVPlayer().then((video: media.AVPlayer) => {
if (video != null) {
this.avPlayer = video;
this.setAVPlayerCallback(this.avPlayer);
this.avPlayer.url = 'http://fotiletest2.oss-cn-hangzhou.aliyuncs.com/f86ee6ff04f94c4d922936faedbfca06';
console.info(TAG,'createAVPlayer success');
} else {
console.error(TAG,'createAVPlayer fail');
}
}).catch((error: BusinessError) => {
console.error(TAG,`AVPlayer catchCallback, error message:${error.message}`);
});
}
// 注册avplayer回调函数
setAVPlayerCallback(avPlayer: media.AVPlayer) {
avPlayer.on('timeUpdate', (time: number) => {
console.info(TAG,`AVPlayer timeUpdate. time is ${time}`);
})
// 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.');
avPlayer.surfaceId = this.surfaceId;
avPlayer.prepare();
break;
case 'prepared': // prepare调用成功后上报该状态机
console.info(TAG,'AVPlayer state prepared called.');
avPlayer.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_00_X)
avPlayer.seek(1, media.SeekMode.SEEK_PREV_SYNC)
avPlayer.play();
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() {
XComponent({
id: 'test',
type: XComponentType.SURFACE,
controller: this.mXComponentController
})
.onLoad(() => {
this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
})
.width('100%')
.height(260)
Button('窗口1播放')
.width(200)
.height(50)
.onClick(() => {
if (this.avPlayer) {
this.avPlayer.surfaceId = this.surfaceId
}
});
Button('窗口2播放')
.width(200)
.height(50)
.onClick(() => {
if (this.avPlayer) {
this.avPlayer.surfaceId = this.surfaceId2
}
});
XComponent({
id: 'test2',
type: XComponentType.SURFACE,
controller: this.mXComponentController2
})
.onLoad(() => {
this.mXComponentController2.setXComponentSurfaceRect({
offsetX:0,
offsetY:0,
surfaceWidth: 1920,
surfaceHeight: 1080
})
this.surfaceId2 = this.mXComponentController2.getXComponentSurfaceId();
})
.width('100%')
.height(260)
}
.zIndex(1)
.width('100%')
.height('100%')
}
}
针对HarmonyOS鸿蒙Next AVPlayer切换surfaceId异常的问题,这通常发生在跨页面视频播放场景中,当尝试更换XComponent后,新的surfaceId无法与已有的AVPlayer实例成功绑定。以下是一些专业的解决方案:
-
全局管理AVPlayer:
- 将AVPlayer作为全局单例变量存储,在需要切换surfaceId时,从全局获取AVPlayer实例,并更新其surfaceId。
-
确保surfaceId有效性:
- 在设置surfaceId前,确保该surfaceId是有效且当前可用的,避免设置无效的surfaceId导致异常。
-
监听状态变化:
- 通过监听AVPlayer的状态变化,确保在正确的时机进行surfaceId的切换,避免在AVPlayer未准备好时进行操作。
-
优化内存管理:
- 确保视频播放时内存管理得当,避免内存泄漏和过度占用内存,这有助于减少切换surfaceId时的异常。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。