鸿蒙进行视频上传,使用 request.uploadFile方法

一.拉起选择器进行视频选择,并且创建文件名称

async getPictureFromAlbum() {// 拉起相册,选择图片let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE;PhotoSelectOptions.maxSelectNumber = 1;let photoPicker = new photoAccessHelper.PhotoViewPicker();// let photoSelectResult: photoAccessHelper.PhotoSelectResult = awaitphotoPicker.select(PhotoSelectOptions).then((result) => {this.albumPath = result.photoUris[0];const fileName = Date.now() + '.' + 'mp4'const copyFilePath = this.context.cacheDir + '/' + fileNameconst file = fs.openSync(this.albumPath, fs.OpenMode.READ_ONLY)fs.copyFileSync(file.fd, copyFilePath)LoadingDialog.showLoading('正在上传视频...')this.uploadVideo(fileName)})// 读取图片为buffer// const file = fs.openSync(this.albumPath, fs.OpenMode.READ_ONLY);// this.photoSize = fs.statSync(file.fd).size;// console.info('Photo Size: ' + this.photoSize);// let buffer = new ArrayBuffer(this.photoSize);// fs.readSync(file.fd, buffer);// fs.closeSync(file);//// // 解码成PixelMap// const imageSource = image.createImageSource(buffer);// console.log('imageSource: ' + JSON.stringify(imageSource));// this.pixel = await imageSource.createPixelMap({});}

二.进行文件上传使用request.uploadFile方法

  • 需要注意的几点事项

  1. files数组里的name字段为后端所需文件key
  2.  监听headerReceive方法可以使你拿到后端接口返回的请求状态,在headers的body里面,只能通过这种方法才能拿到
  3. 如果不需要通过后端去判断状态,可以监听complete,返回code为0的话就使成功状态
  4. 监听progress为当前上传进度
  async uploadVideo(fileName: string) {let uploadTask: request.UploadTasklet uploadConfig: request.UploadConfig = {url: '你的url',header: { 'Accept': '*/*', 'Content-Type': 'multipart/form-data' },method: "POST",//name 为后端需要的字段名,为key  type不指定的话截取文件后缀files: [{filename: 'file',name: 'video',uri: `internal://cache/${fileName}`,type: ""}],// data为其他所需参数data: [],};try {request.uploadFile(getContext(), uploadConfig).then((data: request.UploadTask) => {uploadTask = data;uploadTask.on("progress", (size, tot) => {console.log('123212' + JSON.stringify(`上传进度:${size}/${tot}\r\n`))})// 监听这个为  后端所返回的请求信息uploadTask.on('headerReceive', (headers: object) => {let bodyStr: string = headers["body"]let body: ESObject = JSON.parse(bodyStr)console.info("upOnHeader headers:" + JSON.stringify(body));this.resultPath = body.video_urlLoadingDialog.hide()});// uploadTask.on('complete', (taskStates: Array<request.TaskState>) => {//   for (let i = 0; i < taskStates.length; i++) {//     console.info("upOnComplete taskState:" + JSON.stringify(taskStates[i]));//   }// });// uploadTask.on('fail', (taskStates: Array<request.TaskState>) => {//   for (let i = 0; i < taskStates.length; i++) {//     console.info("upOnFail taskState:" + JSON.stringify(taskStates[i]));//   }// });}).catch((err: BusinessError) => {console.error(`Failed to request the upload. Code: ${err.code}, message: ${err.message}`);});} catch (err) {console.error(`Failed to request the upload. err: ${JSON.stringify(err)}`);}}

三.完整代码

这里加了个loading状态,不需要可以自行删除

import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { image } from '@kit.ImageKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { promptAction } from '@kit.ArkUI';
import LoadingDialog from '@lyb/loading-dialog';
import { BusinessError, request } from '@kit.BasicServicesKit';interface DurationObject {duration: number;
}@Entry
@Component
struct Index {@State getAlbum: string = '显示相册中的图片';@State pixel: image.PixelMap | undefined = undefined;@State albumPath: string = '';@State resultPath: string = '';@State photoSize: number = 0;@State result: boolean = false;private context: Context = getContext(this);@State isLoading: Boolean = false;controller: VideoController = new VideoController()async uploadVideo(fileName: string) {let uploadTask: request.UploadTasklet uploadConfig: request.UploadConfig = {url: '',header: { 'Accept': '*/*', 'Content-Type': 'multipart/form-data' },method: "POST",//name 为后端需要的字段名,为key  type不指定的话截取文件后缀files: [{filename: 'file',name: 'video',uri: `internal://cache/${fileName}`,type: ""}],// data为其他所需参数data: [],};try {request.uploadFile(getContext(), uploadConfig).then((data: request.UploadTask) => {uploadTask = data;uploadTask.on("progress", (size, tot) => {console.log('123212' + JSON.stringify(`上传进度:${size}/${tot}\r\n`))})// 监听这个为  后端所返回的请求信息uploadTask.on('headerReceive', (headers: object) => {let bodyStr: string = headers["body"]let body: ESObject = JSON.parse(bodyStr)console.info("upOnHeader headers:" + JSON.stringify(body));this.resultPath = body.video_urlLoadingDialog.hide()});// uploadTask.on('complete', (taskStates: Array<request.TaskState>) => {//   for (let i = 0; i < taskStates.length; i++) {//     console.info("upOnComplete taskState:" + JSON.stringify(taskStates[i]));//   }// });uploadTask.on('fail', (taskStates: Array<request.TaskState>) => {for (let i = 0; i < taskStates.length; i++) {console.info("upOnFail taskState:" + JSON.stringify(taskStates[i]));}});}).catch((err: BusinessError) => {console.error(`Failed to request the upload. Code: ${err.code}, message: ${err.message}`);});} catch (err) {console.error(`Failed to request the upload. err: ${JSON.stringify(err)}`);}}async getPictureFromAlbum() {// 拉起相册,选择图片let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE;PhotoSelectOptions.maxSelectNumber = 1;let photoPicker = new photoAccessHelper.PhotoViewPicker();// let photoSelectResult: photoAccessHelper.PhotoSelectResult = awaitphotoPicker.select(PhotoSelectOptions).then((result) => {this.albumPath = result.photoUris[0];const fileName = Date.now() + '.' + 'mp4'const copyFilePath = this.context.cacheDir + '/' + fileNameconst file = fs.openSync(this.albumPath, fs.OpenMode.READ_ONLY)fs.copyFileSync(file.fd, copyFilePath)LoadingDialog.showLoading('正在上传视频...')this.uploadVideo(fileName)})// this.albumPath = photoSelectResult.photoUris[0];// 读取图片为buffer// const file = fs.openSync(this.albumPath, fs.OpenMode.READ_ONLY);// this.photoSize = fs.statSync(file.fd).size;// console.info('Photo Size: ' + this.photoSize);// let buffer = new ArrayBuffer(this.photoSize);// fs.readSync(file.fd, buffer);// fs.closeSync(file);//// // 解码成PixelMap// const imageSource = image.createImageSource(buffer);// console.log('imageSource: ' + JSON.stringify(imageSource));// this.pixel = await imageSource.createPixelMap({});}build() {Column() {Column() {if (this.albumPath) {Row() {Text('需上传视频:').fontSize(20).fontWeight(500).decoration({type: TextDecorationType.Underline,color: Color.Black,style: TextDecorationStyle.SOLID})}.width('100%').margin({ bottom: 10 })Video({ src: this.albumPath }).borderRadius(5).width('100%').height(300)}}.padding(10).borderRadius(10).backgroundColor('white').width('100%')if (this.result && this.resultPath) {Column() {Row() {Text('已返回结果:').fontSize(20).fontWeight(500).decoration({type: TextDecorationType.Underline,color: Color.Black,style: TextDecorationStyle.SOLID})}.width('100%').margin({ bottom: 10 })Video({ src: this.resultPath, controller: this.controller }).width('100%').height(300).borderRadius(10)// .autoPlay(true)// 设置自动播放.loop(true).controls(true).onPrepared((e?: DurationObject) => {if (e != undefined) {LoadingDialog.hide()console.info('onPrepared is ' + e.duration)}}).onStart(() => {setTimeout(() => { // 使用settimeout设置延迟跳过黑屏阶段this.controller.setCurrentTime(1, SeekMode.PreviousKeyframe)}, 150)})}.margin({ top: 15 }).padding(10).borderRadius(10).backgroundColor('white')}Row() {Button('选择文件', { type: ButtonType.Normal, stateEffect: true }).borderRadius(8).backgroundColor(0x317aff).width(90).onClick(() => {this.getPictureFromAlbum();}).margin({ right: 20 })Button('显示视频', { type: ButtonType.Normal, stateEffect: true }).borderRadius(8).backgroundColor(0x317aff).width(90).onClick(() => {if (this.resultPath) {this.result = true;LoadingDialog.showLoading('正在加载视频...')} else {promptAction.showToast({message: '请先选择视频文件!',duration: 2000});}})}.position({ x: 70, y: 730 })}.padding(20).backgroundColor('#e8eaed').backgroundImage($r('app.media.back')).backgroundImageSize(ImageSize.FILL).height('100%').expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41942.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyQt6实例_批量下载pdf工具_exe使用方法

目录 前置&#xff1a; 工具使用方法&#xff1a; step one 获取工具 step two 安装 step three 使用 step four 卸载 链接 前置&#xff1a; 1 批量下载pdf工具是基于博文 python_巨潮年报pdf下载-CSDN博客 &#xff0c;将这个需求创建成界面应用&#xff0c;达到可…

matlab 模拟 闪烁体探测器全能峰

clc;clear;close all %% 参数设置 num_events 1e5; % 模拟事件数 E 662e3; % γ射线能量&#xff08;eV&#xff09; Y 38000; % 光产额&#xff08;photon/MeV&#xff0c;NaI(Tl)&#xff09; eta 0.2; % 量子效率 G 1e6; …

启扬RK3568开发板已成功适配OpenHarmony4.0版本

启扬智能IAC-RK3568-Kit开发板支持Debian、Android等常见开源操作系统&#xff0c;目前已完成OpenHarmony4.0开源国产操作系统的适配工作&#xff0c;满足国产化开源操作系统客户的需求。 启扬智能IAC-RK3568-Kit开发板基于瑞芯微RK3568处理器设计&#xff0c;主频最高可达2.0G…

蓝桥与力扣刷题(蓝桥 山)

题目&#xff1a;这天小明正在学数数。 他突然发现有些止整数的形状像一挫 “山”, 比㓚 123565321、145541123565321、145541, 它 们左右对称 (回文) 且数位上的数字先单调不减, 后单调不增。 小朋数了衣久也没有数完, 他惒让你告诉他在区间 [2022,2022222022] 中有 多少个数…

WinDbg. From A to Z! 笔记(一)

原文链接: WinDbg. From A to Z! 文章目录 为什么使用WinDbg为什么通过本书学习底层原理简述Windows的调试工具一览dbghelp.dll -- Windows 调试助手dbgeng.dll -- 调试引擎接口 调试符号 (Debug Symbols)有哪些调试信息生成调试信息匹配调试信息调用堆栈 侵入式与非侵入式异常…

Axure RP 9.0教程: 基于动态面板的元件跟随来实现【音量滑块】

文章目录 引言I 音量滑块的实现步骤添加底层边框添加覆盖层基于覆盖层创建动态面板添加滑块按钮设置滑块拖动效果引言 音量滑块在播放器类APP应用场景相对较广,例如调节视频的亮度、声音等等。 I 音量滑块的实现步骤 添加底层边框 在画布中添加一个矩形框:500 x 32,圆…

Eclipse IDE for ModusToolbox™ 3.4环境通过JLINK调试CYT4BB

使用JLINK在Eclipse IDE for ModusToolbox™ 3.4环境下调试CYT4BB&#xff0c;配置是难点。总结一下在IDE中配置JLINK调试中遇到的坑&#xff0c;以及如何一步一步解决遇到的问题。 1. JFLASH能够正常下载程序 首先要保证通过JFLASH(我使用的J-Flash V7.88c版本)能够通过JLIN…

黑马点评项目

遇到问题&#xff1a; 登录流程 session->JWT->SpringSession->tokenRedis &#xff08;不需要改进为SpringSession&#xff0c;token更广泛&#xff0c;移动端或者前后端分离都可以用&#xff09; SpringSession配置为redis模式后&#xff0c;redis相当于分布式se…

wgcloud怎么实现服务器或者主机的远程关机、重启操作吗

可以&#xff0c;WGCLOUD的指令下发模块可以实现远程关机和重启 使用指令下发模块&#xff0c;重启主机&#xff0c;远程关机&#xff0c;重启agent程序- WGCLOUD

深度解析Spring Boot可执行JAR的构建与启动机制

一、Spring Boot应用打包架构演进 1.1 传统JAR包与Fat JAR对比 传统Java应用的JAR包在依赖管理上存在明显短板&#xff0c;依赖项需要单独配置classpath。Spring Boot创新的Fat JAR&#xff08;又称Uber JAR&#xff09;解决方案通过spring-boot-maven-plugin插件实现了"…

deepseek(2)——deepseek 关键技术

1 Multi-Head Latent Attention (MLA) MLA的核心在于通过低秩联合压缩来减少注意力键&#xff08;keys&#xff09;和值&#xff08;values&#xff09;在推理过程中的缓存&#xff0c;从而提高推理效率&#xff1a; c t K V W D K V h t c_t^{KV} W^{DKV}h_t ctKV​WDKVht​…

突破反爬困境:SDK架构设计,为什么选择独立服务模式(四)

声明 本文所讨论的内容及技术均纯属学术交流与技术研究目的&#xff0c;旨在探讨和总结互联网数据流动、前后端技术架构及安全防御中的技术演进。文中提及的各类技术手段和策略均仅供技术人员在合法与合规的前提下进行研究、学习与防御测试之用。 作者不支持亦不鼓励任何未经授…

自然语言处理,能否成为人工智能与人类语言完美交互的答案?

自然语言处理&#xff08;NLP&#xff09;作为人工智能关键领域&#xff0c;正深刻改变着人机交互模式。其发展历经从早期基于规则与统计&#xff0c;到如今借深度学习实现飞跃的历程。NLP 涵盖分词、词性标注、语义理解等多元基础任务&#xff0c;运用传统机器学习与前沿深度学…

蓝桥杯备考:八皇后问题

八皇后的意思是&#xff0c;每行只能有一个&#xff0c;每个对角线只能有一个&#xff0c;每一列只能有一个&#xff0c;我们可以dfs遍历每种情况&#xff0c;每行填一个&#xff0c;通过对角线和列的限制来进行剪枝 话不多说&#xff0c;我们来实现一下代码 #include <ios…

HDR(HDR10/ HLG),SDR

以下是HDR&#xff08;HDR10/HLG&#xff09;和SDR的详细解释&#xff1a; 1. SDR&#xff08;Standard Dynamic Range&#xff0c;标准动态范围&#xff09; • 定义&#xff1a;SDR是传统的动态范围标准&#xff0c;主要用于8位色深的视频显示&#xff0c;动态范围较窄&…

【MySQL】验证账户权限

在用户进行验证之后&#xff0c;MySQL将提出以下问题验证账户权限&#xff1a; 1.谁是当前用户&#xff1f; 2.该用户有何权限&#xff1f; 管理权限比如&#xff1a;shutdown、replication slave、load data infile。数据权限比如&#xff1a;select、insert、update、dele…

通过TIM+DMA Burst 实现STM32输出变频且不同脉冲数量的PWM波形

Burst介绍&#xff1a; DMA控制器可以生成单次传输或增量突发传输&#xff0c;传输的节拍数为4、8或16。 为了确保数据一致性&#xff0c;构成突发传输的每组传输都是不可分割的&#xff1a;AHB传输被锁定&#xff0c;AHB总线矩阵的仲裁器在突发传输序列期间不会撤销DMA主设备…

GaussDB数据库表设计与性能优化实践

GaussDB分布式数据库表设计与性能优化实践 引言 在金融、电信、物联网等大数据场景下&#xff0c;GaussDB作为华为推出的高性能分布式数据库&#xff0c;凭借其创新的架构设计和智能优化能力&#xff0c;已成为企业核心业务系统的重要选择。本文深入探讨GaussDB分布式架构下的…

npm install 卡在创建项目:sill idealTree buildDeps

参考&#xff1a; https://blog.csdn.net/PengXing_Huang/article/details/136460133 或者再执行 npm install -g cnpm --registryhttps://registry.npm.taobao.org 或者换梯子

【MySQL】从零开始:掌握MySQL数据库的核心概念(五)

由于我的无知&#xff0c;我对生存方式只有一个非常普通的信条&#xff1a;不许后悔。 前言 这是我自己学习mysql数据库的第五篇博客总结。后期我会继续把mysql数据库学习笔记开源至博客上。 上一期笔记是关于mysql数据库的增删查改&#xff0c;没看的同学可以过去看看&#xf…