当前位置: 首页 > news >正文

鸿蒙进行视频上传,使用 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 = await
    photoPicker.select(PhotoSelectOptions)
      .then((result) => {
        this.albumPath = result.photoUris[0];
        const fileName = Date.now() + '.' + 'mp4'
        const copyFilePath = this.context.cacheDir + '/' + fileName
        const 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.UploadTask
    let 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_url
              LoadingDialog.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.UploadTask
    let 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_url
          LoadingDialog.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 = await
    photoPicker.select(PhotoSelectOptions)
      .then((result) => {
        this.albumPath = result.photoUris[0];
        const fileName = Date.now() + '.' + 'mp4'
        const copyFilePath = this.context.cacheDir + '/' + fileName
        const 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])

  }
}

相关文章:

  • 深入理解C#中的享元模式(Flyweight Pattern)
  • 感应电机反电动势频率与电源频率相等以及转差率的测量机制
  • 26考研——图_图的遍历(6)
  • 【C++】vector的push_back和emplace_back
  • 电动自行车/电动工具锂电池PCM方案--SH367003、SH367004、SH79F329
  • C# SerialPort 类中 Handshake 属性的作用
  • 基于springboot人脸识别的社区流调系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 如何解决用户名文件夹是中文导致的识别不到路径,获取不到ssh密匙
  • 淘宝历史价格数据获取指南:API 与爬虫方案的合法性与效率对比
  • 大模型——字节跳动开源AI Agent框架Agent TARS:智能化自动化的新利器
  • 人工智能之数学基础:特征值和特征向量
  • 监控IP,网站将异常情况通过飞书机器人发至指定群内
  • xss-labs
  • Hive安装后续配置
  • 211、【图论】建造最大岛屿(Python)
  • 个人学习编程(3-24) 数据结构
  • vite中sass警告JS API过期
  • 智能语言交互,AI 对话引领生活变革
  • HarmonyOS Next~鸿蒙AI功能开发:Core Speech Kit与Core Vision Kit的技术解析与实践
  • el-select下拉框,搜索时,若是匹配后的数据有且只有一条,则当失去焦点时,默认选中该条数据
  • .net招聘网站怎么做/百度搜索资源平台官网
  • 相城建设监理有限公司网站/全网搜索指数
  • 网站建设的三大原则/网络营销成功的品牌
  • 什么网站做简历免费/广告公司营销策划方案
  • 南宁市做网站的公司/市场营销试题库(带答案)
  • 松江新城做网站/女生学电子商务好吗