广告页实现

100 阅读1分钟

功能模块,进入广告页,开始倒计时,播放声音,拥有token则进入登录页面

调用avplayer模块播放声音,定义avplayer的类


// 单例的播放类
export class AVPlayerClass {
  static avPlayer: media.AVPlayer | null = null // 初始值
  static audioName: string = "" // 存储当前的音频的名称
  static isSettingBack: boolean = false // 是否设置过回调  因为针对某一个avplayer只能设置一次回调
  // 提供一个静态方法 播放音乐
  static  async playAudio (audioName: string, context: Context) {
    if(!AVPlayerClass.avPlayer) {
      // 需要创建一个播放器
      AVPlayerClass.avPlayer = await media.createAVPlayer()
    }
    // 如果audio有值
    if(audioName) {
      // 将这个值对应的音频文件读取过来赋值给avplayer的fdSrc
      AVPlayerClass.audioName = audioName
      AVPlayerClass.setAvPlayerAudio(context)
    }

  }
  // 注册avplayer回调函数
  static setAVPlayerCallback() {
    // seek操作结果回调函数
    AVPlayerClass.avPlayer!.on('seekDone', (seekDoneTime: number) => {
    //  console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
      AVPlayerClass.avPlayer!.play() // 回到零秒后 才播放
    })
    // error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程
    // 状态机变化回调函数
    AVPlayerClass.avPlayer!.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
      switch (state) {
        // case 'idle': // 成功调用reset接口后触发该状态机上报
        //   console.info('AVPlayer state idle called.');
        //   AVPlayerClass.avPlayer.release(); // 调用release接口销毁实例对象
        //   break;
        case 'initialized': // avplayer 设置播放源后触发该状态上报
          console.info('AVPlayer state initialized called.');
          AVPlayerClass.avPlayer!.prepare();  // 准备播放
          break;
        case 'prepared': // prepare调用成功后上报该状态机
          console.info('AVPlayer state prepared called.');
         AVPlayerClass.avPlayer!.seek(0); // 调用播放接口开始播放 // 将音频的播放进度挪到0的位置
          break;
        case 'playing': // play成功调用后触发该状态机上报
          break;
        case 'paused': // pause成功调用后触发该状态机上报
          console.info('AVPlayer state paused called.');
          break;
        case 'completed': // 播放结束后触发该状态机上报
          console.info('AVPlayer state completed called.');
          AVPlayerClass.avPlayer!.reset() // 重置
          break;
        case 'stopped': // stop接口成功调用后触发该状态机上报
          console.info('AVPlayer state stopped called.');
          break;
        case 'released':
          console.info('AVPlayer state released called.');
          break;
        default:
          console.info('AVPlayer state unknown called.');
          break;
      }
    })
  }
  static  async setAvPlayerAudio (context: Context) {
    // AVPlayerClass.audioName
    let fileDescriptor = await context.resourceManager.getRawFd(AVPlayerClass.audioName)
    let avFileDescriptor: media.AVFileDescriptor =
      { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };
    if(!AVPlayerClass.isSettingBack) {
      // 设置回调 回调只能设置一次
      AVPlayerClass.setAVPlayerCallback()
    }
    if(AVPlayerClass.avPlayer) {
      // 拿到了资源 赋值给播放器的src属性  会走回调
      AVPlayerClass.avPlayer.fdSrc = avFileDescriptor;
    }

  }
}
// AVPlayerClass.playAudio("success.wav")

调用avplayer,设置填写播放源与context即可开始播放

async onPageShow(): Promise<void> {

  AVPlayerClass.playAudio('information.m4a',getContext(this))

}

编写倒计时模块

自定义一个倒计时模块组件

@Component
export default struct countComp{
  @Consume time:number


   aboutToAppear(): void {
     let timeId=setInterval(()=>{
       this.time--
       console.log(`time:${this.time}`)
       if(this.time===0){
         clearInterval(timeId)
       }
     },1000)
   }



  build() {
    Text(`还剩${this.time}秒`).padding(5).borderRadius(10)
      .fontColor(Color.Black)
  }
}

需要外部@Provide一个time进入

广告页面布局

import { AVPlayerClass } from 'common/Index'
import media from '@ohos.multimedia.media';
import countComp from 'common/src/main/ets/components/ad/countComp';

@Entry
@Component
struct Index {

  @Provide time:number=5

  async onPageShow(): Promise<void> {

    AVPlayerClass.playAudio('information.m4a',getContext(this))

  }

  build() {

    Stack(){

      Image($r('app.media.bg_listen'))
        .width('100%')
        .height('100%')

      countComp().margin(15)

    }.alignContent(Alignment.TopEnd)


  }

}

image.png

感兴趣的小伙伴可以查看我的gitee地址

gitee.com/liuhaobi/dr…