logo头像

学如逆水行舟

ArkUI中图片与视频多媒体组件的应用

@toc

Image与Video组件

多媒体数据可以让应用程序的内容更加丰富多彩。在实际开发中,我们经常会需要在应用中展示图片与播放视频。ArkUI中提供了封装好的组件用来支持多媒体内容的渲染。使用起来非常方便。本篇文章将介绍图片组件Image与视频播放器组件Video的应用。

显示图片的Image组件

Image组件用来在页面中显示图片,其用来显示的图片资源可以是本地的也可以是网络的。Image本身支持的图片资源格式也很丰富,能够渲染png、jpg、bmp、gif和heif格式的图片数据。
我们先来看使用Image组件加载本地图片的方法。首先,将要显示的图片文件放入工程的ets文件夹下,如图所示。
image.png
需要注意,本地图片的路径必须在ets文件夹下,我们可以创建更多子文件夹来分类存放图片文件。修改index.ets文件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct Index {
build() {
RelativeContainer() {
Image('images/img-demo.png')
.width(300)
.height(300)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}

Image组件的构造方法可以直接传入本地资源路径,运行上面的代码,显示效果如图所示。
image.png
Image组件加载网络图片也非常简单,只需要将本地的资源地址替换为网络地址即可。ImageAttribute实例中提供了许多配置方法,可以对图片的填充模式、拉伸方式等进行配置,常用的配置方法列举如下:
| 方法 | 参数类型 | 意义 |
|—————|——————-|————————————–|
| fillColor | ResourceColor | 设置填充颜色。 |
| objectFit | ImageFit | 设置图片的缩放类型。 |
| objectRepeat | ImageRepeat | 设置图片平铺时的重复模式。 |
| renderMode | ImageRenderMode | 设置图片的渲染模式,即可以将图片作为模板使用。|
| syncLoad | boolean | 设置图片是否同步进行加载。 |
| onComplete | 函数 | 设置图片加载完成的回调。 |
| onError | 函数 | 设置图片加载失败的回调。 |

播放视频的Video组件

Video组件用来播放视频,其除了拥有基础的视频播放能力外,还提供了播放控制的相关能力,如播放进度控制、音量控制、全屏播放控制等。Video组件默认提供了一套控制UI,包括进度条和一些控制按钮,使用非常简单。
和Image组件类似,Video组件同样支持本地视频和网络视频的播放,要播放本地视频,只需要将视频文件放入ets文件夹下即可,如果要播放网络视频,将视频资源的地址设置为网络URL即可。例如下面的代码即可在页面中播放本地视频:

1
2
3
4
5
6
7
8
9
10
11
RelativeContainer() {
Video({src:"videos/demo.mp4"})
.width(300)
.height(200)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')

需要注意,Video组件不支持直接在DevEco Studio中进行预览,我们可以在真机或模拟器中观察效果。运行上面代码,视频播放组件效果如图3-25所示。可以看到,Video组件自带控制面板,可以进行视频的播放进度控制,暂停与续播以及全屏播放。这些功能无需开发者再做额外的适配,直接可用,例如点击全屏按钮,视频会自动进入全屏播放模式,如图所示。
image.pngimage.png
在构造Video组件实例时,可以传入一个配置对象,下表列出了常用的配置字段:
| 配置属性 | 类型 | 意义 |
|———————|———————————–|———————————————————————-|
| src | string | Resource | 设置视频资源地址。 |
| currentProgressRate | number | string | PlaybackSpeed | 设置播放速率,其中 PlaybackSpeed 枚举定义了一些常用的倍速值,如 2 倍数,0.75 倍速等。 |
| previewUri | string | PixelMap | Resource | 设置视频预览图。 |
| controller | VideoController | 视频控制器,用来自定义控制播放行为。 |

通过controller属性可以配置一个控制器对象,此对象用来手动控制视频播放的行为,如暂停续播等,在实际应用中,Video组件的默认控制UI有时不能满足我们的需求,我们也可以使用自定义的组件来实现视频的播放控制,后面会具体介绍。现在,我们先来看下Video组件常用的实例配置方法:
| 方法 | 参数类型 | 意义 |
|———————–|———————————————|—————————————|
| muted | boolean | 设置是否静音播放。 |
| autoPlay | boolean | 设置是否自动播放。 |
| controls | boolean | 设置是否使用自带的控制栏组件。 |
| loop | boolean | 设置是否循环播放。 |
| objectFit | ImageFit | 设置视频的缩放模式,同 Image 组件的 objectFit 方法。|
| onStart | () => void | 开始播放的回调。 |
| onPause | () => void | 暂停播放的回调。 |
| onFinish | () => void | 播放结束的回调。 |
| onFullscreenChange | (event: {fullscreen:boolean;}) => void | 全屏播放状态变化的回调。 |
| onPrepared | (event: { duration: number;}) => void | 播放准备完成的回调。 |
| onSeeking | (event: { time: number;}) => void | 进度条被操作中的回调。 |
| onSeeked | (event: { time: number;}) => void | 进度条操作完成的回调。 |
| onUpdate | (event: { time: number;}) => void | 播放进度变化的回调。 |
| onError | () => void | 播放失败的回调。 |
| onStop | Callback | 停止播放的回调。 |

可以看到Video组件提供了大量的回调方法,这些回调方法不仅可以帮助开发者实时的获悉视频播放的状态,还能通过它们做许多自定义的逻辑,如通过播放进度的回调来更新自定义的进度条等,

自定义视频控制器

我们知道,Video组件默认集成了许多控制能力,并且在UI展现上,其自带一个控制栏组件,我们也可以自定义视频控制器的UI展现,自主对播放器的播放行为进行控制。在配置Video组件时,我们可以使用controls方法来将默认的控制栏组件隐藏,定义自己的播放控制组件,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@Entry
@Component
struct Index {
// 视频控制器
videoController: VideoController = new VideoController()
// 状态数据
// 当前播放的时间
@State currentTime: number = 0
// 视频总时长
@State totalTime: number = 0

build() {
RelativeContainer() {
Column({space: 10}) {
Video({src:"videos/demo.mp4", controller: this.videoController})
// 隐藏自带的控制栏
.controls(false)
// 监听播放准备完成和更新的回调,设置状态数据
.onPrepared((event) => {
this.totalTime = event.duration
})
.onUpdate((event) => {
this.currentTime = event.time
})
.width(300)
.height(200)
// 自定义播放控制组件
Button("开始播放").onClick(()=>{
this.videoController.start()
})
Button("暂停播放").onClick(()=>{
this.videoController.pause()
})
Button("停止播放").onClick(()=>{
this.videoController.stop()
})
Progress({type: ProgressType.Capsule, value: this.currentTime, total: this.totalTime})
.width(200)
.height(10)
.backgroundColor(Color.White)
.color(Color.Red)
Slider({min:0, max: this.totalTime, value:this.currentTime}).onChange((value: number, mode: SliderChangeMode)=>{
this.videoController.setCurrentTime(value)
})
.width(200)
.height(10)
}.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}

上面代码中,videoController属性是自定义的视频播放控制器,我们将使用其进行播放行为的具体控制,currentTime和totalTime这两个属性我们将其定义为了状态数据,状态数据具有响应性,即状态数据的改变会直接驱动到页面组件的更新。运行代码,效果如图所示。
image.png
上面示例代码只演示了一些常用的视频控制方法,VideoController类中完整提供的功能如下表所示。
| 方法名 | 参数 | 意义 |
|——————-|———-|————————–|
| start | 无 | 开始播放视频。 |
| pause | 无 | 暂停播放视频。 |
| stop | 无 | 停止播放视频。 |
| setCurrentTime | number | 设置从某个时间点开始播放。|
| requestFullscreen | boolean | 请求进入全屏模式。 |
| exitFullscreen | 无 | 退出全屏模式。 |
| reset | 无 | 重置播放器。 |

其中pause和stop都会停止视频的播放,pause只是暂停,再次调用start时会从当前暂停的时间点继续播放,而stop是完全停止,再次调用start时会重新准备视频,并从头播放。