HarmonyOS鸿蒙Next中video组件横屏时的实现方式
HarmonyOS鸿蒙Next中video组件横屏时的实现方式 自定义播放器,横屏全屏播放时不能够像video组件处理的那么优雅。希望获得指导性代码,谢谢。
可以参考下面的代码,主要使用了
- 【媒体服务avplayer】(https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V13/_a_v_player-V13)
- 【XCompontent】(https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V13/ts-basic-components-xcomponent-V13)实现自定义视频播放,如果想实现视频播放横向全屏,可以将XCompontent的宽度和高度设置为100%,再利用
setPreferredOrientation
设置窗口的显示方向属性
代码:
import media from '@ohos.multimedia.media';
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
export class AVPlayerDemo {
private count: number = 0;
surfaceID: string = ''; // surfaceID用于播放画面显示,具体的值需要通过Xcomponent接口获取,相关文档链接见上面Xcomponent创建方法
private isSeek: boolean = true; // 用于区分模式是否支持seek操作
private fileSize: number = -1;
private fd: number = 0;
// 注册avplayer回调函数
setAVPlayerCallback(avPlayer: media.AVPlayer) {
// startRenderFrame首帧渲染回调函数
avPlayer.on('startRenderFrame', () => {
console.info(`AVPlayer start render frame`);
})
// seek操作结果回调函数
avPlayer.on('seekDone', (seekDoneTime: number) => {
console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
})
// error回调监听函数,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
avPlayer.on('error', (err: BusinessError) => {
console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
avPlayer.reset(); // 调用reset重置资源,触发idle状态
})
// 状态机变化回调函数
avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
switch (state) {
case 'idle': // 成功调用reset接口后触发该状态机上报
console.info('AVPlayer state idle called.');
// avPlayer.release(); // 调用release接口销毁实例对象
break;
case 'initialized': // avplayer 设置播放源后触发该状态上报
console.info('AVPlayer state initialized called.');
avPlayer.surfaceId = this.surfaceID; // 设置显示画面,当播放的资源为纯音频时无需设置
avPlayer.prepare();
break;
case 'prepared': // prepare调用成功后上报该状态机
console.info('AVPlayer state prepared called.');
avPlayer.play(); // 调用播放接口开始播放
break;
case 'playing': // play成功调用后触发该状态机上报
console.info('AVPlayer state playing called.');
this.count++;
break;
case 'paused': // pause成功调用后触发该状态机上报
console.info('AVPlayer state paused called.');
// avPlayer.play(); // 再次播放接口开始播放
break
}
});
// 以下demo为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
async avPlayerFdSrcDemo() {
// 创建avPlayer实例对象
let avPlayer: media.AVPlayer = await media.createAVPlayer();
// 创建状态机变化回调函数
this.setAVPlayerCallback(avPlayer);
// 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址
// 返回类型为{fd,offset,length},fd为HAP包fd地址,offset为媒体资源偏移量,length为播放长度
let context = getContext(this) as common.UIAbilityContext;
let fileDescriptor = await context.resourceManager.getRawFd('videoTest.mp4');
let avFileDescriptor: media.AVFileDescriptor =
{ fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };
this.isSeek = true; // 支持seek操作
// 为fdSrc赋值触发initialized状态机上报
avPlayer.fdSrc = avFileDescriptor;
// await avPlayer.play();
}
}
view页面:
import { AVPlayerDemo } from '../model/AVPlayerDemo';
import window from '@ohos.window'
// xxx.ets
@Entry
@Component
struct PreviewArea {
private surfaceId: string = ''
private xComponentContext: Record<string, () => void> = {}
xComponentController: XComponentController = new XComponentController()
XComWidth: string = '100%';
XComHeight: string = '400';
build() {
Stack() {
XComponent({
id: 'xcomponent',
type: XComponentType.SURFACE,
controller: this.xComponentController
})
.onLoad(() => {
this.xComponentController.setXComponentSurfaceSize({ surfaceWidth: 1920, surfaceHeight: 1080 })
this.surfaceId = this.xComponentController.getXComponentSurfaceId()
this.xComponentContext = this.xComponentController.getXComponentContext() as Record<string, () => void>
const AVPlayer = new AVPlayerDemo();
AVPlayer.surfaceID = this.surfaceId;
AVPlayer.avPlayerFdSrcDemo();
})
.width(this.XComWidth)
.height(this.XComHeight)
Column() {
Button('横屏播放').onClick((event: ClickEvent) => {
this.XComHeight = '100%';
window.getLastWindow(getContext(), (err, windowclass) => {
windowclass.setPreferredOrientation(window.Orientation.LANDSCAPE)
});
})
Button('竖屏播放').onClick((event: ClickEvent) => {
this.XComHeight = '400';
window.getLastWindow(getContext(), (err, windowclass) => {
windowclass.setPreferredOrientation(window.Orientation.PORTRAIT)
});
})
}
}
}
}
更多关于HarmonyOS鸿蒙Next中video组件横屏时的实现方式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,video
组件横屏时的实现方式主要依赖于系统的屏幕旋转功能和布局管理。当设备旋转时,系统会自动调整video
组件的显示方式以适应横屏模式。
具体实现步骤如下:
-
设置屏幕旋转支持:在
config.json
文件中,确保orientation
属性设置为landscape
或sensorLandscape
,以允许屏幕旋转到横屏模式。 -
布局调整:在UI布局文件中,使用
DirectionalLayout
或DependentLayout
等布局管理器,确保video
组件能够根据屏幕方向自动调整大小和位置。 -
全屏显示:在横屏模式下,通常需要将
video
组件设置为全屏显示。可以通过设置video
组件的width
和height
属性为match_parent
来实现。 -
事件处理:监听屏幕旋转事件,在屏幕旋转时动态调整
video
组件的显示状态。可以使用onConfigurationChanged
方法来处理屏幕方向变化。 -
媒体控制:在横屏模式下,确保播放控制按钮(如播放、暂停、音量控制等)能够正常显示和操作。可以通过调整布局或使用
MediaController
组件来实现。
通过以上步骤,可以在HarmonyOS鸿蒙Next中实现video
组件在横屏模式下的正常显示和操作。
在HarmonyOS鸿蒙Next中,实现video
组件横屏播放的方式主要依赖于屏幕方向的设置。可以通过以下步骤实现:
- 设置屏幕方向:在
config.json
中配置orientation
为landscape
,强制应用以横屏模式运行。 - 使用
Video
组件:在js
文件中引入Video
组件,并在struct
中定义Video
的宽高,确保其适应横屏布局。 - 动态调整布局:根据屏幕方向动态调整
Video
组件的宽高,确保视频播放时始终填充屏幕。
示例代码:
@Entry
@Component
struct VideoExample {
private videoController: VideoController = new VideoController();
build() {
Column() {
Video({
src: 'https://example.com/sample.mp4',
controller: this.videoController
})
.width('100%')
.height('100%')
}.width('100%').height('100%')
}
}