今天我们来深入探讨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的媒体能力仍在不断发展,建议开发者定期查阅官方文档以获取最新功能和最佳实践。