HarmonyOS开发案例:【视频播放器】

介绍

基于video、swiper和slider组件,实现简单的视频播放器,可支持海报轮播、视频播放等功能。

相关概念

  • [video组件]:视频播放组件。
  • [swiper组件]:滑动容器,提供切换子组件显示的能力。
  • [slider组件]:滑动z条组件,用来快速调节设置值,如音量、亮度等。

环境搭建

软件要求

  • [DevEco Studio]版本:DevEco Studio 3.1 Release及以上版本。
  • OpenHarmony SDK版本:API version 9及以上版本。

硬件要求

  • 开发板类型:[润和RK3568开发板]。
  • OpenHarmony系统:3.2 Release及以上版本。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。以3.2 Release版本为例:

  2. 搭建烧录环境。

    1. [完成DevEco Device Tool的安装]
    2. [完成RK3568开发板的烧录]
  3. 搭建开发环境。

    1. 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”)。
    3. 工程创建完成后,选择使用[真机进行调测]。
    4. 鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。

搜狗高速浏览器截图20240326151450.png

代码结构解读

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在gitee中提供。、

HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿

├──entry/src/main/js                          // 代码区
│  └──MainAbility   
│     ├──common
│     │  ├──constant
│     │  │  └──commonConstants.js             // 公共常量类
│     │  ├──images                            // 图片文件
│     │  └──video
│     │     └──video.mp4                      // 视频文件
│     ├──i18n
│     │  ├──en-US.json	                      // 英文国际化
│     │  └──zh-CN.json	                      // 中文国际化
│     ├──pages
│     │  ├──homePage
│     │  │  ├──homePage.css                   // 主页面样式
│     │	 │  ├──homePage.hml                   // 主页面
│     │	 │  └──homePage.js                    // 主页面逻辑
│     │  └──videoPage
│     │     ├──videoPage.css                  // 播放页面样式
│     │	    ├──videoPage.hml                  // 播放页面
│     │	    └──videoPage.js                   // 播放页面逻辑
│     └──app.js                               // 程序入口
└──entry/src/main/resource                    // 应用静态资源目录

主页面

主页面分为轮播图区域和滑动图区域两部分,效果如图所示:

轮播图使用swiper组件自动播放轮播图片,点击图片跳转到视频播放页面。

<!-- homePage.hml -->
<div class="container">
    <swiper class="swiper" id="swiper" index="0" autoplay='true' indicator="true"
            loop="true" digital="false">
        <image class="swiper-img" src="{{ swiperVideos[0] }}" onclick="playVideo"></image>
        <image class="swiper-img" src="{{ swiperVideos[1] }}" onclick="playVideo"></image>
        <image class="swiper-img" src="{{ swiperVideos[2] }}" onclick="playVideo"></image>
    </swiper>
    ...
</div>
// homePage.js
export default {
  data: {
    swiperVideos: [],
    ...
  },

  // 初始化数据
  onInit() {
    ...
  },

  // 跳转到视频播放页面
  playVideo() {
    router.push({
      url: CommonConstants.PLAY_PAGE
    });
  },
};

滑动图区域分为最近播放和为你推荐两部分,使用List组件进行纵向排列;最近播放和为你推荐中的图片使用List组件进行横向排列,可滑动图片,点击图片跳转到播放页面。

<!-- homePage.hml -->
<div class="container">
    ...
    <div class="horizontal-area">
        <list class="todo-wrapper">
            <list-item for="{{ horizontal_description }}" class="todo-item" clickeffect="false">
                <div class="horizontal-area-div">
                    <text class="horizontal-area-description">{{ $item }}</text>
                    <list class="todo-wrapper">
                        <list-item for="{{ horizontal_videos }}" clickeffect="false" class="todo-item">
                            <div class="image-area" onclick="playVideo">
                                <image src="{{ $item.image }}"></image>
                                <text>{{ $item.name }}</text>
                            </div>
                        </list-item>
                    </list>
                </div>
            </list-item>
        </list>
    </div>
</div>
// homePage.js
export default {
  data: {
    ...
    horizontal_description: [],
    horizontal_videos: []
  },

  // 初始化数据
  onInit() {
    ...
  },

  // 跳转到视频播放页面
  playVideo() {
    router.push({
      url: CommonConstants.PLAY_PAGE
    });
  },
};

视频播放页面

视频播放页面主要分为标题栏、视频播放区域和进度条三个部分,效果如图所示:

标题栏包括返回图标和“视频”字样。

<!-- videoPage.hml -->
<div class="container">
    <div class="title">
        <image src="{{ playIcons.backSrc }}" onclick="back"></image>
        <text>{{ $t('strings.play') }}</text>
    </div>
    ...
