今天我们来深入探讨HarmonyOS Next中几种核心媒体展示组件的使用方法,通过实际代码示例展示如何打造丰富的多媒体体验。

HarmonyOS Next为开发者提供了一套强大而灵活的媒体展示组件,使开发者能够轻松实现视频播放、动态布局适应、全屏切换等常见多媒体功能。无论是构建短视频应用、视频直播平台还是内容丰富的媒体浏览应用,这些组件都能提供强有力的支持。

本文将重点介绍Video组件、AVPlayer与XComponent的结合使用,以及如何通过媒体查询实现动态布局,帮助开发者快速掌握鸿蒙Next媒体开发的核心技能。

1. Video组件基础使用

Video组件是鸿蒙多媒体系统中最常用的组件之一,它提供了开箱即用的视频播放功能8。

1.1 基本参数配置

创建一个基础Video组件非常简单,以下是一个基本示例:

typescript

// Video基础使用示例
Video({src: $rawfile('video.mp4'), // 视频资源路径,支持本地和网络路径previewUri: $r('app.media.preview'), // 未播放时的预览图片controller: this.videoController // 视频控制器
})
.width('100%')
.aspectRatio(1.78) // 设置宽高比
.controls(true) // 显示控制栏
.autoPlay(false) // 不自动播放
.loop(false) // 不循环播放
.objectFit(ImageFit.Cover) // 视频显示模式
.onPrepared((event) => {console.info('视频准备完成,时长:' + event.duration + '秒');
})
.onUpdate((event) => {console.info('当前播放进度:' + event.time);
})
.onFinish(() => {console.info('视频播放结束');
})

Video组件支持多种参数配置:8

  • src: 视频源,支持本地路径(如$rawfile('video.mp4'))和网络URL

  • previewUri: 视频未播放时显示的预览图

  • controller: 视频控制器,用于控制播放、暂停等操作

  • currentProgressRate: 播放倍速,支持0.75、1.0、1.25、1.75、2.0

1.2 视频控制功能

通过VideoController可以实现对视频的精确控制:8

typescript

// 创建VideoController
private videoController: VideoController = new VideoController();// 在build方法中使用
Video({src: this.videoSrc,controller: this.videoController
})// 播放控制方法
playVideo() {this.videoController.start();
}pauseVideo() {this.videoController.pause();
}stopVideo() {this.videoController.stop();
}seekTo(position: number) {this.videoController.seekTo(position);
}

2. 全屏切换功能实现

全屏切换是视频应用中的常见需求,鸿蒙Next提供了多种实现方式。

2.1 使用Video组件内置全屏功能

Video组件提供了onFullscreenChange回调,可以轻松实现全屏切换:6

typescript

