HarmonyOS鸿蒙Next中如何使用AVPlayer实现视频播放功能?

HarmonyOS鸿蒙Next中如何使用AVPlayer实现视频播放功能? 我需要在应用中播放视频,如何使用 XComponent 显示视频画面?如何实现全屏播放?

3 回复

实现思路:

  1. 使用 XComponent 创建视频渲染表面:
XComponent({
  id: 'videoPlayer',
  type: XComponentType.SURFACE,
  controller: this.xComponentController
})
.onLoad(() => {
  this.surfaceId = this.xComponentController.getXComponentSurfaceId();
})
  1. 将 surfaceId 绑定到 AVPlayer:
avPlayer.surfaceId = this.surfaceId;
avPlayer.url = 'https://example.com/video.mp4';
  1. 监听状态变化并控制播放:
avPlayer.on('stateChange', (state: string) => {
  if (state === 'initialized') {
    avPlayer.prepare();
  } else if (state === 'prepared') {
    avPlayer.play();
  }
});
  1. 完整示例代码:
import { media } from '@kit.MediaKit';

@Entry
@Component
struct VideoPlayerPage {
  private avPlayer: media.AVPlayer | null = null;
  private xComponentController: XComponentController = new XComponentController();
  private surfaceId: string = '';
  @State isPlaying: boolean = false;
  @State currentTime: number = 0;
  @State duration: number = 0;
  @State isFullScreen: boolean = false;

  async aboutToAppear() {
    this.avPlayer = await media.createAVPlayer();
    this.setupPlayerCallbacks();
  }

  aboutToDisappear() {
    if (this.avPlayer) {
      this.avPlayer.release();
      this.avPlayer = null;
    }
  }

  setupPlayerCallbacks() {
    if (!this.avPlayer) return;

    this.avPlayer.on('stateChange', (state: string) => {
      console.info(`Video state: ${state}`);
      if (state === 'initialized') {
        this.avPlayer!.surfaceId = this.surfaceId;
        this.avPlayer!.prepare();
      } else if (state === 'prepared') {
        this.duration = this.avPlayer!.duration || 0;
        this.avPlayer!.play();
        this.isPlaying = true;
      } else if (state === 'completed') {
        this.isPlaying = false;
      }
    });

    this.avPlayer.on('timeUpdate', (time: number) => {
      this.currentTime = time;
    });
  }

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

  build() {
    Stack() {
      Column() {
        // 视频画面
        XComponent({
          id: 'videoPlayer',
          type: XComponentType.SURFACE,
          controller: this.xComponentController
        })
          .width('100%')
          .height(this.isFullScreen ? '100%' : 220)
          .onLoad(() => {
            this.surfaceId = this.xComponentController.getXComponentSurfaceId();
            if (this.avPlayer) {
              this.avPlayer.url = 'https://example.com/video.mp4';
            }
          })

        // 控制栏
        if (!this.isFullScreen) {
          Column({ space: 12 }) {
            // 进度条
            Row() {
              Text(this.formatTime(this.currentTime)).fontSize(12)
              Slider({
                value: this.duration > 0 ? (this.currentTime / this.duration) * 100 : 0,
                min: 0,
                max: 100
              })
                .layoutWeight(1)
                .onChange((value: number) => {
                  const seekTime = (value / 100) * this.duration;
                  this.avPlayer?.seek(seekTime);
                })
              Text(this.formatTime(this.duration)).fontSize(12)
            }
            .width('100%')
            .padding({ left: 16, right: 16 })

            // 按钮
            Row({ space: 20 }) {
              Button(this.isPlaying ? '暂停' : '播放')
                .onClick(() => {
                  if (this.isPlaying) {
                    this.avPlayer?.pause();
                  } else {
                    this.avPlayer?.play();
                  }
                  this.isPlaying = !this.isPlaying;
                })

              Button('全屏').onClick(() => {
                this.isFullScreen = true;
              })
            }
          }
          .padding(16)
        }
      }

      // 全屏时的返回按钮
      if (this.isFullScreen) {
        Button('退出全屏')
          .position({ x: 16, y: 16 })
          .onClick(() => {
            this.isFullScreen = false;
          })
      }
    }
    .width('100%')
    .height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中如何使用AVPlayer实现视频播放功能?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,使用AVPlayer实现视频播放需导入@ohos.multimedia.media模块。首先创建AVPlayer实例,通过createAVPlayer()初始化。设置视频源使用url属性指定文件路径或网络URL。调用prepare()加载资源,随后play()开始播放。可监听stateChange事件处理播放状态。

在HarmonyOS Next中,使用AVPlayer结合XComponent实现视频播放的步骤如下:

  1. 导入模块

    import { avPlayer } from '[@kit](/user/kit).AudioKit';
    import { XComponent } from '[@ohos](/user/ohos).arkui.node';
    
  2. 创建AVPlayer实例

    let avPlayer: avPlayer.AVPlayer = await avPlayer.createAVPlayer();
    
  3. 设置XComponent作为视频渲染表面

    • 在ArkUI中声明XComponent:
      XComponent({
        id: 'xcomponentId',
        type: 'surface',
        controller: this.xComponentController
      })
      
    • 获取Surface ID并设置给AVPlayer:
      let surfaceId = this.xComponentController.getXComponentSurfaceId();
      avPlayer.surfaceId = surfaceId;
      
  4. 配置播放源并准备播放

    avPlayer.url = '视频URL或本地路径';
    await avPlayer.prepare();
    avPlayer.play();
    
  5. 实现全屏播放

    • 通过调整XComponent的宽高占满屏幕,或切换至全屏页面/窗口。
    • 监听设备方向变化,动态调整布局:
      // 监听屏幕旋转
      display.on('rotate', (curRotation) => {
        // 调整XComponent为全屏尺寸
      });
      
    • 可结合窗口模块([@ohos](/user/ohos).window)设置全屏模式。

关键点

  • 确保XComponent的type设置为’surface’。
  • 通过AVPlayer的事件监听(如’onStateChange’)处理播放状态。
  • 全屏时需管理UI布局、状态栏和导航栏的隐藏。

按以上步骤即可实现视频播放及全屏功能。

回到顶部