1. 鸿蒙Video组件基础入门

第一次接触鸿蒙Video组件时,我就像拿到一个新玩具的孩子,既兴奋又有点不知所措。这个组件就像是手机里的万能播放器,不仅能播本地视频,还能流畅播放网络视频。记得当时为了测试,我特意找了个猫咪视频放在项目里,看着它顺利播放出来的那一刻,简直比看到真猫还开心。

创建Video组件其实特别简单,就像搭积木一样。最基本的代码结构长这样:

@Entry
@Component
struct MyVideoPlayer {
  private controller: VideoController = new VideoController()
  @State videoSrc: Resource = $rawfile('cat.mp4')

  build() {
    Column() {
      Video({
        src: this.videoSrc,
        controller: this.controller
      })
    }
  }
}

这里有几个关键点需要注意:

  • src属性支持三种视频源:本地资源、网络URL和沙箱路径
  • controller是视频的遥控器,控制播放暂停等操作
  • 本地视频要放在resources/rawfile目录下

我刚开始用的时候犯过一个低级错误,把视频文件放错了目录,结果怎么调试都播不出来。后来才发现鸿蒙对资源路径有严格要求,这个坑希望大家能避开。

2. 核心功能深度解析

2.1 视频控制三板斧

VideoController就像视频的遥控器,我把它常用的方法总结为"三板斧":

  1. start() - 播放键
  2. pause() - 暂停键
  3. setCurrentTime() - 进度条拖拽
// 跳转到第30秒播放
this.controller.setCurrentTime(30)

这里有个实用技巧:从API 12开始支持精准跳转模式,像这样:

// 精准跳转,不卡顿
this.controller.setCurrentTime(30, SeekMode.Accurate)

2.2 事件监听实战

事件监听就像是给视频装了感应器,我常用这几个:

  • onPrepared:视频准备好时触发,可以获取总时长
  • onUpdate:播放进度变化时触发,用来更新进度条
  • onError:出错时触发,做错误处理
Video({
  //...
})
.onPrepared((event) => {
  console.log(`视频总时长:${event.duration}秒`)
})
.onUpdate((event) => {
  this.currentTime = event.time // 更新当前时间
})

2.3 播放器属性调校

Video组件有很多实用属性可以调整:

  • muted:静音开关
  • autoPlay:自动播放(预览器无效)
  • loop:循环播放
  • objectFit:视频填充模式(类似CSS的object-fit)
Video({/*...*/})
  .muted(false)
  .autoPlay(true)
  .loop(false)
  .objectFit(ImageFit.Cover)

3. 自定义控制栏开发

3.1 隐藏默认控制栏

首先要把自带控制栏关掉:

Video({/*...*/})
  .controls(false) // 关键!

3.2 打造专属控制栏

我用Row+Button+Slider组合了一套控制栏:

@Component
struct CustomControls {
  @Link isPlaying: boolean
  @Link currentTime: number
  @Link duration: number
  private controller: VideoController
  
  build() {
    Row() {
      // 播放/暂停按钮
      Button(this.isPlaying ? '暂停' : '播放')
        .onClick(() => {
          this.isPlaying ? this.controller.pause() 
                       : this.controller.start()
          this.isPlaying = !this.isPlaying
        })
      
      // 进度条
      Slider({
        value: this.currentTime,
        max: this.duration
      }).onChange((value) => {
        this.controller.setCurrentTime(value)
      })
      
      // 全屏按钮
      Button('全屏')
        .onClick(() => {
          this.controller.requestFullscreen(true)
        })
    }
  }
}

3.3 样式美化技巧

给控制栏加点样式会更美观:

  • 设置半透明背景
  • 添加内边距
  • 使用Flex布局自适应宽度
Row()
  .width('100%')
  .height(60)
  .backgroundColor('#33333399')
  .padding(10)
  .justifyContent(FlexAlign.SpaceAround)

4. 高级功能与避坑指南

4.1 多实例播放

遇到画中画需求时,可以用AVPlayer:

import media from '@ohos.multimedia.media'
const avPlayer = media.createAVPlayer()
avPlayer.url = 'https://example.com/video.mp4'
avPlayer.surfaceId = xComponentController.getXComponentSurfaceId()
avPlayer.play()

4.2 常见问题排查

我踩过的几个坑:

  1. 网络视频播不了?检查是否申请了网络权限
    // module.json5
    "requestPermissions": [{
      "name": "ohos.permission.INTERNET"
    }]
    
  2. 视频卡顿?大视频建议分片加载
  3. 全屏异常?不同设备实现可能不同

4.3 性能优化建议

  • 复用VideoController实例
  • 及时销毁不用的播放器
  • 网络视频做好加载状态管理

记得有次做视频列表,没注意实例回收,结果内存蹭蹭涨,被测试同学追着打。后来加了回收机制才解决:

onPageHide() {
  this.controller.stop()
}

5. 完整示例代码

最后分享一个我常用的模板:

@Entry
@Component
struct VideoDemo {
  private controller: VideoController = new VideoController()
  @State src: string = 'https://example.com/video.mp4'
  @State isPlaying: boolean = false
  @State currentTime: number = 0
  @State duration: number = 0

  build() {
    Column() {
      // 视频区域
      Video({
        src: this.src,
        controller: this.controller
      })
      .controls(false)
      .onStart(() => this.isPlaying = true)
      .onPause(() => this.isPlaying = false)
      .onPrepared((e) => this.duration = e.duration)
      .onUpdate((e) => this.currentTime = e.time)

      // 自定义控制栏
      CustomControls({
        isPlaying: $isPlaying,
        currentTime: $currentTime,
        duration: $duration,
        controller: this.controller
      })
    }
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