草庐IT

微信小程序cameraContext拍摄的视频或照片上传后端,不需要处理实时监听的ArrayBuffer格式的视频数据,只需要直接使用wx.uploadFile上传后端,简单好用(带前后端代码)

学编程的司马光 2024-02-23 原文

最终方案请直接看文章最后!

最近在做一个微信小程序录制视频(图片也是一样的逻辑),然后上传后端的功能,使用的是微信小程序提供的cameraContext实例,具体官方文档请参考:

CameraContext | 微信开放文档

然后发现录制好后,成功的响应信息response中存的都是地址:

tempThumbPath - 封面图片文件的临时路径 (本地路径):
tempThumbPath: "http://tmp/8tuxDZnK7tdt678c62402deaa133e9dbf62f746f1f23.jpg",

tempVideoPath - 视频的文件的临时路径 (本地路径,特别需要注意:微信开发工具里上传的视频格式为webm,真机上为mp4。)
tempVideoPath: "http://tmp/ZCoaEV8mrjDk0d2caffb008ec28bcef88d60d1272031.webm"

本来想直接和后端进行交互,将视频文件直接传送给后端,发现这两个地址都是url字符串,需要拿到真实的视频数据才可以,于是在找到了获取实时录制的视频数据的方法,获取摄像头当前帧图像:

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log("onLoad options", options)
    this.cameraContext = cameraContext;
    //this.setCameraSize();
    // 获取 Camera 实时帧数据
    // context.onCameraFrame()返回视频图像的监听器
    this.listener = this.cameraContext.onCameraFrame((frame) => {
      // frame.data 就是视频数据 格式是ArrayBuffer
      console.log(frame.data instanceof ArrayBuffer, frame.width, frame.height)
      this.videoFile = frame.data;
    });
  }

// 在视频开始录制startRecord中调用开始监听的方法
this.listener.start() // 开始监听帧数据

// 在视频结束录制stopRecord中调用停止监听的方法
this.listener.stop(this); // 停止监听帧数据

打印后发现videoFile是ArrayBuffer格式的数据:

 因此想把ArrayBuffer转换成Blob格式的数据,再传给后端,发现微信小程序暂不支持Blob格式数据,因此放弃。

CSDN上倒是有个兄弟转成了Base64,但是有点过于复杂,有需要可以看看

微信小程序onCameraFrame获取的ArrayBuffer转为base64图片的方法

最终还是去官网找到了解决方案:

官方说明文档:

微信小程序将将本地资源上传到服务器

微信小程序代码:

第一个参数video就是上面的tempVideoPath - 视频的文件的临时路径

  upRecord: (video, token, type) => {
    let formData = { 
      token: "123qwe",
      type: "SV",
    };
    wx.uploadFile({
      url: PATH.PATH_UP_RECORD,//这是你自己后台的连接
      filePath: video,
      name:"file",//后台要绑定的名称
      header: {
        "Content-Type": "multipart/form-data"
      },
      //参数绑定
      formData: formData,// HTTP 请求中其他额外的 form data
      success:function(ress){
        console.log('上传成功,返回内容是: ', ress);
        wx.showToast({
          title: '上传成功',
        })
      },
      fail: function(ress){
        console.log("。。上传服务器 失败", ress);
        wx.showToast({
          title: '上传失败',
        })
      }
    })
  },

后端代码:

@RequestParam("file") MultipartFile file 这个请求参数名,

需要和上面的name(name:"file",//后台要绑定的名称)对应

	@RequestMapping(value = "/upVideo", method = RequestMethod.POST)
	public ResponseEntity<JSONObject> upVideo(@RequestParam("file") MultipartFile file,
	                                          @RequestParam String token,
	                                          @RequestParam String type) {
		JSONObject json = new JSONObject();
		try {
			if (file.isEmpty() || StringUtils.isBlank(token)) {
				log.info("上传失败,上传数据存在空值 token={}", token);
				json.put("STATUS", "ERROR");
				json.put("MSG", "上传失败,上传数据存在空值");
				return new ResponseEntity<>(json, HttpStatus.BAD_REQUEST);
			}
			//存放地址
			String path = "D:\\20220907\\video";
			//如果父文件夹不存在 则创建文件夹 文件夹为path,视频名字file.getOriginalFilename()
			File filepath = new File(path, Objects.requireNonNull(file.getOriginalFilename()));
			if (!filepath.getParentFile().exists()) {
				filepath.getParentFile().mkdirs();
			}
			File fi = new File(path + File.separator + file.getOriginalFilename());
			//下载到本地
			file.transferTo(fi);
			//获取绝对路径
			String localAddress = fi.getAbsolutePath();
			log.info("存入本地文件地址:" + localAddress);
			//获取后缀名
			String suffix = localAddress.substring(localAddress.lastIndexOf("."), localAddress.length());
			log.info("后缀名:" + suffix);
			json.put("STATUS", "200");
			json.put("MSG", "上传视频成功");
			return new ResponseEntity<>(json, HttpStatus.OK);

		} catch (Exception e) {
			log.error("系统异常,上视频失败", e);
			return new ResponseEntity<>(json, HttpStatus.INTERNAL_SERVER_ERROR);//500,系统异常
		}
	}

仅为测试调试代码,有需要请调整优化,执行完可以看到文件确实存到后端服务器的本地了:

收工

有关微信小程序cameraContext拍摄的视频或照片上传后端,不需要处理实时监听的ArrayBuffer格式的视频数据,只需要直接使用wx.uploadFile上传后端,简单好用(带前后端代码)的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  4. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  5. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  6. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  7. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  8. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  9. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  10. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

随机推荐