1.上传的组件是基于antd的Upload 上前端页面 采用手动上传的方式
<Upload
action=''
onChange={this.uploadVideo}
headers={{'Content-Type': 'application/json'}}
beforeUpload={this.beforeUpload}
showUploadList={{showRemoveIcon: false}}
>
<Button>上传视频</Button>
<span style={{marginLeft:15, fontSize:14, color:"#858585"}}><Icon type="exclamation-circle" style={{marginRight:5,verticalAlign:"middle"}}/>上传中请勿进行其他操作!</span>
</Upload>
2.js代码
import {getSign} from '../../utils/sign'
beforeUpload=(file)=> {
let files = [];
this.setState({
fileList: [...files]
})
return false;
}
//获取签名
getSignature=(info,signature)=> {
const {liveInfo} = this.props;
const UID = getUid();
let media_type = (info.file.type === '' && (info.file.name.substring(info.file.name.lastIndexOf('.')+1)).toLowerCase() === 'flv') ? 'FLV' : 'MP4';
let obj = JSON.stringify({uid:UID,appid:liveInfo.id,file_name:info.fileList[info.fileList.length-1].name,media_type:media_type,SecretId:SecretId,Signature:signature});
return request('http://*******/nnapi/VodManage/CreateUploadVideo', { //请求后台的接口 接收签名
method: 'POST',
headers: {'Content-Type':'application/json'},
body: obj,
dataType:'json',
}).then((response) => {
return response.data.code.signature;
})
};
//上传视频 upload组件发生变化的时候自动触发
uploadVideo = (info) => {
let newInfo = [];
let flvType = '';
info.fileList.forEach(item=>{
if(item.type === 'video/mp4' || ((item.name.substring(item.name.lastIndexOf('.')+1)).toLowerCase() === 'flv' && item.type === '')){
newInfo.push(item)
}
})
info.fileList = newInfo;
//过滤上传的视频 把不符合条件的给过滤掉 从最后一个开始上传 防止用户中间上传不符合条件的文件
const isMP4 = info.file.type === 'video/mp4';
const isFLV = info.file.type === '' && (info.file.name.substring(info.file.name.lastIndexOf('.')+1)).toLowerCase() === 'flv';
//MP4 FLV符合一个即可
if (!((!isMP4 && isFLV) || (isMP4 && !isFLV))) {
message.error('只能上传mp4或者flv格式');
return false;
}
const isLt3G = info.file.size < 3 * 1024 * 1024 *1024;
if (!isLt3G) {
message.error('文件大小必须小于 3G!');
return false;
}
let that = this;
const {liveInfo} = this.props;
const UID = getUid();
let signData1 = {
appid: '0',
file_name: info.fileList[0].name.replace(/\s+/g, ""),
media_type,
uid: UID,
SecretId: "xxxxxx"
}
const signature = getSign(signData1);
const tcVod = new TcVod.default({
getSignature:()=>{
return that.getSignature(info,signature)
}
})
const uploader = tcVod.upload({
mediaFile: info.fileList[0].originFileObj, // 媒体文件(视频或音频或图片),类型为 File
})
//上传进度 控制进度条的进度 ps:upload采用手动上传之后 组件自带的进度条消失了(暂时没找到解决办法,所以自己用了一个外部的进度条控制)
uploader.on('media_progress', function(info) {
let percent = parseInt(info.percent * 100);
that.setState({
proPrecent:percent
})
})
//上传完成
uploader.done().then(function (doneResult) {
// deal with doneResult
if(doneResult.fileId){
let signData2 = {
appid:liveInfo.id,
file_name:info.fileList[0].name.replace(/\s+/g, ""),
media_type,
uid:UID,
SecretId:"xxxxxx",
url:doneResult.video.url,
file_id:doneResult.fileId
}
const signatureDone = getSign(signData2);
let media_type = (info.file.type === '' && (info.file.name.substring(info.file.name.lastIndexOf('.')+1)).toLowerCase() === 'flv') ? 'FLV' : 'MP4';
//上传完成
let obj = JSON.stringify({uid:UID,appid:liveInfo.id,file_name:info.fileList[info.fileList.length-1].name,media_type:media_type,file_id:doneResult.fileId,url:doneResult.video.url,Signature:signatureDone,SecretId:SecretId});
request('http://*******/nnapi/VodManage/UploadComplete', { //请求后台的接口 进行转码
method: 'POST',
headers: {'Content-Type':'application/json'},
body: obj,
dataType:'json',
}).then((response) => {
const uploadVideoArr = that.state.uploadVideoList;
let tmpVideo = {
id: '',
snap_url: "",
title: response.data.file_name,
vod_url: 'transcoding'
}
uploadVideoArr.unshift(tmpVideo);
that.setState({
uploadVideoList:uploadVideoArr
})
})
}
}).catch(function (err) {
// deal with error
console.log(err)
message.error('上传失败')
})
}
2.封装的getSign.js代码 前端自己计算签名 ps:为了防止别人拿到链接一直请求 所以需要前端计算签名和后端的签名进行匹配 匹配完成才允许上传
//对传入的参数进行排序 相当于php中ksort 函数
function JsonSort(jsonData) {
try {
let tempJsonObj = {};
let sdic = Object.keys(jsonData).sort();
sdic.map((item, index)=>{
tempJsonObj[item] = jsonData[sdic[index]]
})
return tempJsonObj;
} catch(e) {
return jsonData;
}
}
/* js生成签名 */
export function getSign(data) { // 获取签名 返回一个包含"?"的参数串
var dataJson = date;
var obj = JsonSort(dataJson);
var src_str = JSON.stringify(obj).replace(/{|}/g,'').replace(/":"/g,'=').replace(/":/g,'=').replace(/","/g,'&').replace(/,"/g,'&').replace(/\\"/g,"'").replace(/"/g,"");
//可过滤空格
return calculateSign(src_str);
}
// 生成sign
function calculateSign(str) {
var CryptoJS = require('crypto-js'); //我下载的版本 "crypto-js": "^3.1.9-1"
var srcStr = str;
var secretKey = secretKey;
var retStr = (CryptoJS.HmacSHA1(srcStr, secretKey)).toString(CryptoJS.enc.Base64); //用于转码
return retStr;
}