回复
09-自然壁纸实战教程-视频下载 原创 精华
万少skr
发布于 2025-7-8 15:09
浏览
0收藏
09-自然壁纸实战教程-视频下载
前言
视频下载页面的功能主要提供了视频的播放,和下载,因为下载比较耗时,所以这里还用到了多线程taskpoll来实现。

获取和构造播放视频数据
@Local videoPlayerViewModel: VideoPlayerViewModel = new VideoPlayerViewModel()
aboutToAppear() {
// 获取传递过来的视频数据
const param = NavigationUtils.getInstance().getParamByIndex() as VideoData
if (param) {
this.videoPlayerViewModel.videoData = param
// 设置视频URL(优先使用小尺寸视频以提高流畅度)
this.videoPlayerViewModel.setUrl(param)
} else {
promptAction.showToast({
message: '未获取到视频数据',
duration: 2000
})
}
}
构造视频播放结构

这里用到的视频的属性和事件比较多,需要单独讲解一下。
- 视频组件初始化:
- 使用
Video组件,绑定视频资源src、视频控制器controller和预览图片previewUri。 - 设置视频播放器的宽度和高度,根据是否全屏显示调整高度。
- 设置视频的适应模式为
contain,确保视频内容完整显示。 - 启用自动播放和系统默认控件。
- 使用
- 事件监听:
onStart:当视频开始播放时,将isPlaying状态设置为true。onPause:当视频暂停时,将isPlaying状态设置为false。onFinish:当视频播放结束时,将isPlaying状态设置为false,并将当前时间currentTime重置为0。onUpdate:实时更新当前播放时间currentTime。onPrepared:当视频准备就绪后,立即开始播放,并将isPlaying状态设置为true。
- 快捷键和点击事件:
- enableAnalyzer:设置组件支持AI分析,当前支持主体识别、文字识别和对象查找等功能,支持attributeModifier动态设置属性方法。
- enableShortcutKey:启用快捷键功能,允许用户通过键盘快捷键控制视频播放。
- 点击视频区域时,如果视频正在播放,则暂停播放;如果视频未播放,则开始播放。
Video({
src: this.videoPlayerViewModel.videoUrl,
controller: this.videoPlayerViewModel.controller,
previewUri: this.videoPlayerViewModel.videoData?.videos?.medium?.thumbnail
})
.width('100%')
.height(this.videoPlayerViewModel.isFullScreen ? '100%' : '240vp')
.objectFit(ImageFit.Contain)
.autoPlay(true)
.controls(true) // 使用系统默认控件
.onStart(() => {
this.videoPlayerViewModel.isPlaying = true
})
.onPause(() => {
this.videoPlayerViewModel.isPlaying = false
})
.onFinish(() => {
this.videoPlayerViewModel.isPlaying = false
this.videoPlayerViewModel.currentTime = 0
})
.onUpdate((event) => {
this.videoPlayerViewModel.currentTime = event.time
})
.onPrepared((event) => {
this.videoPlayerViewModel.duration = event.duration
// 视频准备好后立即开始播放
this.videoPlayerViewModel.controller.start()
this.videoPlayerViewModel.isPlaying = true
})
.enableAnalyzer(true)
.enableShortcutKey(true)
.onClick(() => {
if (this.videoPlayerViewModel.isPlaying) {
this.videoPlayerViewModel.controller.pause()
} else {
this.videoPlayerViewModel.controller.start()
}
})
视频信息
视频信息结构就是常规的布局,这里就不体现核心代码了。

下载视频

