//去选取视频,然后根据视频来判断需要不需要进行剪辑功能,如果进入剪辑,iOS不显示视频时间,安卓显示,所以如果有时长限制可以直接用参数来设置最小时长和最大时长
goVideo = (index) => {
this.pauseVideo()
const { houseMaterialInfo } = this.state
let houseInfo = houseMaterialInfo
this.setState({ upLoadingIndex: index })
wx.chooseMedia({
sourceType: ['album'],
mediaType: ['video'],
count: 1,
sizeType: ['original'],
success: res => {
if (res.tempFiles[0].size > (500 * 1024 * 1024)) {
Utils.info('上传视频超过500MB,请重新录制')
return
}
houseInfo[index].isUpdaLoaded = true
this.setState({ houseMaterialInfo: houseInfo })
if (res.tempFiles[0].duration > 25){
Utils.info('上传视频超过25秒,请进行编辑')
setTimeout(()=>{
this.editVideo(res.tempFiles[0].tempFilePath, index, (res.tempFiles[0].width < res.tempFiles[0].height ? true : false))
},1000)
return
}else{
if (Uploader.isSupport()) {
this.uploadOne(res.tempFiles, 0, index, res.tempFiles[0].duration, (res.tempFiles[0].width < res.tempFiles[0].height ? true : false))
} else {
this.uploadLoadRecord(res.tempFiles[0])
}
}
},
fail: (err) => {
// Utils.info('上传视频失败')
houseMaterialInfo[index].mediaPath = ''
houseInfo[index].isUpdaLoaded = false
this.setState({ houseMaterialInfo: houseInfo })
}
})
}
editVideo = (videoPath, index, isPortraitVideo) =>{
const { houseMaterialInfo } = this.state
wx.openVideoEditor({
filePath: videoPath,
minDuration:15,
maxDuration:25,
success:(res)=> {
if (Uploader.isSupport()) {
this.uploadOne([res], 0, index, (res.duration / 1000), isPortraitVideo)
} else {
this.uploadLoadRecord(res.tempFilePath)
}
// 可以在这里处理编辑后的视频,例如上传到服务器
},
fail:(err)=> {
let houseInfo = houseMaterialInfo
houseInfo[index].isUpdaLoaded = false
this.setState({ houseMaterialInfo: houseMaterialInfo })
console.log('编辑视频失败',err);
}
});
}
// 分片上传是一个用于上传视频文件的方法,isPortraitVideo 参数判断是否为竖屏视频
uploadOne(obj, n = 0, index, videoLength, isPortraitVideo) {
// 获取当前组件的 state 中的 houseMaterialInfo 数据
const { houseMaterialInfo } = this.state;
// 根据环境选择上传和合并文件的 API 地址
const uploadUrl = `${env === 'dev' || env === 'test' ? '上传地址' : '上传地址'}/xcx/v1/tool/chunk/upload-file`;
const mergeUrl = `${env === 'dev' || env === 'test' ? '地址' : '地址'}/xcx/v1/tool/chunk/complete-upload`;
// 如果没有文件要上传,直接退出
if (typeof (obj[n]) === 'undefined') { return false }
// 标记上传正在进行中
this.isUploading = true;
Utils.info('上传中...'); // 提示上传开始
// 获取上传文件的路径
const tempFilePath = obj[n].tempFilePath;
// 获取当前时间并处理文件的扩展名和其它信息
const d = new Date();
const tmpArr = tempFilePath.split('.');
const file = { fileName: '', ext: '', index: 0, now: 0, chunkSize: 5 * 1024 * 1024, dir: '' };
file.now = parseInt(d.getTime() + '' + rndInt(1000, 9999), 10); // 生成唯一的文件名
if (tmpArr.length > 1) { file.ext = tmpArr.pop().toLowerCase() } // 获取文件扩展名并转换为小写
file.fileName = file.now + (file.ext !== '' ? '.' + file.ext : ''); // 拼接文件名
file.index = Math.ceil(obj[n].size / file.chunkSize); // 计算文件的分片数
file.dir = d.getFullYear() + '' + lt10(d.getMonth() + 1) + lt10(d.getDate()); // 生成文件上传目录
// 引入签名模块,生成上传所需的签名
const signature = require('@/signature/index.ts').default;
const postBody = {
url: uploadUrl,
method: 'POST',
header: {
Authorization: ''
}
};
// 为上传请求生成签名
signature['api-b-livein.ke.com'](
Object.assign(
{
headers: {}
},
postBody
)
);
// 配置上传的选项
const opt = {
fileName: file.fileName,
chunkSize: file.chunkSize,
maxConcurrency: 5, // 最多允许 5 个并发上传
maxChunkRetries: 3, // 最大重试次数为 3
chunkRetryInterval: 3000, // 每次重试的时间间隔为 3 秒
totalSize: obj[n].size, // 文件总大小
query: { fid: 1, dir: file.dir }, // 上传时的参数
uploadUrl, // 分片上传 URL
mergeUrl, // 合并分片 URL
tempFilePath, // 临时文件路径
timeout: 60000, // 超时时间设置为 60 秒
header: {
'Content-Type': 'multipart/form-data', // 设置请求内容类型
accept: 'application/json', // 接受的响应格式
'Livein-Access-Token': Utils.read('token'), // 用户的访问令牌
userId: Utils.read('daiKeUserId') || '', // 用户 ID
Authorization: postBody.header.Authorization // 请求的 Authorization
},
};
// 处理不同类型的文件,目前暂时没有根据类型做处理
switch (obj[n].fileType) {
case 'image':
break;
case 'video':
break;
default:
}
// 创建一个上传器实例
const uploader = new Uploader(opt);
// 处理上传重试事件
uploader.on('retry', (res) => {});
// 处理上传成功事件
uploader.on('success', (res) => {
// 如果上传成功,更新状态
if (res.errno === 0 && res.data && res.data.path) {
this.isUploading = false; // 标记上传完成
houseMaterialInfo[index].mediaPath = res.data.path; // 存储文件路径
houseMaterialInfo[index].videoUrl = tempFilePath; // 存储视频的本地路径
houseMaterialInfo[index].isUpdaLoaded = false; // 更新状态
// 判断视频长度和是否竖屏,如果不符合要求,提示上传限制
if (parseInt(videoLength) < 15 || parseInt(videoLength) > 25 || !isPortraitVideo) {
houseMaterialInfo[index].suggestText = '请上传 15s~25s的竖版视频';
}
this.setState({ houseMaterialInfo }); // 更新组件的状态
} else {
this.isUploading = false; // 上传失败时,标记上传状态
houseMaterialInfo[index].isUpdaLoaded = false; // 标记为上传失败
this.setState({ isUploading: false, houseMaterialInfo });
Utils.info(res.error || '上传失败'); // 显示错误信息
}
});
// 处理上传失败事件
uploader.on('fail', (res) => {
this.isUploading = false;
houseMaterialInfo[index].isUpdaLoaded = false;
this.setState({ isUploading: false, houseMaterialInfo });
Utils.info(res.error || '上传失败'); // 显示上传失败的错误信息
});
// 处理上传进度事件
uploader.on('progress', (res) => {
const tmp = {
eq: n,
size: obj[n].size / 1024, // 文件大小(KB)
progress: res.progress, // 上传进度
uploadedSize: parseInt(`${res.uploadedSize / 1024}`), // 已上传的大小(KB)
averageSpeed: parseInt(`${res.averageSpeed / 1024}`), // 平均上传速度(KB/s)
timeRemaining: res.timeRemaining / 1000 // 剩余上传时间(秒)
};
this.setState({ upload: tmp }); // 更新上传进度
});
// 开始上传文件
uploader.upload();
this.uploader = uploader; // 保存上传实例
}
// 上传资源文件的方法
uploadLoadRecord = (paramRes) => {
// 如果当前已经有文件在上传,禁止重复上传
if (this.isUploading) return;
// 设置上传 URL
const url = `${env === 'dev' || env === 'test' ? 'http://test-i.app-api-b.ttb.test.ke.com' : 'https://api-b-livein.ke.com'}/xcx/v1/tool/upload-resource`;
// 标记上传正在进行中
this.isUploading = true;
Utils.info('上传中...');
this.setState({ isUploading: true });
// 为上传请求生成签名
const signature = require('@/signature/index.ts').default;
const postBody = {
url,
method: 'POST',
header: {
Authorization: ''
}
};
signature['api-b-livein.ke.com'](
Object.assign(
{
headers: {}
},
postBody
)
);
// 使用 Ditto 库上传文件
Ditto.uploadFile({
url,
filePath: paramRes.tempFilePath, // 文件的路径
name: 'resource', // 文件表单字段名
formData: {},
header: {
'Content-Type': 'multipart/form-data',
accept: 'application/json',
'Livein-Access-Token': Utils.read('token'), // 用户令牌
userId: Utils.read('daiKeUserId') || '', // 用户 ID
Authorization: postBody.header.Authorization // 请求的 Authorization
},
success: res => {
// 解析返回的数据,上传成功时更新状态
const respon = JSON.parse(res.data);
if (respon.errno === 0 && respon.data && respon.data.path) {
this.setState({ isUploading: false, upLoadingIndex: -1 });
this.isUploading = false;
this.setState({
videoPath: respon.data.path, // 上传成功后返回的视频路径
videoSrc: paramRes.tempFilePath // 视频源路径
});
} else {
this.isUploading = false;
this.setState({ isUploading: false, upLoadingIndex: -1 });
Utils.info(respon.error || '上传失败'); // 显示错误信息
}
},
fail: err => {
// 上传失败时的处理
this.isUploading = false;
this.setState({ isUploading: false, upLoadingIndex: -1 });
Utils.info(err || '上传失败'); // 显示上传失败的错误信息
}
});
};
小程序分片上传
于 2025-02-19 11:56:43 首次发布