今天我们来深入探讨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 }; // 设置surfaceId this.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
-
Video组件提供了开箱即用的视频播放功能,适合大多数基本场景
-
AVPlayer与XComponent组合提供了更高级的自定义控制能力
-
全屏切换可以通过Video组件内置功能或自定义实现
-
小窗口播放增强了用户体验,允许后台播放
-
媒体查询实现了响应式布局,适应不同设备特性
-
性能优化技术如LazyForEach和@Reusable确保了流畅体验
鸿蒙Next的媒体能力仍在不断发展,建议开发者定期查阅官方文档以获取最新功能和最佳实践。