HarmonyOS NEXT Practical: Play Video

victordengvictordeng
3 min read

Objective: To achieve the playback, pause, end playback, reset, and jump to specific positions for video components.

The Video component is used to play video files and control their playback status, commonly used for short video and internal video list pages in applications. When the video appears in its entirety, it will automatically play. When the user clicks on the video area, it will pause playback and display a playback progress bar. By dragging the playback progress bar, the video can be played to a specific location. Please refer to the video for specific usage.

Load video resources The Video component supports loading both local and network videos.

Add attribute The Video component properties are mainly used to set the playback format of the video. For example, setting whether to mute video playback and whether to display control bars during playback.

Event call The callback events of the Video component mainly include playback start, pause end, playback failure, playback stop, video preparation, and operation progress bar. In addition, the Video component also supports calling general events such as click, touch, etc.

Video Controller Usage The Video Controller is mainly used to control the status of videos, including playing, pausing, stopping, and setting progress. For detailed usage, please refer to the VideoController user manual.

  • Default controller: The default controller supports four basic functions of video start, pause, progress adjustment, and full screen display.

  • Custom controller: To use a custom controller, first turn off the default controller, and then use components such as buttons and sliders for custom control and display, suitable for use in scenarios with strong customization.

others The Video component has already encapsulated the basic capabilities of video playback, and developers do not need to create video instances or set up video information. They only need to set up data sources and basic information to play videos, which has relatively weak scalability.

Actual combat: VideoPage

@Entry
@Component
struct VideoPage {
  @State videoSrc: Resource = $rawfile('video_demo.mp4')
  @State previewUri: Resource = $rawfile('video_preview.jpg')
  @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X
  @State isAutoPlay: boolean = false
  @State showControls: boolean = true
  @State isShortcutKeyEnabled: boolean = false
  controller: VideoController = new VideoController()

  build() {
    Column() {
      Video({
        src: this.videoSrc,
        previewUri: this.previewUri,
        currentProgressRate: this.curRate,
        controller: this.controller
      })
        .width('100%')
        .aspectRatio(16/9)
        .autoPlay(this.isAutoPlay)
        .controls(this.showControls)
        .enableShortcutKey(this.isShortcutKeyEnabled)
        .onStart(() => {
          console.info('onStart')
        })
        .onPause(() => {
          console.info('onPause')
        })
        .onFinish(() => {
          console.info('onFinish')
        })
        .onError(() => {
          console.info('onError')
        })
        .onStop(() => {
          console.info('onStop')
        })
        .onPrepared((e?: DurationObject) => {
          if (e != undefined) {
            console.info('onPrepared is ' + e.duration)
          }
        })
        .onSeeking((e?: TimeObject) => {
          if (e != undefined) {
            console.info('onSeeking is ' + e.time)
          }
        })
        .onSeeked((e?: TimeObject) => {
          if (e != undefined) {
            console.info('onSeeked is ' + e.time)
          }
        })
        .onUpdate((e?: TimeObject) => {
          if (e != undefined) {
            console.info('onUpdate is ' + e.time)
          }
        })
        .onFullscreenChange((e?: FullscreenObject) => {
          if (e != undefined) {
            console.info('onFullscreenChange is ' + e.fullscreen)
          }
        })

      Row() {
        Button('播放').onClick(() => {
          this.controller.start() // 开始播放
        }).margin(2)
        Button('暂停').onClick(() => {
          this.controller.pause() // 暂停播放
        }).margin(2)
        Button('结束播放').onClick(() => {
          this.controller.stop() // 结束播放
        }).margin(2)
      }

      Row(){
        Button('重置视频').onClick(() => {
          this.controller.reset() // 重置AVPlayer
        }).margin(2)
        Button('跳至第10秒').onClick(() => {
          this.controller.setCurrentTime(10, SeekMode.Accurate) // 精准跳转到视频的10s位置
        }).margin(2)
      }
    }
  }
}

interface DurationObject {
  duration: number;
}

interface TimeObject {
  time: number;
}

interface FullscreenObject {
  fullscreen: boolean;
}
0
Subscribe to my newsletter

Read articles from victordeng directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

victordeng
victordeng