18.ArkUI Video的介绍和使用
ArkUI Video 组件详解与使用指南
Video 是 ArkUI 中用于播放视频的多媒体组件,支持本地和网络视频资源的播放控制。以下是 Video 组件的详细介绍和使用方法。
基本介绍
Video 组件特点:
- 支持本地和网络视频播放
- 提供播放控制、全屏、音量调节等功能
- 支持自定义控制栏
- 可监听播放状态和进度变化
- 支持视频封面和加载状态显示
基本使用
1. 基础视频播放
@Entry
@Component
struct BasicVideoExample {private controller: VideoController = new VideoController()build() {Column() {Video({src: 'https://example.com/sample.mp4', // 视频地址previewUri: $r('app.media.video_cover'), // 封面图controller: this.controller // 控制器}).width('100%').height(300)// 自定义控制按钮Row({ space: 20 }) {Button('播放').onClick(() => {this.controller.start()})Button('暂停').onClick(() => {this.controller.pause()})}.margin(10)}}
}
2. 全屏视频播放
@Entry
@Component
struct FullscreenVideoExample {private controller: VideoController = new VideoController()@State isFullscreen: boolean = falsebuild() {Stack() {Video({src: 'common/sample.mp4', // 本地视频controller: this.controller}).width(this.isFullscreen ? '100%' : '80%').height(this.isFullscreen ? '100%' : 200).onFullscreenChange((isFullscreen) => {this.isFullscreen = isFullscreen})if (!this.isFullscreen) {Button('全屏').onClick(() => {this.controller.requestFullscreen(true)}).position({ x: '50%', y: '50%' })}}.width('100%').height('100%')}
}
核心功能
1. 视频控制方法
private controller: VideoController = new VideoController()// 播放
this.controller.start()// 暂停
this.controller.pause()// 停止
this.controller.stop()// 跳转到指定位置(毫秒)
this.controller.seek(5000)// 全屏切换
this.controller.requestFullscreen(true)
2. 视频事件监听
Video({src: 'https://example.com/video.mp4',controller: this.controller
})
.onPrepared(() => {console.log('视频准备完成')
})
.onStart(() => {console.log('开始播放')
})
.onPause(() => {console.log('暂停播放')
})
.onFinish(() => {console.log('播放完成')
})
.onError(() => {console.log('播放出错')
})
.onSeeked((timeMs: number) => {console.log('跳转到:', timeMs)
})
.onUpdate((event: { time: number, duration: number }) => {console.log('当前进度:', event.time, '总时长:', event.duration)
})
3. 视频属性控制
Video({ /* 参数 */ })
.muted(false) // 是否静音
.autoPlay(false) // 是否自动播放
.loop(false) // 是否循环播放
.controls(true) // 是否显示默认控制栏
.objectFit(ImageFit.Contain) // 视频填充模式
高级功能
1. 自定义视频控制栏
@Entry
@Component
struct CustomControlsVideo {private controller: VideoController = new VideoController()@State currentTime: number = 0@State duration: number = 0@State isPlaying: boolean = falsebuild() {Column() {Video({src: 'common/sample.mp4',controller: this.controller}).controls(false) // 禁用默认控制栏.autoPlay(false).onUpdate((event: { time: number, duration: number }) => {this.currentTime = event.timethis.duration = event.duration}).onStart(() => { this.isPlaying = true }).onPause(() => { this.isPlaying = false }).width('100%').height(300)// 自定义控制栏Column() {// 进度条Row() {Text(this.formatTime(this.currentTime))Slider({value: this.currentTime,min: 0,max: this.duration}).onChange((value: number) => {this.controller.seek(value)}).layoutWeight(1)Text(this.formatTime(this.duration))}// 控制按钮Row({ space: 20 }) {Button(this.isPlaying ? '暂停' : '播放').onClick(() => {this.isPlaying ? this.controller.pause() : this.controller.start()})Button('静音').onClick(() => {this.controller.mute(!this.controller.isMuted())})Button('全屏').onClick(() => {this.controller.requestFullscreen(true)})}.margin({ top: 10 }).justifyContent(FlexAlign.Center)}.padding(10).backgroundColor('#f5f5f5')}}formatTime(ms: number): string {const seconds = Math.floor(ms / 1000)const mins = Math.floor(seconds / 60)const secs = seconds % 60return `${mins}:${secs < 10 ? '0' : ''}${secs}`}
}
2. 视频列表播放
@Entry
@Component
struct VideoListPlayer {private controller: VideoController = new VideoController()@State currentVideo: number = 0private videos = [{ title: '视频1', url: 'https://example.com/video1.mp4' },{ title: '视频2', url: 'https://example.com/video2.mp4' }]build() {Column() {// 视频播放器Video({src: this.videos[this.currentVideo].url,controller: this.controller}).onFinish(() => {this.playNext()}).width('100%').height(300)// 视频标题Text(this.videos[this.currentVideo].title).fontSize(18).margin(10)// 视频列表List() {ForEach(this.videos, (video, index) => {ListItem() {Row() {Text(video.title)if (index === this.currentVideo) {Text('正在播放').fontColor('#FF0000').margin({ left: 10 })}}.onClick(() => {if (index !== this.currentVideo) {this.currentVideo = indexthis.controller.start()}})}})}.layoutWeight(1)}}playNext() {if (this.currentVideo < this.videos.length - 1) {this.currentVideo++this.controller.start()}}
}
3. 视频缓存与下载
@Entry
@Component
struct CachedVideoPlayer {private controller: VideoController = new VideoController()@State downloadProgress: number = 0@State isDownloaded: boolean = falsebuild() {Column() {if (this.isDownloaded) {Video({src: 'file:///data/videos/cached.mp4', // 本地缓存路径controller: this.controller}).width('100%').height(300)} else {Column() {Text('视频未缓存,请先下载')Progress({ value: this.downloadProgress, total: 100 }).width('80%').margin(10)Button('下载视频').onClick(() => {this.simulateDownload()})}.height(300).justifyContent(FlexAlign.Center)}}}simulateDownload() {const interval = setInterval(() => {if (this.downloadProgress >= 100) {clearInterval(interval)this.isDownloaded = true} else {this.downloadProgress += 10}}, 500)}
}
最佳实践
-
网络视频优化:
- 使用合适的视频格式和压缩率
- 实现缓冲进度显示
- 提供清晰度切换选项
-
用户体验:
- 添加视频封面提升观感
- 重要视频提供下载功能
- 横竖屏适配
-
性能考虑:
- 列表中的视频使用缩略图预加载
- 离开页面时暂停播放
- 避免同时加载多个视频
-
无障碍设计:
- 为控制按钮添加accessibilityLabel
- 确保有文字替代说明
实际应用示例
1. 短视频播放器
@Entry
@Component
struct ShortVideoPlayer {private controller: VideoController = new VideoController()@State currentIndex: number = 0@State isPlaying: boolean = falseprivate videos = [{ url: 'https://example.com/short1.mp4', likes: 1243 },{ url: 'https://example.com/short2.mp4', likes: 5678 }]build() {Stack() {// 视频播放Video({src: this.videos[this.currentIndex].url,controller: this.controller}).controls(false).loop(true).onStart(() => { this.isPlaying = true }).onPause(() => { this.isPlaying = false }).width('100%').height('100%')// 右侧互动按钮Column() {Column() {Image($r('app.media.ic_like')).width(30).height(30)Text(this.videos[this.currentIndex].likes.toString()).fontSize(12)}.onClick(() => {// 点赞逻辑})// 更多互动按钮...}.position({ x: '85%', y: '50%' })// 底部控制栏Row() {Button(this.isPlaying ? '暂停' : '播放').onClick(() => {this.isPlaying ? this.controller.pause() : this.controller.start()})// 更多控制按钮...}.position({ x: '50%', y: '90%' })}.height('100%').gesture(// 添加滑动切换手势SwipeGesture({ direction: SwipeDirection.Vertical }).onActionEnd(() => {this.currentIndex = (this.currentIndex + 1) % this.videos.lengththis.controller.start()}))}
}
2. 教育课程播放器
@Entry
@Component
struct CoursePlayer {private controller: VideoController = new VideoController()@State currentTime: number = 0@State duration: number = 0@State playbackRate: number = 1.0build() {Column() {// 视频区域Video({src: 'https://edu.example.com/lesson1.mp4',controller: this.controller}).controls(false).onUpdate((event) => {this.currentTime = event.timethis.duration = event.duration}).width('100%').height(250)// 课程标题和进度Text('第一章: ArkUI基础').fontSize(18).margin(10)Text(`进度: ${Math.floor(this.currentTime/1000)}/${Math.floor(this.duration/1000)}秒`).fontSize(14)// 高级控制栏Row({ space: 10 }) {Button(this.playbackRate === 1.0 ? '1x' : '正常').onClick(() => {this.playbackRate = this.playbackRate === 1.0 ? 1.5 : 1.0this.controller.setSpeed(this.playbackRate)})Slider({value: this.currentTime,min: 0,max: this.duration}).onChange((value) => {this.controller.seek(value)}).layoutWeight(1)Button('章节').onClick(() => {// 显示章节列表})}.padding(10)// 课程目录Expanded() {List() {ListItem() {Text('1.1 ArkUI介绍')}ListItem() {Text('1.2 基础组件')}// 更多课程项...}}}}
}
通过合理使用 Video 组件,可以实现各种视频播放场景,从简单的播放器到复杂的交互式视频应用。根据具体需求选择合适的控制方式和功能组合,以提供最佳的视频观看体验。