HarmonyOS鸿蒙Next中video组件如何获取视频播放进度,然后展示出来

HarmonyOS鸿蒙Next中video组件如何获取视频播放进度,然后展示出来 video 组件如何获取视频播放进度,然后展示出来

6 回复

【背景知识】

【解决方案】

通过事件回调机制来实现。核心思路是:

  1. 子组件(Player)定义回调接口:在Player组件中,定义可以被父组件传递进来的回调函数onPrepared和onUpdate,分别用于获取视频时长和监控播放进度变化。
  2. 父组件传递回调函数:父组件在调用Player时,通过属性方式传入具体的回调函数实现。
  3. 子组件在适当时机调用:Player内部的Video组件在onPrepared(获取时长)和onUpdate(获取进度)等事件触发时,调用父组件传过来的回调函数。

具体代码实现如下:

父组件:

@Component
@Entry
struct MovePage {
  @State duration: number = 0; // 视频总时长状态
  @State time: number = 0; // 当前播放时间状态

  build() {
    Column({ space: 20 }) {
      Column() {
        Player({
          src: $rawfile('example.mp4'),
          isControls: true,
          onPrepared: (duration: number) => {
            this.duration = duration;
          },
          onUpdate: (time: number) => {
            this.time = time;
          }
        });
      }
      .width('100%')
      .height('70%');

      Column({ space: 5 }) {
        Text('视频总时长:' + this.duration + 's');
        Text('当前播放进度:' + this.time + 's');
      }.width('100%');
    }
    .width('100%')
    .height('100%');
  }
}

子组件:

@Component
export default struct Player {
  [@Prop](/user/Prop) src: string | Resource;
  [@Prop](/user/Prop) isControls: boolean = true;
  onPrepared?: (duration: number) => void; // 视频准备完成时触发该事件
  onUpdate?: (time: number) => void; // 播放进度变化时触发该事件
  private videoController: VideoController = new VideoController();

  build() {
    Column({ space: 10 }) {
      Video({
        src: this.src,
        controller: this.videoController
      })
        .loop(true)// 循环播放
        .objectFit(ImageFit.Cover)// 画面填充模式
        .controls(this.isControls)// 绑定控制条
        .onPrepared((event) => {
          this.onPrepared?.(event.duration); // 获取到总时长后调用
        })
        .onUpdate((event) => {
          this.onUpdate?.(event.time); // 当前视频播放的进度
        })
        .onError(() => {
          console.error('播放失败');
        });
      Row({ space: 10 }) {
        Button('开始播放')
          .onClick(() => {
            this.videoController.start();
          });
        Button('暂停播放')
          .onClick(() => {
            this.videoController.pause();
          });
      };
    }.width('100%')
    .height('90%');
  }
}

更多关于HarmonyOS鸿蒙Next中video组件如何获取视频播放进度,然后展示出来的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


背景知识:

  • 事件监听机制

    Video组件通过 onUpdate 事件实时获取当前播放进度,通过 onPrepared 事件获取视频总时长1。这两个事件是进度展示的关键。

  • 数据格式转换

    将获取的时间戳(单位:秒)转换为 mm:ss 格式,通过文本组件展示。

问题解决:

Video({
    //这里可以使用http网络资源,也可以使用本地的media资源
    src: $r('app.media.video_sample'),
    controller: this.vController
})
    .controls(false) // 隐藏默认控制器
    .onPrepared((event: PreparedInfo) => {
        //准备中获取总时长
        event.duration; // 获取总时长(秒)
        this.formatTime(event.duration); // 转格式
    })
    .onUpdate((event: PlaybackInfo) => {
      //每秒更新回调
        event.time; // 实时更新当前播放时间(秒)
        this.formatTime(event.time); // 转格式
    })


// 将秒数转为 mm:ss 格式
private formatTime(seconds: number): string {
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${this.padZero(minutes)}:${this.padZero(remainingSeconds)}`;
}

// 补零函数
private padZero(num: number): string {
    return num < 10 ? `0${num}` : `${num}`;
}

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17,

获取播放进度需要使用两个回调方法:

onPrepared(callback: Callback<PreparedInfo>):视频准备完成时触发该事件,可获取视频播放长度

onUpdate(callback: Callback<PlaybackInfo>) :播放进度变化时触发该事件,可获取当前播放时间

当前播放进度为 e.time / e.duration

Video({
    src: 'your-video-url',
  })
  .onPrepared((e: PreparedInfo) => {
    console.info('总时长 ' + e.duration);
  })
  .onUpdate((e?: PlaybackInfo) => {
    if (e != undefined) {
      // 当前播放时间
      console.info('当前播放到 ' + e.time);
    }
  })

在HarmonyOS Next中,使用VideoControllergetCurrentTime()方法获取当前播放时间(单位:毫秒)。通过监听onUpdate事件实时更新进度。使用Text组件展示格式化后的时间,例如“当前播放位置:${currentTime}ms”。

在HarmonyOS Next中,可以通过监听VideoControlleronCurrentTimeUpdate事件来获取视频播放进度。

具体实现步骤如下:

  1. 创建VideoController:在组件中创建VideoController对象,用于控制视频播放和监听事件。
private videoController: VideoController = new VideoController();
  1. 监听播放进度:通过onCurrentTimeUpdate回调函数获取当前播放时间。
this.videoController.onCurrentTimeUpdate((currentTime: number) => {
  // currentTime单位为秒,可转换为需要的时间格式
  this.currentTime = this.formatTime(currentTime);
});
  1. 绑定到Video组件:将controller绑定到Video组件。
Video({
  src: $rawfile('video.mp4'),
  controller: this.videoController
})
  1. 展示进度:在UI中显示格式化后的时间。
Text(this.currentTime)
  .fontSize(16)
  1. 时间格式化示例
private formatTime(seconds: number): string {
  const min = Math.floor(seconds / 60);
  const sec = Math.floor(seconds % 60);
  return `${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`;
}

完整示例:

@Entry
@Component
struct VideoProgressExample {
  private videoController: VideoController = new VideoController();
  @State currentTime: string = '00:00';

  build() {
    Column() {
      Video({
        src: $rawfile('video.mp4'),
        controller: this.videoController
      })
        .width('100%')
        .height(300)

      Text(`当前进度: ${this.currentTime}`)
        .fontSize(16)
        .margin(10)
    }
  }

  aboutToAppear() {
    this.videoController.onCurrentTimeUpdate((currentTime: number) => {
      this.currentTime = this.formatTime(currentTime);
    });
  }

  private formatTime(seconds: number): string {
    const min = Math.floor(seconds / 60);
    const sec = Math.floor(seconds % 60);
    return `${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`;
  }
}

这样就可以实时获取并显示视频播放进度了。

回到顶部