</div>
// videoPage.js
export default {
  data: {
    playIcons: {},
    ...
  },

  // 初始化数据
  onInit() {
    this.playIcons = CommonConstants.PLAY_ICONS;
    ...
  },

  ...
};

当视频暂停时,视频区域展示暂停图标;当视频播放时,视频区域暂停图标隐藏,效果如图所示:

<!-- videoPage.hml -->
<div class="container">
    ...
    <video id="video" ...></video>
    <image class="play-image" show="{{ !isPlay }}" src="{{ playIcons.publicPlayIcon }}"></image>
    ...
</div>
// videoPage.js
export default {
  data: {
    playIcons: {},
    ...
    src: '',
    ...
    isPlay: false,
    ...
  },

  // 初始化数据
  onInit() {
    this.playIcons = CommonConstants.PLAY_ICONS;
    this.src = CommonConstants.VIDEO_SRC;
  },
  ...
};

进度条分为播放/暂停图标和进度条(进度条左边为当前视频播放时间,进度条右边为视频总时长)两部分。

<div class="container">
    ...
    <div class="progress">
        <div class="image-div">
            <image src="{{ isPlay ? playIcons.pauseIcon : playIcons.playIcon }}" onclick="startOrPause"></image>
        </div>
        <div class="slider-div">
            <text class="now-time">
                {{ nowTime }}
            </text>
            <slider min="{{ sliderMin }}" max="{{ sliderMax }}" value="{{ sliderValue }}"
                    mode="outset" onchange="change"></slider>
            <text class="duration-time">
                {{ durationTime }}
            </text>
        </div>
    </div>
</div>
// videoPage.js
export default {
  data: {
    playIcons: {},
    ...
    sliderMin: 0,
    sliderMax: 100,
    sliderValue: 0,
    nowTime: '00:00',
    duration: 0,
    durationTime: '00:00',
    isPlay: false,
    secondUnit: 60,
    zero: '0',
    initTime: '00:00',
    paddingLen: 2,
    milliSeconds: 1000,
    ...
  },

  // 初始化数据
  onInit() {
    this.playIcons = CommonConstants.PLAY_ICONS;
    ...
  },
  ...
};

视频播放逻辑

视频播放器可设置是否静音播放、视频路径、是否自动播放、是否显示控制栏、是否循环播放等属性。

<!-- index.hml -->
<video id="video"
       muted="{{ muted }}"
       src="{{ src }}"
       autoplay="{{ autoplay }}"
       controls="{{ controlShow }}"
       loop="{{ loop }}"
       ...
>
</video>
// index.js
data: {
  ...
  videoId: 'video', // 播放器id
  muted: false, // 是否静音播放
  src: '', // 视频地址
  autoplay: true, // 是否自动播放
  controlShow: false, // 是否显示控制栏
  loop: false, // 是否循环播放
  ...
},

视频加载完成后获取视频总时长,当视频开始播放后获取视频当前播放时间(单位:秒)并更新进度条的值;拖动进度条可设置视频播放位置,点击播放/暂停图标可对视频进行控制。

<!-- index.hml -->
<video id="video"
       ...
       onprepared="prepared"
       onstart="start"
       onpause="pause"
       onfinish="finish"
       ontimeupdate="timeUpdate">
</video>
...
<div class="progress">
    <div class="imageDiv">
        <image src="{{ isPlay ? playIcons.pauseIcon : playIcons.playIcon }}" onclick="startOrPause"></image>
    </div>
    <div class="sliderDiv">
        ...
        <slider min="{{ sliderMin }}" max="{{ sliderMax }}" value="{{ sliderValue }}"
                mode="outset" onchange="change"></slider>
        ...
    </div>
</div>
// index.js
...
// 视频准备完成
prepared(event) {
  this.duration = event.duration;
  this.durationTime = this.secondToTime(event.duration);
},

// 视频开始播放
start() {
  this.isPlay = true;
},
// 视频暂停播放
pause() {
  this.isPlay = false;
},

// 视频播放完成
finish() {
  setTimeout(() => {
    this.nowTime = this.initTime;
    this.sliderValue = this.sliderMin;
  }, this.milliSeconds);
},

// 播放进度变化
timeUpdate(event) {
  if ((this.currentTime != -1) && (this.currentTime !== event.currenttime)) {
    return;
  }
  this.currentTime = -1;
  let currSliderValue = event.currenttime / this.duration * this.sliderMax;
  this.sliderValue = ((this.sliderValue > currSliderValue) ? this.sliderValue : currSliderValue);
  let currTime = this.sliderValue * this.duration / this.sliderMax;
  this.nowTime = this.secondToTime(Math.round(currTime));
},
    