下载视频是这个项目中比较有意思的功能,因为是使用了多线程+下载的+保存到相册的能力,这里的主要逻辑是
下载视频的主要逻辑
主要逻辑:
- 检查下载状态:首先检查是否已有下载任务正在进行中,如果有则提示用户已有下载任务正在进行中并返回。
- 获取上下文和路径:获取应用的上下文对象和缓存目录路径,用于保存下载的视频文件。
- 配置下载任务:设置下载任务的配置信息,包括下载动作、视频URL、保存路径、进度条显示、覆盖文件、网络类型和任务标题等。
- 创建下载任务:使用
request.agent.create方法创建下载任务,并处理创建成功或失败的情况。 - 开始下载任务:在下载任务创建成功后,调用
task.start方法开始下载,并处理下载开始、进度更新、下载完成和下载失败的情况。 - 更新进度:在下载过程中,通过
task.on('progress', ...)事件更新下载进度。 - 下载完成后的操作:在下载完成后,调用
task.on('completed', ...)事件,将视频文件保存到相册,并更新下载状态和进度。 - 错误处理:在创建下载任务或下载过程中出现错误时,通过
task.on('failed', ...)事件和catch块处理错误,并更新下载状态和进度。 - 重置进度条:在下载完成后,设置一个延迟后重置下载进度的操作,以确保用户界面能够正确反映下载状态。
// 下载视频
downFile() {
if (this.isDownloading) {
promptAction.showToast({ message: '已有下载任务进行中' });
return;
}
//上下文对象
let context = getContext(this) as common.UIAbilityContext
let filesDir = context.cacheDir
//保存到的沙箱路径
let filePath = `${filesDir}/${Date.now()}.mp4`;
this.filePath = filePath
//下载任务的配置信息
let config: request.agent.Config = {
action: request.agent.Action.DOWNLOAD,
url: this.videoUrl,
saveas: filePath,
gauge: true,
overwrite: true,
network: request.agent.Network.WIFI,
title: this.videoData?.tags.split(',')[0] || 'video_download' // 添加下载任务标题
}
//创建下载任务
request.agent.create(context, config)
.then(async (task: request.agent.Task) => {
this.isDownloading = true; // 开始下载
this.downloadProgress = 0; // 重置进度
//创建成功之后,开始下载任务
task.start((err: BusinessError) => {
if (err) {
request.agent.remove(task.tid)
promptAction.showToast({ message: '下载失败' })
this.isDownloading = false; // 下载失败
this.downloadProgress = 0;
} else {
promptAction.showToast({ message: '开始下载...' })
}
})
task.on('progress', (progressInfo: request.agent.Progress) => { // Explicitly type progressInfo
if (progressInfo.sizes[0] > 0) {
this.downloadProgress =
Math.floor((progressInfo.sizes[0] / progressInfo.sizes[0]) * 100);
}
})
task.on('completed', async () => {
//下载完成--->保存到相册
this.isDownloading = false; // 下载完成
this.downloadProgress = 100; // 确保进度为100%
promptAction.showToast({ message: '下载完成,正在保存到相册...' });
this.save(filePath)
// 可以在这里稍作延迟后重置进度条,或者在保存成功后
setTimeout(() => {
this.downloadProgress = 0;
}, 2000);
})
task.on('failed', () => {
promptAction.showToast({ message: '下载任务失败' });
this.isDownloading = false;
this.downloadProgress = 0;
})
})
.catch((err: BusinessError) => {
promptAction.showToast({ message: `创建下载任务失败: ${err.message}` });
this.isDownloading = false;
this.downloadProgress = 0;
})
}
保存到相册
该功能在之前的教程中已经出现过了,
- 获取当前应用的上下文(
context)。 - 创建一个
photoAccessHelper对象,用于访问和管理设备的照片和视频库。 - 定义一个包含源文件URI的数组
srcFileUris,这里只包含一个URI,即要保存的视频文件。 - 定义一个
photoCreationConfigs数组,其中包含了保存视频时的配置信息,如文件名后缀、照片类型(这里是视频)、标题和子类型等。 - 调用
showAssetsCreationDialog方法,弹出授权对话框,让用户选择保存视频的目标位置,并返回目标URI。 - 使用
fileIo.open方法以读写模式打开源文件和目标文件。 - 使用
fileIo.copyFile方法将源文件的内容复制到目标文件中。 - 关闭源文件和目标文件。
- 如果保存成功,显示成功提示信息;如果失败,显示失败提示信息。
// 保存到相册
async save(srcFileUri: string) {
let context = getContext(this)
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
try {
let srcFileUris: Array<string> = [
srcFileUri
];
// 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选
let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
{
title: `${Date.now()}`, // 可选
fileNameExtension: 'mp4',
photoType: photoAccessHelper.PhotoType.VIDEO,
subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
}
];
// 基于弹窗授权的方式获取媒体库的目标uri
let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
// 将来源于应用沙箱的内容写入媒体库的目标uri
let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY);
let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY);
await fileIo.copyFile(srcFile.fd, desFile.fd);
fileIo.closeSync(srcFile);
fileIo.closeSync(desFile);
promptAction.showToast({ message: '保存成功' })
} catch (error) {
promptAction.showToast({ message: '保存失败' })
}
}
如何获取资料
获取资料的途径,可以关注我们 官网的公众号 青蓝逐码 ,输入 项目名称 《自然壁纸》 即可获得以上资料。
关于我们
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
赞
收藏
回复
相关推荐




















