这不前两天来了个奇葩需求,我写的小视频平台人家要上传2个G以上的视频,一开始咋想都想不通怎么写,后来一下就茅厕顿开了属于是,话不多说直接上码!
upload.js:
var bytesPerPiece = 5 * 1024 * 1024; // 每个文件切片大小定为5MB .
var nowIndex = 0;//当前片index
var identifier = `${Date.now()}${Math.random()}`;//文件唯一标识
var array = identifier.split('.');//处理唯一标识
identifier = array[0].toString() + array[1].toString();
const fs = wx.getFileSystemManager();
module.exports = Behavior({
data: {
bytesPerPiece: 20 * 1024 * 1024, // 每个文件切片大小定为1MB .
totalPieces: 0,
},
methods: {
onLoad: function (obj) {
},
async uploader(file, time, success_func) {
var arr = file.url.split('/');//拆解文件url
var fileName = arr[arr.length - 1];//获得文件名
var state = false;
var length = parseInt(file.size / bytesPerPiece);//总片数(取整)
if (bytesPerPiece * length == file.size) {
state = true
}
if (nowIndex < length) {
var chunk = fs.readFileSync(file.url, '', nowIndex * bytesPerPiece, bytesPerPiece);//按第几片加文件长度读取片文件;
// var identifier = sparkMd5.hash(uuid);
console.log(chunk)
try {
fs.writeFileSync(//保存片文件
`${wx.env.USER_DATA_PATH}/${fileName}`,//给文件一个路径
chunk,
'utf8'
)
} catch (e) {
console.error(e)
}
var obj = { chunkSize: bytesPerPiece, fileName: fileName, identifier: identifier, index: nowIndex, totalChunks: state ? length : length + 1, totalSize: file.size }
console.log(nowIndex, obj);
await wx.uploadFile({
url: this.data.host + '/apiToker/tkFile/base/burstUpload',
// url: args.url,
header: {
// method: 'GET',
Authorization: wx.getStorageSync('Authorization'),
},
filePath: `${wx.env.USER_DATA_PATH}/${fileName}`,
name: 'file',
// header: {},
formData: obj,
success: res => {
nowIndex++;
this.uploader(file, time, success_func);
},
fail: res => {
console.log(res);
}
})
}
if (nowIndex == length && !state) {//当index等于分片长度时上传剩余部分
var chunk = fs.readFileSync(file.url, '', nowIndex * bytesPerPiece, file.size - (nowIndex * bytesPerPiece));//按第几片加文件长度读取片文件;
console.log('upload7', chunk)
try {
fs.writeFileSync(//保存片文件
`${wx.env.USER_DATA_PATH}/${fileName}`,
chunk,
'utf8'
)
} catch (e) {
console.error(e)
}
var obj = { chunkSize: file.size - (nowIndex * bytesPerPiece), fileName: fileName, identifier: identifier, index: nowIndex, totalChunks: state ? length : length + 1, totalSize: file.size }
console.log(nowIndex, obj);
await wx.uploadFile({
url: this.data.host + '/apiToker/tkFile/base/burstUpload',
// url: args.url,
header: {
// method: 'GET',
Authorization: wx.getStorageSync('Authorization'),
},
filePath: `${wx.env.USER_DATA_PATH}/${fileName}`,
name: 'file',
// header: {},
formData: obj,
success: res => {
console.log(res);
this.request({
url: this.data.host + '/apiToker/tkFile/base/mergeShard',
data: { identifier: identifier, fileName: fileName },
method: 'POST'
}, res => {
this[success_func](res, time);
})
}
})
}
}
}
})
你需要上传视频的页面需要引入vant的van-uploader组件
wxml:
js:
先需要在页面引入上面的js,用behaviors继承;
// pages/my/add_video/add_video.js
var uploader = require('../../../common/upload.js');
Page({
behaviors: [uploader],
/**
* 页面的初始数据
*/
data: {
fileList: [],
videoData: { value: "", state: false, emptyTip: '您还没上传视频' },
timer: "",
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
afterRead(event) {
wx.showLoading({
title: '正在上传',
mask: true
})
const { file } = event.detail;
console.log(file);
let that = this;
var arr = file.url.split('/');
console.log("arr", arr);
this.uploader(file, parseInt(file.duration), 'success');
},
success(res, time) {
this.data.videoData.value = JSON.stringify(res.data);
console.log(res);
// 上传完成需要更新 fileList
var fileList = this.data.fileList;
fileList.push({ url: res.data.fileUrl, duration: time });
this.setData({ fileList: fileList });
wx.hideLoading();
},
delete(e) {
let fileList = this.data.fileList;
let index = e.detail.index;
fileList.splice(index, 1);
this.setData({
fileList,
})
},
tooBig() {
wx.showToast({
title: '视频大小不可以超过3G!',
})
},
})
雷猴我是前端鸡莫西,觉得写的好的麻烦点点关注谢谢老板们~祝您新年月薪2个W写的代码没bug~