// 暂停或播放
startOrPause() {
  if (this.isPlay) {
    this.$element(this.videoId).pause();
  } else {
    this.$element(this.videoId).start();
  }
},
    
// 拖动进度条
change(event) {
  this.sliderValue = event.progress;
  this.currentTime = Math.round(this.duration * event.progress / this.sliderMax);
  this.$element(this.videoId).setCurrentTime({
    currenttime: this.currentTime
  });
},
...
<think>好的,用户想了解HarmonyOS视频播放器开发教程或使用方法。首先,我需要查阅提供的引用内容,看看有哪些相关的信息。引用1提到了ijkplayer,基于FFmpeg的视频播放器,适用于OpenHarmonyHarmonyOS。引用2和4讨论了AVPlayer和Video组件的使用,特别是AVPlayer的功能比较全面,支持多种格式,而Video组件可以设置播放属性如静音、控制条等。引用3是关于DevEco Studio的配置,这可能涉及到开发环境的搭建。引用5提到了一个回调接口,可能和播放器的事件处理有关。 用户的需求是寻找教程或使用方法,所以需要分步骤说明。首先应该介绍主要的视频播放方案,比如AVPlayer和Video组件,以及第三方库ijkplayer。然后,可能需要指导如何配置开发环境,比如安装DevEco Studio,创建项目。接下来,具体讲解如何使用这些组件,包括代码示例和参数设置。此外,可能还需要提到相关的事件处理和优化方法,比如使用回调接口处理播放状态。最后,生成相关问题,帮助用户深入了解更多细节。 需要注意的是,用户可能对不同的播放器方案有疑问,比如如何选择AVPlayer和Video组件,或者如何集成ijkplayer。因此,在回答中需要对比不同方案的适用场景,比如AVPlayer适合端到端播放,而Video组件适合简单场景。同时,代码示例要符合HarmonyOS的ArkTS语法,确保正确性。另外,引用对应的参考资料时要正确标注,例如使用AVPlayer的部分引用引用2和4。 可能还需要提醒用户关于权限申请的问题,比如访问媒体文件需要相应的权限配置,这在开发过程中容易被忽略。此外,播放控制如暂停、跳转等操作,也需要通过controller来实现,这部分应该在示例代码中体现。最后,生成的问题要围绕用户可能进一步关心的点,比如性能优化、高级功能实现等。</think>关于HarmonyOS视频播放器开发,以下是分步骤的教程及核心实现方法: ### 一、视频播放核心方案 1. **原生Video组件**(基础级) - 适用于简单播放场景,支持本地/网络视频 - 关键属性配置示例: ```typescript Video({ src: $rawfile('demo.mp4'), // 资源路径 controller: this.videoController }) .controls(true) // 显示控制条[^4] .autoPlay(false) .onPrepared(() => { console.log('资源加载完成') }) // 预加载回调[^4] ``` 2. **AVPlayer高级播放器**(企业级) - 支持流媒体协议(HTTP/RTSP/HLS) - 核心代码结构: ```typescript // 创建播放实例 const avPlayer = await media.createAVPlayer(); // 设置播放源 avPlayer.url = 'https://example.com/video.mp4'; // 注册回调监听[^5] avPlayer.registerCallback(this.mediaCallback); // 开始播放 avPlayer.play(); ``` 3. **第三方播放器集成** - ijkplayer基于FFmpeg开发,支持更多视频格式[^1] - 需通过Native API集成C++层代码 ### 二、开发环境配置 1. 安装DevEco Studio 3.1+(NEXT版本专用)[^3] 2. 创建ArkTS工程时勾选Multimedia特性 3. 配置权限: ```json "reqPermissions": [ { "name": "ohos.permission.INTERNET" }, // 网络播放 { "name": "ohos.permission.READ_MEDIA" } // 本地文件 ] ``` ### 三、播放控制实现 1. 进度控制: ```typescript // 跳转到指定时间 this.videoController.seek(120000); // 单位:毫秒 // 获取当前进度 const currentTime = this.videoController.getCurrentTime(); ``` 2. 状态监听: ```typescript @State playbackStatus: string = 'stopped'; Video(...) .onPlay(() => { this.playbackStatus = 'playing'; }) .onPause(() => { this.playbackStatus = 'paused'; }) ``` ### 四、性能优化建议 1. 预加载缓冲: ```typescript avPlayer.setParameter({ key: 'preferred_buffer_duration', value: '5000' // 5秒缓冲 })[^2]; ``` 2. 分辨率适配: ```typescript Video(...) .objectFit(ImageFit.Cover) // 填充模式 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值