Video({src: this.videoSrc,controller: this.videoController
})
.onFullscreenChange((event) => {// 横竖屏切换this.windowChange(event.fullscreen);
})// 全屏切换方法
windowChange(isFullscreen: boolean) {let context = getContext(this);window.getLastWindow(context).then((lastWindow) => {if (isFullscreen) {// 设置全屏lastWindow.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE);lastWindow.setWindowSystemBarEnable([]); // 隐藏系统栏} else {// 退出全屏lastWindow.setPreferredOrientation(window.Orientation.PORTRAIT);lastWindow.setWindowSystemBarEnable(['status', 'navigation']); // 显示系统栏}});
}

2.2 使用AVPlayer和XComponent实现高级全屏功能

对于需要更自定义控制的场景,可以使用AVPlayer和XComponent组合:5

typescript

// 初始化AVPlayer
async initAVPlayer() {await this.release();const context = getContext(this);// 获取资源文件描述符context.resourceManager.getRawFd(this.fileName).then(async (value) => {this.avPlayer = await media.createAVPlayer();this.avPlayer.fdSrc = {fd: value.fd,offset: value.offset,length: value.length};// 设置surfaceIdthis.setSurfaceID();});
}// 将XComponent与AVPlayer绑定
setSurfaceID() {this.avPlayer.surfaceId = this.surfaceID;
}// 全屏切换动画
toggleFullScreen() {animateTo({duration: 300,onFinish: () => {this.isLandscape = !this.isLandscape;this.changeOrientation();}}, () => {this.isFullScreen = !this.isFullScreen;});
}// 改变屏幕方向
changeOrientation() {let context = getContext(this);window.getLastWindow(context).then((lastWindow) => {if (this.isLandscape) {// 横屏模式lastWindow.setWindowLayoutFullScreen(true, () => {lastWindow.setWindowSystemBarEnable([]);lastWindow.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE);});} else {// 竖屏模式lastWindow.setPreferredOrientation(window.Orientation.UNSPECIFIED, () => {lastWindow.setWindowSystemBarEnable(['status', 'navigation'], () => {lastWindow.setWindowLayoutFullScreen(false);});});}});
}

3. 小窗口播放模式

小窗口播放是现代视频应用的重要特性,允许用户在浏览其他内容时继续观看视频13。

typescript

// 小窗口播放组件
@Component
struct SmallVideoComponent {private controller: VideoController;private currentTime: number = 0;build() {Column() {Video({src: $rawfile('video.mp4'),controller: this.controller}).width(200).height(120).controls(false).objectFit(ImageFit.Cover).onUpdate((event) => {this.currentTime = event.time;})}.onClick(() => {// 点击小窗口切换回全屏this.switchToFullScreen();})}
}// 在主页中实现滚动时切换小窗口
@Entry@Component
struct MainPage {private scroller: Scroller = new Scroller();@State isSmallWindow: boolean = false;build() {Scroll(this.scroller) {Column() {// 主内容区域if (!this.isSmallWindow) {VideoPlayerComponent()}// 其他内容ForEach(this.contentList, (item) => {ContentItem(item)})}.onScroll(() => {// 滚动超过500vp时切换为小窗口if (this.scroller.currentOffset().yOffset > 500 && !this.isSmallWindow) {this.isSmallWindow = true;} else if (this.scroller.currentOffset().yOffset <= 500 && this.isSmallWindow) {this.isSmallWindow = false;}})}// 显示小窗口if (this.isSmallWindow) {SmallVideoComponent().position({x: 20, y: 20})}}
}

4. 基于媒体查询的动态布局

鸿蒙的媒体查询模块允许根据设备特性动态调整布局,提供响应式体验2。

typescript

import mediaquery from '@ohos.mediaquery';// 创建媒体查询监听器
let resolutionListener = mediaquery.matchMediaSync('(resolution > 2dppx)');
let orientationListener = mediaquery.matchMediaSync('(orientation: landscape)');// 根据设备分辨率调整布局
resolutionListener.on('change', (mediaQueryResult) => {if (mediaQueryResult.matches) {// 高分辨率设备布局this.videoWidth = '100%';this.videoHeight = 360;this.controlsSize = 24;} else {// 低分辨率设备布局this.videoWidth = '100%';this.videoHeight = 240;this.controlsSize = 20;}
});// 根据屏幕方向调整布局
orientationListener.on('change', (mediaQueryResult) => {if (mediaQueryResult.matches) {// 横屏布局this.isLandscape = true;this.videoWidth = '100%';this.videoHeight = '100%';} else {// 竖屏布局this.isLandscape = false;this.videoWidth = '100%';this.videoHeight = 300;}
});// 在组件中使用响应式变量
Video({src: this.videoSrc,controller: this.videoController
})
.width(this.videoWidth)
.height(this.videoHeight)
.controls(true)

5. 直播流媒体实现

鸿蒙Next同样支持直播流媒体播放,以下是实现直播功能的关键代码13:

typescript

// 直播页面组件
@Component
struct LivePage {private liveController: VideoController = new VideoController();@State currentLive: LiveDataModel = null;@State liveList: LiveDataModel[] = [];aboutToAppear() {// 获取直播数据this.getLiveData();}// 获取直播数据async getLiveData() {try {this.liveList = await LiveUtils.getLiveList();if (this.liveList.length > 0) {this.currentLive = this.liveList[0];}} catch (error) {console.error('获取直播数据失败: ' + JSON.stringify(error));}}build() {Swiper() {ForEach(this.liveList, (liveItem) => {Column() {Video({src: liveItem.streamUrl,controller: this.liveController}).width('100%').height('100%').objectFit(ImageFit.Cover).controls(true).loop(true)// 直播叠加信息LiveOverlay(liveItem)}})}.index(this.currentIndex).autoPlay(false).indicator(false).vertical(true).onChange((index) => {// 切换直播流this.liveController.stop();this.currentLive = this.liveList[index];this.liveController.start();})}
}

6. 性能优化技巧

在媒体应用开发中,性能优化至关重要56。

6.1 使用LazyForEach懒加载

typescript

// 使用LazyForEach优化长列表性能
LazyForEach(this.liveDataSource, (liveItem: LiveDataModel) => {LiveItemComponent({ liveItem: liveItem })
}, (liveItem: LiveDataModel) => liveItem.id.toString())

6.2 组件复用优化

typescript

// 使用@Reusable装饰器实现组件复用
@Reusable
@Component
struct VideoPlayerComponent {@Prop videoItem: VideoItem;build() {Column() {Video({src: this.videoItem.url,previewUri: this.videoItem.thumbnail}).width('100%').height(200)}}
}

总结

HarmonyOS Next提供了丰富而强大的媒体展示组件,从简单的Video组件到高级的AVPlayer与XComponent组合,可以满足各种多媒体应用场景的需求。通过本文介绍的几种媒体展示组件的使用方法,开发者可以快速构建功能丰富、性能优异的媒体应用。

关键要点包括:135

  1. Video组件提供了开箱即用的视频播放功能,适合大多数基本场景

  2. AVPlayer与XComponent组合提供了更高级的自定义控制能力

  3. 全屏切换可以通过Video组件内置功能或自定义实现

  4. 小窗口播放增强了用户体验,允许后台播放

  5. 媒体查询实现了响应式布局,适应不同设备特性

  6. 性能优化技术如LazyForEach和@Reusable确保了流畅体验

鸿蒙Next的媒体能力仍在不断发展,建议开发者定期查阅官方文档以获取最新功能和最佳实践。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95006.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95006.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95006.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

复现RoboDK机器人校准功能(以Staubli TX2‑90L / TX200机械臂为测试对象,实测精度接近原厂)

本算法复现了 RoboDK 的机器人校准功能&#xff1a;在训练集的理论校准后精度与 RoboDK 一致&#xff0c;在测试集的实测精度接近 Staubli 原厂。 参考&#xff1a;RoboDK 机器人校准功能&#xff08;https://robodk.com.cn/cn/robot-calibration&#xff09; 特性 支持 SDH 参…

Vue常用指令和生命周期

Vue 是基于 MVVM模型的前端 JavaScript 框架。Vue 核心是数据驱动视图&#xff0c;通过响应式数据实现视图自动更新。<template><div>{{ message }}</div><button click"changeMsg">修改内容</button> </template><script se…

深度学习周报(8.25~8.31)

目录 摘要 Abstract 1 RNN学习意义 2 RNN基础知识 2.1 核心思想 2.2 传播 2.3 优缺点 2.4 变体结构与应用场景 3 RNN结构代码示例 4 总结 摘要 本周主要学习了循环神经网络的学习意义与基础知识&#xff0c;重点了解了RNN循环连接的核心思想、前向传播与反向传播过程…

借助 LAMBDA 公式,实现单元格区域高效转换

新特性介绍 “转换单元格&#xff08;Transform&#xff09;” 功能允许用户将自定义的单参数 LAMBDA 公式应用于选中的单元格区域。用户可选择公式参数的作用域 —— 按单元格、按行、按列或按整个区域。 转换完成后&#xff0c;源单元格区域会被清空&#xff0c;转换后的区…

LeetCode 01背包 494. 目标和

494. 目标和给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 ‘’ &#xff0c;在 1 之前…

Dify 1.8.0 全网首发,预告发布

距离Dify 1.7.2过去两周了 Dify 1.8.0 又跟大伙见面了&#xff01; 1.8.0&#xff0c;属于主版本号不变、但第二位数字更新的“阶段性大更”&#xff0c;意味着功能上的显著优化和体验上的重要升级。 根据官方的Github日志&#xff0c;这一版本将继续聚焦三大核心方向&#x…

基于LangChain框架搭建AI问答系统(附源码)

AI问答系统1. 背景知识2. 问答系统流程3. 知识问答系统相关组件3.1 文档加载器3.2 文档切割器3.3 嵌入模型包装器3.4 向量存储库3.5 模型包装器3.6 链组件4. 问答系统演示4.1 问答程序4.2 演示大模型回答效果5.问答系统代码1. 背景知识 在人工智能技术飞速发展的今天&#xff…

【Python】QT(PySide2、PyQt5):Qt Designer,VS Code使用designer,可能的报错

Qt designer&#xff1a;可直接在designer界面&#xff0c;使用拖拽的方式设计需要的界面&#xff0c;可设定部分属性。安装Pyside2后&#xff0c;designer默认在python安装目录的Lib/sit_packages/PySide2文件夹中。designer使用&#xff1a;① 双击打开designer.exe&#xff…

前端常见安全问题 + 防御方法 + 面试回答

目录 XSS&#xff08;跨站脚本攻击&#xff09;CSRF&#xff08;跨站请求伪造&#xff09;SQL 注入文件上传漏洞其他前端常见安全问题面试常见问答 1. XSS&#xff08;跨站脚本攻击&#xff09; 定义 XSS&#xff08;Cross-Site Scripting&#xff09;是一种 通过注入恶意脚…

jxWebUI--下拉选择框

下拉选择框提供了预先定义好的选项&#xff0c;用户只能在这些选项中选择输入。 combobox 定义格式 combobox 控件名 属性列表 ;属性 bind 类型&#xff1a;string 缺省值&#xff1a; 输入控件所绑定的变量名。当给输入控件bind了一个变量名后【bindbind_var_name】&#xff0…

大模型时代:用Redis构建百亿级向量数据库方

大模型时代&#xff1a;用Redis构建百亿级向量数据库方案第一章&#xff1a;大模型时代的向量数据库挑战1.1 大模型时代的特征与需求1.2 向量数据库的核心价值1.3 百亿级向量的技术挑战第二章&#xff1a;Redis作为向量数据库的优势2.1 Redis的核心优势2.2 Redis向量搜索模块&a…

jsqlparser(六):TablesNamesFinder 深度解析与 SQL 格式化实现

在数据库应用开发中&#xff0c;SQL语句的解析和处理是一项常见而重要的任务。本文将深入探讨 JSQLParser 中的 TablesNamesFinder 类&#xff0c;分析其核心原理、与 AST 访问接口&#xff08;CCJSqlParserVisitor &#xff09;的关系、使用场景&#xff0c;并通过实际代码示例…

Python训练营打卡Day49-神经网络调参指南

知识点回顾&#xff1a;随机种子内参的初始化神经网络调参指南 参数的分类调参的顺序各部分参数的调整心得 作业&#xff1a;对于day41的简单cnn&#xff0c;看看是否可以借助调参指南进一步提高精度。 随机种子 import torch import torch.nn as nn# 定义简单的线性模型&…

Elasticsearch 常用任务管理命令及实战应用

常用任务管理命令 列出所有任务 curl -X GET "http://<es_host>:<es_port>/_tasks?detailedtrue&pretty" -H Content-Type: application/json获取特定类型的任务 curl -X GET "http://<es_host>:<es_port>/_tasks?actions<act…

Java试题-选择题(26)

Java试题-选择题(26) 题目 下列有关Thread的描述,哪个是正确的 ? A:启动一个线程的方法是:thread. run() B:结束一个线程的通常做法是:thread. stop() C:将一个线程标记成daemon线程,意味着当主线程结束,并且没有其它正在运行的非daemon线程时,该daemon线程也会自…

缓存的原理、引入及设计

开篇寄语&#xff1a;缓存&#xff0c;你真的用对了吗&#xff1f; 我们为什么要学习缓存呢&#xff1f;有必要学习缓存吗&#xff1f; 缓存的使用&#xff0c;是提升系统性能、改善用户体验的唯一解决之道。 其实&#xff0c;作为互联网公司&#xff0c;只要有直接面对用户的业…

单片机如何控制模数转换芯片

一、介绍单片机控制模数转换&#xff08;ADC&#xff09;芯片的核心是通过通信接口发送控制指令&#xff0c;并读取转换后的数字信号&#xff0c;本质是“指令交互数据传输”的协同过程&#xff0c;具体实现需分4步完成&#xff0c;关键在于接口匹配和时序同步。二、核心1. 先明…

【Proteus仿真】开关控制系列仿真——开关控制LED/拨码开关二进制计数/开关和继电器控制灯灭

目录 0案例视频效果展示 0.1例子1&#xff1a;开关控制LED灯亮灭 0.2例子2&#xff1a;数码管显示拨码开关二进制计数(000~255) 0.3例子3&#xff1a;开关和继电器控制灯亮灭 1基础知识补充 1.1 74LS245双总线收发器 1.1.1 引脚及功能 1.1.2应用场景 1.1.3真值表 1.2…

Q1 Top IF 18.7 | 基于泛基因组揭示植物NLR进化

文章DOI: 10.1016/j.chom.2025.07.011 标题&#xff1a;Pangenomic context reveals the extent of intraspecific plant NLR evolution 期刊&#xff1a;Cell Hose & Microbe (https://i-blog.csdnimg.cn/direct/0e31f86b94d348b0a1adb084ec4e49b7.png)(https://i-blog.cs…

技术干货|Prometheus PromQL查询语言之聚合操作内置函数

聚合操作 Prometheus还提供了下列内置的聚合操作符,这些操作符作用域瞬时向量。可以将瞬时表达式返回的样本数据进行聚合,形成一个新的时间序列。 sum (求和) min (最小值) max (最大值) avg (平均值) stddev (标准差) stdvar (标准差异) count (计数) count_values …