【鸿蒙开发实战篇】基于AVPlayer播放网络视频案例

大家好,我是 V 哥。今天我们来详细讲解在 HarmonyOS 6.0(API 21)中,如何使用 AVPlayer 实现网络视频播放功能。AVPlayer 是鸿蒙系统提供的一个功能完善的音视频播放 ArkTS API,它集成了流媒体和本地资源解析、媒体资源解封装、视频解码和渲染功能,能够直接播放 MP4、MKV 等格式的网络视频文件。

联系V哥获取 鸿蒙学习资料

一、功能概述与开发准备

AVPlayer 核心能力

  • 端到端播放:支持网络流媒体(如 HLS、MP4)和本地文件的完整播放流程。
  • 播放控制:提供播放、暂停、跳转、停止、倍速播放等控制能力。
  • 状态监听 :通过 stateChangetimeUpdate 等事件监听播放器状态和进度变化。

开发环境配置module.json5 文件中添加必要的依赖和权限:

json 复制代码
{
  "module": {
    "dependencies": {
      "@ohos.multimedia.media": "^1.0"  // 媒体服务核心库
    },
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET",
        "reason": "用于播放网络视频"
      }
    ]
  }
}

二、实现步骤详解

步骤 1:创建 AVPlayer 实例

首先导入媒体模块并创建 AVPlayer 实例:

typescript 复制代码
import { media } from '@ohos.multimedia.media';

// 创建 AVPlayer 实例
let avPlayer: media.AVPlayer | undefined = undefined;

async function createAVPlayer(): Promise<void> {
  try {
    avPlayer = await media.createAVPlayer();
    console.info('AVPlayer 创建成功');
  } catch (error) {
    console.error(`AVPlayer 创建失败: ${error.code}, ${error.message}`);
  }
}

步骤 2:设置播放窗口(Surface)

AVPlayer 需要通过 XComponent 获取 SurfaceID 来设置视频渲染窗口:

typescript 复制代码
import { XComponent } from '@ohos.arkui.node';

@Entry
@Component
struct VideoPage {
  @State surfaceId: string = '';
  xComponentController: XComponentController = new XComponentController();

  build() {
    Column() {
      // XComponent 用于显示视频画面
      XComponent({
        id: 'video_surface',
        type: XComponentType.SURFACE,
        controller: this.xComponentController
      })
        .onLoad(() => {
          // 获取 SurfaceID 并设置给 AVPlayer
          this.surfaceId = this.xComponentController.getXComponentSurfaceId();
          this.setSurface();
        })
        .width('100%')
        .height(300)
    }
  }

  async setSurface() {
    if (avPlayer && this.surfaceId) {
      await avPlayer.surfaceId = this.surfaceId;
    }
  }
}

步骤 3:设置网络视频资源并准备播放

配置网络视频 URL 并初始化播放器:

typescript 复制代码
async function setupVideoSource(): Promise<void> {
  if (!avPlayer) return;

  try {
    // 设置网络视频 URL
    let url = 'https://example.com/sample.mp4'; //改成自己的哈
    avPlayer.url = url;
    
    // 监听状态变化
    avPlayer.on('stateChange', (state: media.AVPlayerState) => {
      switch (state) {
        case media.AVPlayerState.IDLE:
          console.info('播放器处于闲置状态');
          break;
        case media.AVPlayerState.INITIALIZED:
          console.info('资源初始化完成');
          break;
        case media.AVPlayerState.PREPARED:
          console.info('播放器已准备就绪');
          this.startPlayback(); // 自动开始播放
          break;
        case media.AVPlayerState.PLAYING:
          console.info('视频播放中');
          break;
        case media.AVPlayerState.PAUSED:
          console.info('视频已暂停');
          break;
        case media.AVPlayerState.COMPLETED:
          console.info('播放完成');
          break;
      }
    });

    // 准备播放
    await avPlayer.prepare();
    console.info('播放器准备完成');
  } catch (error) {
    console.error(`设置视频源失败: ${error.code}, ${error.message}`);
  }
}

步骤 4:实现播放控制功能

实现基本的播放控制方法:

typescript 复制代码
// 开始播放
async function startPlayback(): Promise<void> {
  if (avPlayer && avPlayer.state === media.AVPlayerState.PREPARED) {
    await avPlayer.play();
  }
}

// 暂停播放
async function pausePlayback(): Promise<void> {
  if (avPlayer && avPlayer.state === media.AVPlayerState.PLAYING) {
    await avPlayer.pause();
  }
}

// 跳转到指定位置(单位:毫秒)
async function seekTo(position: number): Promise<void> {
  if (avPlayer) {
    await avPlayer.seek(position);
  }
}

// 停止播放并重置
async function stopPlayback(): Promise<void> {
  if (avPlayer) {
    await avPlayer.stop();
    await avPlayer.reset(); // 重置到 idle 状态
  }
}

步骤 5:实现进度监听与显示

通过 timeUpdate 事件监听播放进度:

typescript 复制代码
@State currentPosition: number = 0;
@State duration: number = 0;

function setupProgressListener(): void {
  if (!avPlayer) return;

  // 监听时间更新
  avPlayer.on('timeUpdate', (time: number) => {
    this.currentPosition = time;
  });

  // 监听视频时长
  avPlayer.on('durationUpdate', (duration: number) => {
    this.duration = duration;
  });
}

三、完整案例:网络视频播放器

以下是一个完整的网络视频播放器实现:

