最终方案请直接看文章最后!
最近在做一个微信小程序录制视频(图片也是一样的逻辑),然后上传后端的功能,使用的是微信小程序提供的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,系统异常
}
}
仅为测试调试代码,有需要请调整优化,执行完可以看到文件确实存到后端服务器的本地了:
收工