智能客服
你问我答,随时在线为你解决问题

























应用中子页面播放音频,点击返回首页后,仍然可以短暂地听到音频声音,声音没有立刻结束。
检查应用中AVPlayer实例调用stop接口停止音频播放的调用时机,是否在首页的onPageShow函数中停止的音频播放,问题代码如下:
- onPageShow(): void {
- // 应用首页停止子页面的音频播放
- this.avStop();
- }
- avStop(): void {
- if (this.avPlayer) {
- try {
- this.avPlayer.stop();
- console.info(`avPlayer Stop success`);
- } catch (e) {
- console.error(`avPlayer Stop failed`);
- }
- }
- }
应用在首页的onPageShow函数中,调用的AVPlayer实例的stop接口停止的音频播放;而子页面从销毁到执行首页onPageShow函数中stop接口停止音频播放,有一定代码运行时间,导致返回首页后短暂的音频播放问题。
应用在子页面的aboutToDisappear函数中,调用AVPlayer实例的stop及release接口,停止音频播放并销毁AVPlayer实例,避免返回首页后仍然有音频播放的问题,示例如下:
- aboutToDisappear() {
- if (this.avPlayer == null) {
- console.info(`${this.tag}: avPlayer has not init aboutToDisappear`);
- return;
- }
-
-
- try {
- this.avPlayer.stop();
- console.info(`${this.tag}: avStop==`);
- } catch (e) {
- console.error(`${this.tag}: avStop== ${JSON.stringify(e)}`);
- }
-
-
- this.avPlayer.release((err) => {
- if (err == null) {
- console.info(`${this.tag}: videoRelease release success`);
- } else {
- console.error(`${this.tag}: videoRelease release failed, error message is = ${JSON.stringify(err.message)}`);
- }
- });
- if (this.subFile) {
- try {
- fileIo.closeSync(this.subFile);
- } catch (err) {
- console.error(`failed to close subtitle file, ${JSON.stringify(err)}`);
- }
- }
- }
完整示例如下:
- @Entry
- @Component
- struct Index {
- pathStack: NavPathStack = new NavPathStack();
-
-
- build() {
- Navigation(this.pathStack) {
- Row() {
- Column() {
- Text('首页')
- .fontSize(50)
- .fontWeight(FontWeight.Bold);
- // 添加按钮,以响应用户onClick事件
- Button() {
- Text('子页面音频')
- .fontSize(20)
- .fontWeight(FontWeight.Bold);
- }
- .type(ButtonType.Capsule)
- .margin({
- top: 50
- })
- .backgroundColor('#0D9FFB')
- .width('40%')
- .height('5%')
- .onClick(() => {
- this.pathStack.pushPathByName('PageOne', null);
- });
- }
- .width('100%');
- }
- .height('100%');
- }
- .title('Navigation')
- .mode(NavigationMode.Stack);
- }
- }
- import display from '@ohos.display';
- import { common } from '@kit.AbilityKit';
- import media from '@ohos.multimedia.media';
- import { fileIo } from '@kit.CoreFileKit';
-
-
- const PROPORTION = 0.99; // 占屏幕比例
- const SURFACE_W = 0.9; // 表面宽比例
- const SURFACE_H = 1.78; // 表面高比例
-
-
- @Builder
- export function PageOneBuilder() {
- PageOne();
- }
-
-
- @Component
- struct PageOne {
- pathStack: NavPathStack = new NavPathStack();
- tag: string = 'AVPlayManager';
- private xComponentController: XComponentController = new XComponentController();
- private avPlayer: media.AVPlayer | null = null;
- private subFile: fileIo.File | null = null;
- private surfaceId: string = '';
- private intervalID: number = -1;
- private context: common.UIAbilityContext | undefined = undefined;
- private fileName: string = '3463094780.mp3'; // 资源需替换成用户自己的资源,否则无法成功运行
- private isSwiping: boolean = false; // 用户滑动过程中
- private xComponentFlag: boolean = false;
- @State surfaceW: number | null = null;
- @State surfaceH: number | null = null;
- private percent: number = 0;
- private windowWidth: number = 300;
- private windowHeight: number = 200;
-
-
- async msleepAsync(ms: number): Promise<boolean> {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve(true);
- }, ms);
- });
- }
-
-
- async avSetupVideoAndSubtitle() {
- // 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址。
- if (this.context === undefined) {
- return;
- }
- // this.fileName需根据应用实际情况配置对应的资源,否则会导致程序无法正常运行
- let fileDescriptorVideo = await this.context.resourceManager.getRawFd(this.fileName);
- let avFileDescriptor: media.AVFileDescriptor =
- { fd: fileDescriptorVideo.fd, offset: fileDescriptorVideo.offset, length: fileDescriptorVideo.length };
-
-
- if (this.avPlayer) {
- console.info(`${this.tag}: init avPlayer release2createNew`);
- this.avPlayer.release();
- await this.msleepAsync(1500);
- }
- // 创建avPlayer实例对象
- this.avPlayer = await media.createAVPlayer();
- // 创建状态机变化回调函数
- await this.setAVPlayerCallback((avPlayer: media.AVPlayer) => {
- this.percent = avPlayer.width / avPlayer.height;
- this.setVideoWH();
- });
- // 为fdSrc赋值触发initialized状态机上报
- this.avPlayer.fdSrc = avFileDescriptor;
- }
-
-
- avPlay(): void {
- if (this.avPlayer) {
- try {
- this.avPlayer.play();
- } catch (e) {
- console.error(`${this.tag}: avPlay = ${JSON.stringify(e)}`);
- }
- }
- }
-
-
- // 注册avplayer回调函数
- async setAVPlayerCallback(callback: (avPlayer: media.AVPlayer) => void): Promise<void> {
- // seek操作结果回调函数
- if (this.avPlayer == null) {
- console.error(`${this.tag}: avPlayer has not init!`);
- return;
- }
- this.avPlayer.on('seekDone', (seekDoneTime) => {
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
- });
- this.avPlayer.on('speedDone', (speed) => {
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer speedDone, speed is ${speed}`);
- });
- // error回调监听函数,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
- this.avPlayer.on('error', (err) => {
- console.error(`${this.tag}: setAVPlayerCallback Invoke avPlayer failed ${JSON.stringify(err)}`);
- if (this.avPlayer == null) {
- console.error(`${this.tag}: avPlayer has not init on error`);
- return;
- }
- this.avPlayer.reset();
- });
- // 状态机变化回调函数
- this.avPlayer.on('stateChange', async (state) => {
- if (this.avPlayer == null) {
- console.info(`${this.tag}: avPlayer has not init on state change`);
- return;
- }
- switch (state) {
- case 'idle': // 成功调用reset接口后触发该状态机上报
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state idle called.`);
- break;
- case 'initialized': // avplayer设置播放源后触发该状态上报
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state initialized called.`);
- if (this.surfaceId) {
- this.avPlayer.surfaceId = this.surfaceId; // 设置显示画面,当播放的资源为纯音频时无需设置
- console.info(`${this.tag}: setAVPlayerCallback this.avPlayer.surfaceId = ${this.avPlayer.surfaceId}`);
- this.avPlayer.prepare();
- }
- break;
- case 'prepared': // prepare调用成功后上报该状态机
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state prepared called.`);
- this.avPlayer.on('bufferingUpdate', (infoType: media.BufferingInfoType, value: number) => {
- console.info(`${this.tag}: bufferingUpdate called, infoType value: ${infoType}, value:${value}}`);
- });
- this.avPlayer.play(); // 调用播放接口开始播放
- callback(this.avPlayer);
- break;
- case 'playing': // play成功调用后触发该状态机上报
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state playing called.`);
- if (this.intervalID !== -1) {
- clearInterval(this.intervalID);
- }
- break;
- case 'completed': // 播放结束后触发该状态机上报
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state completed called.`);
- if (this.intervalID !== -1) {
- clearInterval(this.intervalID);
- }
- this.avPlayer.off('bufferingUpdate');
- break;
- case 'released':
- console.info(`${this.tag}: setAVPlayerCallback released called.`);
- break;
- case 'stopped':
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state stopped called.`);
- break;
- case 'error':
- console.error(`${this.tag}: setAVPlayerCallback AVPlayer state error called.`);
- break;
- case 'paused':
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state paused called.`);
- break;
- default:
- console.info(`${this.tag}: setAVPlayerCallback AVPlayer state unknown called.`);
- break;
- }
- });
- }
-
-
- async aboutToAppear() {
- this.windowWidth = display.getDefaultDisplaySync().width;
- this.windowHeight = display.getDefaultDisplaySync().height;
- this.surfaceW = this.windowWidth * SURFACE_W;
- this.surfaceH = this.surfaceW / SURFACE_H;
- this.context = this.getUIContext().getHostContext() as common.UIAbilityContext;
- // 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址。
- if (this.context === undefined) {
- return;
- }
- // this.fileName需根据应用实际情况配置对应的资源,否则会导致程序无法正常运行
- let fileDescriptorVideo = await this.context.resourceManager.getRawFd(this.fileName);
- let avFileDescriptor: media.AVFileDescriptor =
- { fd: fileDescriptorVideo.fd, offset: fileDescriptorVideo.offset, length: fileDescriptorVideo.length };
-
-
- if (this.avPlayer) {
- console.info(`${this.tag}: init avPlayer release2createNew`);
- this.avPlayer.release();
- await this.msleepAsync(1500);
- }
- // 创建avPlayer实例对象
- this.avPlayer = await media.createAVPlayer();
- // 创建状态机变化回调函数
- await this.setAVPlayerCallback((avPlayer: media.AVPlayer) => {
- this.percent = avPlayer.width / avPlayer.height;
- this.setVideoWH();
- });
- // 为fdSrc赋值触发initialized状态机上报
- this.avPlayer.fdSrc = avFileDescriptor;
- }
-
-
- aboutToDisappear() {
- if (this.avPlayer == null) {
- console.info(`${this.tag}: avPlayer has not init aboutToDisappear`);
- return;
- }
-
-
- try {
- this.avPlayer.stop();
- console.info(`${this.tag}: avStop==`);
- } catch (e) {
- console.error(`${this.tag}: avStop== ${JSON.stringify(e)}`);
- }
-
-
- this.avPlayer.release((err) => {
- if (err == null) {
- console.info(`${this.tag}: videoRelease release success`);
- } else {
- console.error(`${this.tag}: videoRelease release failed, error message is = ${JSON.stringify(err.message)}`);
- }
- });
- if (this.subFile) {
- try {
- fileIo.closeSync(this.subFile);
- } catch (err) {
- console.error(`failed to close subtitle file, ${JSON.stringify(err)}`);
- }
- }
- }
-
-
- setVideoWH(): void {
- if (this.percent >= 1) { // 横向视频
- this.surfaceW = Math.round(this.windowWidth * PROPORTION);
- this.surfaceH = Math.round(this.surfaceW / this.percent);
- } else { // 纵向视频
- this.surfaceH = Math.round(this.windowHeight * PROPORTION);
- this.surfaceW = Math.round(this.surfaceH * this.percent);
- }
- }
-
-
- @Builder
- CoverXComponent() {
- XComponent({
- // 装载视频容器
- id: 'xComponent',
- type: XComponentType.SURFACE,
- controller: this.xComponentController
- })
- .id('VideoView')
- .visibility(this.xComponentFlag ? Visibility.Visible : Visibility.Hidden)
- .onLoad(() => {
- this.surfaceId = this.xComponentController.getXComponentSurfaceId();
- })
- .height(`${this.surfaceH}px`)
- .width(`${this.surfaceW}px`);
- }
-
-
- build() {
- NavDestination() {
- Column() {
- Row() {
- Button() {
- Text('返回首页')
- .fontSize(30)
- .fontWeight(FontWeight.Bold);
- }
- .type(ButtonType.Capsule)
- .margin({
- top: 20
- })
- .backgroundColor('#0D9FFB')
- .width('40%')
- .height('5%')
- .onClick(() => {
- this.pathStack.clear();
- });
- };
-
-
- Stack() {
- Column() {
- this.CoverXComponent();
- }
- .align(Alignment.TopStart)
- .margin({ top: 80 })
- .id('VideoView')
- .justifyContent(FlexAlign.Center);
-
-
- Text()
- .height(`${this.surfaceH}px`)
- .width(`${this.surfaceW}px`)
- .margin({ top: 80 })
- .backgroundColor(Color.Black)
- .visibility(this.isSwiping ? Visibility.Visible : Visibility.Hidden);
- }
- .backgroundColor(Color.Black)
- .height('90%')
- .width('100%');
-
-
- }.backgroundColor(Color.Black)
- .height('100%')
- .width('100%');
- }.title('PageOne')
- .onReady((context: NavDestinationContext) => {
- this.pathStack = context.pathStack;
- });
- }
- }
智能客服
你问我答,随时在线为你解决问题
合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功