typescript 复制代码
@Entry
@Component
struct NetworkVideoPlayer {
  @State surfaceId: string = '';
  @State currentPos: number = 0;
  @State totalDuration: number = 0;
  @State isPlaying: boolean = false;
  
  xComponentController: XComponentController = new XComponentController();
  avPlayer: media.AVPlayer | undefined = undefined;

  aboutToAppear() {
    this.initAVPlayer();
  }

  async initAVPlayer() {
    try {
      this.avPlayer = await media.createAVPlayer();
      this.setupEventListeners();
    } catch (error) {
      console.error(`播放器初始化失败: ${error.message}`);
    }
  }

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

    // 状态监听
    this.avPlayer.on('stateChange', (state: media.AVPlayerState) => {
      if (state === media.AVPlayerState.PREPARED) {
        this.avPlayer?.play();
        this.isPlaying = true;
      }
    });

    // 进度监听
    this.avPlayer.on('timeUpdate', (time: number) => {
      this.currentPos = time;
    });

    this.avPlayer.on('durationUpdate', (duration: number) => {
      this.totalDuration = duration;
    });
  }

  async setupVideoSource() {
    if (!this.avPlayer || !this.surfaceId) return;

    try {
      //改成自己的url地址哈
      this.avPlayer.url = 'https://example.com/sample.mp4';
      this.avPlayer.surfaceId = this.surfaceId;
      await this.avPlayer.prepare();
    } catch (error) {
      console.error(`视频源设置失败: ${error.message}`);
    }
  }

  build() {
    Column() {
      // 视频显示区域
      XComponent({
        id: 'video_surface',
        type: XComponentType.SURFACE,
        controller: this.xComponentController
      })
        .onLoad(() => {
          this.surfaceId = this.xComponentController.getXComponentSurfaceId();
          this.setupVideoSource();
        })
        .width('100%')
        .height(300)

      // 控制面板
      Row({ space: 20 }) {
        Button(this.isPlaying ? '暂停' : '播放')
          .onClick(() => {
            if (this.isPlaying) {
              this.avPlayer?.pause();
              this.isPlaying = false;
            } else {
              this.avPlayer?.play();
              this.isPlaying = true;
            }
          })
        
        Text(`${this.formatTime(this.currentPos)}/${this.formatTime(this.totalDuration)}`)
          .fontSize(14)
      }
      .margin(10)
    }
  }

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

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

四、关键注意事项

  1. 网络权限与安全 :确保在 module.json5 中声明 INTERNET 权限,并使用 HTTPS 链接保证网络安全。

  2. 状态机管理:AVPlayer 有严格的状态机(idle → initialized → prepared → playing 等),必须在合适的状态下调用相应方法。

  3. 资源释放 :在页面销毁时务必调用 release() 方法释放资源,防止内存泄漏:

typescript 复制代码
aboutToDisappear() {
  if (this.avPlayer) {
    this.avPlayer.release();
    this.avPlayer = undefined;
  }
}
  1. 错误处理:增加网络状态监听,处理弱网或断网情况:
typescript 复制代码
avPlayer.on('error', (error: BusinessError) => {
  console.error(`播放错误: ${error.code}, ${error.message}`);
  // 可在此添加重试逻辑或用户提示
});

五、总结

通过本文的详细实现步骤,我们掌握了在 HarmonyOS 6.0 中使用 AVPlayer 播放网络视频的完整流程。关键点包括:正确创建 AVPlayer 实例、通过 XComponent 设置播放窗口、配置网络视频源、实现播放控制以及合理的资源管理。AVPlayer 提供了强大的视频播放能力,结合正确的状态管理和错误处理,可以开发出体验良好的网络视频播放应用。

希望这篇文章能帮助你在鸿蒙应用开发中顺利实现视频播放功能!

相关推荐
Kevin Coding4 小时前
JsonConvert:适用于 Android、鸿蒙与 Flutter 的 JSON 转 Model 插件
android·flutter·harmonyos
m0_749690236 小时前
【寻迹校园 HarmonyOS NEXT 实战 28】不交换手机号也能交接:固定校内交接点的隐私设计
华为·harmonyos·arkts·产品设计·隐私设计·安全交接
Magic-ZYJ6 小时前
HarmonyOS Stage 模型实战:UIAbility 生命周期如何驱动页面安全状态
安全·华为·harmonyos·鸿蒙·移动端开发·独立开发者·心晴手记
贾伟康6 小时前
【中国方言题库|09】HarmonyOS ArkTS 方言搜索实战:实现词语检索和无结果反馈
harmonyos·arkts·状态管理·arkui·本地搜索
Dovis(誓平步青云)7 小时前
从手机单栏到平板分栏:任务清单的筛选、选中态与不可变更新
华为·harmonyos
梦想不只是梦与想7 小时前
鸿蒙 AppGallery Connect:查看应用信息(三)
harmonyos·appgallery·client id·app id·developer id
贾伟康7 小时前
【中国方言题库|03】HarmonyOS ArkTS 四川话分库实战:复用题库组件并保持地区参数清晰
harmonyos·arkts·arkui·路由传参·组件复用
贾伟康7 小时前
【中国方言题库|10】HarmonyOS ArkTS 语音播放实战:管理读音播放与页面生命周期
生命周期·harmonyos·arkts·语音合成·texttospeech
YM52e18 小时前
鸿蒙ArkTS实战项目 - 门店陈列巡检台:巡检卡片与多列切换实现
学习·华为·harmonyos
lilian23319 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos