技术饭
微信小程序通过STS方式直接上传视频到阿里视频点播解决方案
微信小程序通过STS方式直接上传视频到阿里视频点播解决方案,这里必须批评下阿里云官方的文档写的实在是让人看不懂,是在太乱啦,阿里官方并没有提供微信小程序上传的SDK,然后这个小问题困扰了我两天的时间,下了好几次工单,然后自己一步一步摸索才解决的。
1、PHP后端代码,获取与刷新视频点播的权限信息以及上传地址
/**
* [CreateUploadVideo 获取视频上传地址和凭证接口]
*/
public function CreateUploadVideo() {
if($this->request->isPost()){
//获取参数
$params = $this->request->param();
//视频配置信息
$this->userId = config('video.userId');
$this->regionId = config('video.regionId'); // 点播服务接入区域
$this->accessKeyId = config('video.accessKeyId');
$this->accessKeySecret = config('video.accessKeySecret');
$this->TemplateGroupId = config('video.TemplateGroupId'); //视频分组ID
$this->TemplateGroupIdAudio = config('video.TemplateGroupIdAudio'); //音频分组ID
$this->cateid = config('video.cateid'); //模板ID
$this->StorageLocation = config('video.StorageLocation'); //存储位置
//加载自动加载文件
require_once env('extend_path') . 'voduploadsdk' . DIRECTORY_SEPARATOR . 'Autoloader.php';
//实例化
$profile = \DefaultProfile::getProfile($this->regionId, $this->accessKeyId, $this->accessKeySecret);
$client = new \DefaultAcsClient($profile);
//请求
$request = new \vod\Request\V20170321\CreateUploadVideoRequest();
$request->setTitle($params['title']); // 视频标题(必填参数)
$request->setFileName($params['fielname']); // 视频源文件名称,必须包含扩展名(必填参数)
//$request->setDescription($params['remark']); // 视频源文件描述(可选)
//$request->setCoverURL(''); // 自定义视频封面(可选)
//$request->setTags($params['tags']); // 视频标签,多个用逗号分隔(可选)
$request->setCateId($this->cateid); //设置视频分类ID
$request->setTemplateGroupId($this->TemplateGroupId); //转码模板组ID
$res = $client->getAcsResponse($request);
$res = (array) $res;
if(!isset($res['VideoId']) || empty($res['VideoId'])){
//返回数据
$rdata['code'] = 0;
$rdata['data'] = $res;
$rdata['msg'] = '创建视频失败';
return json($rdata);
}
$res['UploadAddress'] = json_decode(base64_decode($res['UploadAddress']), true);
$res['UploadAddress']['host'] = "http://" . $res['UploadAddress']['Bucket'] . "." . str_replace(array("https://","http://"), '', $res['UploadAddress']['Endpoint']);
$res['UploadAuth'] = json_decode(base64_decode($res['UploadAuth']), true);
//返回数据
$rdata['code'] = 1;
$rdata['data'] = $res;
$rdata['msg'] = '创建视频成功';
return json($rdata);
}
}
/**
* [RefreshUploadVideo 刷新视频上传凭证接口]
*/
public function RefreshUploadVideo() {
if($this->request->isPost()){
//获取参数
$params = $this->request->param();
//视频配置信息
$this->userId = config('video.userId');
$this->regionId = config('video.regionId'); // 点播服务接入区域
$this->accessKeyId = config('video.accessKeyId');
$this->accessKeySecret = config('video.accessKeySecret');
$this->TemplateGroupId = config('video.TemplateGroupId'); //视频分组ID
$this->TemplateGroupIdAudio = config('video.TemplateGroupIdAudio'); //音频分组ID
$this->cateid = config('video.cateid'); //模板ID
$this->StorageLocation = config('video.StorageLocation'); //存储位置
//加载自动加载文件
require_once env('extend_path') . 'voduploadsdk' . DIRECTORY_SEPARATOR . 'Autoloader.php';
//查询视频详情
$profile = \DefaultProfile::getProfile($this->regionId, $this->accessKeyId, $this->accessKeySecret);
$client = new \DefaultAcsClient($profile);
$request = new \vod\Request\V20170321\RefreshUploadVideoRequest();
$request->setVideoId($params['video_id']);
$res = $client->getAcsResponse($request);
$res = (array) $res;
if(!isset($res['VideoId']) || empty($res['VideoId'])){
//返回数据
$rdata['code'] = 0;
$rdata['data'] = $res;
$rdata['msg'] = '刷新视频失败';
return json($rdata);
}
$res['UploadAddress'] = json_decode(base64_decode($res['UploadAddress']), true);
$res['UploadAddress']['host'] = "http://" . $res['UploadAddress']['Bucket'] . "." . str_replace(array("https://","http://"), '', $res['UploadAddress']['Endpoint']);
$res['UploadAuth'] = json_decode(base64_decode($res['UploadAuth']), true);
//返回数据
$rdata['code'] = 1;
$rdata['data'] = $res;
$rdata['msg'] = '刷新视频成功';
return json($rdata);
}
}
2、返回的信息进行签名处理STS上传
//通过STS上传视频到阿里云demo
//1:首先调用点播的接口获取到uploadAuth和UploadAddress这两个数值
//2:对上面两个信息进行base64解码,获取到上传用的STS信息,还有endpoint, objectkey等信息。使用base64解析UploadAuth字符串,可以得到json格式的上传凭证。使用base64解析UploadAddress字符串,可以得到json格式的上传地址。具体参考:https://help.aliyun.com/document_detail/55397.html?spm=a2c4g.11186623.6.594.CtPvo9,其中AccessKeyId、AccessKeySecret、SecurityToken和Expiration就是一对STS信息。
//3:利用web直传,选择本地视频去上传。另外注意一下,因为用的是STS的方式去上传的,表单域里面注意加上:x-oss-security-token 参数值就是解码出来的Token信息
//4.获取到uploadAuth和Address的接口是:https://help.aliyun.com/document_detail/55407.html?spm=a2c4g.11174283.6.630.A80tBD
//5.OSS 的post请求参数请看:https://help.aliyun.com/document_detail/31988.html?spm=5176.11065259.1996646101.searchclickresult.5cab18efejYjTT
/*
//返回数据
{
"code": 1,
"data": {
"UploadAddress": {
"Endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"Bucket": "outin-57a2d845237011e99d0b00163e1c955c",
"FileName": "customerTrans/61e252e80309a494e95a782a3faa3847/3d2cb307-16cfae3ef16-0006-6b02-5f2-58d74.mp4",
"host": "http://outin-57a2d845237011e99d0b00163e1c955c.oss-cn-shanghai.aliyuncs.com"
},
"VideoId": "c3d8e9bd383841579c633ffe0bbd9955",
"RequestId": "7947DAD8-93D7-4E44-BF4B-23886A0EAF00",
"UploadAuth": {
"SecurityToken": "CAIS2wR1q6Ft5B2yfSjIr4iDeeKNnppWwaSxRhHY0FNnZO1orpbyujz2IHlPe3FhAOoev/k/mW9U7foclrUqG8cbGBSbMpoosMoIqFn9JpfZv8u84YADi5CjQecCvK5cmZ28Wf7waf+AUArGCTmd5MgYo9bTcTGlQCZuW//toJV7b9MRcxClZD5dfrl/LRdjr8lo1xGzUPG2KUzSn3b3BkhlsRYe72Rk8vaHxdaAzRDcgVbmqJcSvJ+jC4C8Ys9gG519XtypvopxbbGT8CNZ5z9A9qp9kM49/izc7P6QH35b4RiNL8/Z7tQNXwhiffobHa9YrfHgmNhlvvDSj43t1ytVOeZcX0akQ5u7ku7ZHP+oLt8jaYvjP3PE3rLpMYLu4T48ZXUSODtDYcZDUHhrEk4RUjXdI6Of8UrWSQC7Wsr217otg7Fyyk3s8MaHAkWLX7SB2DwEB4c4aEokVW4RxnezW6UBaRBpbld7Bq6cV5lOdBRZoK+KzQrJTX9Ez2pLmuD6e/LOs7oDVJ37WZtKyuh4Y49d4U8rVEjPQqiykT0cFgpfTK1RzbPmNLKm9baB25/zW+PdDe0dsVgoXVL7piGWG3RLNn+ztJ9xbkeE+sKUkfPFqZ8wTFZ0vY8HVFiIIIdh91Y+u/LstBnK+76+D3vt9Xcj5t7d8pNz80JiZbDmoZfL4G6P7STNO/Zjw5+PBjM0e3ntJSwlmsL1r2kcuhUMn1uzPxsi8FmL3Q6yBpZCiaPTlyoeWvYOybmHF2z8oH8cINaI8qsNZ+RuR+lHSc2gxjtuwvD3ML0OCD43WXwagAE+930aLWPCt1tHotVQ9XjK37tQB8czAGRFpr/E9yIBB4OGwnQW0bgKBKqErnnSP1NPnfTyyqPOTS4mZDwQhIJsInVXx3KKE+Y4TH1W7/iantdq7BMx12IulwbEFHz7jBbbB9/wzBxkNaYZKU6GsIjpKw7sz6GsjFki2yz3xpsicw==",
"AccessKeyId": "STS.NK62X9sEwvfZD7i4S2hbDASYX",
"ExpireUTCTime": "2019-09-04T07:05:49Z",
"AccessKeySecret": "7AXKnRXThv8tRWNTzBTc6Ef68Ym9bBZFAw9N1WFy3AAq",
"Expiration": "3411",
"Region": "cn-shanghai"
}
},
"msg": "创建视频成功"
}*/
//STS方式临时 AccessKeyId
accessid= 'STS.NJKkTbposZ8bdUFcVkJTWgTMA';
//STS方式临时 AccessKeySecret
accesskey= '9DVN15Evqq7r399DDPa42oyuwRBw1SCLzDM4ipkCfTyC';
//点播视频上传地址,请填写返回的
host = 'http://outin-test.oss-cn-shanghai.aliyuncs.com';
//表单 x-oss-security-token
token = 'CAIS2wR1q6Ft5B2yfSjIr4n+IO7WnbBS7fqJZnP3h1Y+Rtt7iJHmozz2IHlPe3FhAOoev/k/mW9U7foclrUqG8cbGBSbMpoosMoIqFn9JpfZv8u84YADi5CjQecl5q5cmZ28Wf7waf+AUArGCTmd5MgYo9bTcTGlQCZuW//toJV7b9MRcxClZD5dfrl/LRdjr8lo1xGzUPG2KUzSn3b3BkhlsRYe72Rk8vaHxdaAzRDcgVbmqJcSvJ+jC4C8Ys9gG519XtypvopxbbGT8CNZ5z9A9qp9kM49/izc7P6QH35b4RiNL8/Z7tQNXwhiffobHa9YrfHgmNhlvvDSj43t1ytVOeZcX0akQ5u7ku7ZHP+oLt8jaYvjP3PE3rLpMYLu4T48ZXUSODtDYcZDUHhrEk4RUjXdI6Of8UrWSQC7Wsr217otg7Fyyk3s8MaHAkWLX7SB2DwEB4c4aEokVW4RxnezW6UBaRBpbld7Bq6cV5lOdBRZoK+KzQrJTX9Ez2pLmuD6e/LOs7oDVJ37WZtKyuh4Y49d4U8rVEjPQqiykT0cFgpfTK1RzbPmNLKm9baB25/zW+PdDe0dsVgoXVL7piGWG3RLNn+ztJ9xbkeE+sKUkfPFqZ8wTFZ0vY8HVFiIIIdh91Y+u/LstBnK+76+D3vt9Xcj5t7d8pNz80JiZbDmoZfL4G6P7STNO/Zjw5+PBjM0e3ntJSwlmsL1r2kcuhUMn1uzPxsi8FmL3Q6yBpZCiaPTlyoeWvYOybmHF2z8oH8cINaI8qsNZ+RuR+lHSc2gxjtuwvD3ML0OCD43WXwagAFRj3MoxFe5fJTQEzTNIrs9E6Zwgq6yO45bAXXYoQUOvNi7Uh2rWOeDytyQ+9jwvIgjWBSNaHCRFxResQ/4rtNSP9pPpjKNiYC+76Z6cNL2kmsdJhRB/Tu+RRseP0sjlfUESxv0TdSe2oYGZj9M89w4vCpsLGaEUaIJP4z1pMW9ug==';
//文件目录以及名称 FileName
key = 'customerTrans/61e252e80309a494e95a782a3faa3847/c96c087-16cfacf787c-0006-6b02-5f2-58d74.mp4';
g_dirname = ''
g_object_name = ''
g_object_name_type = ''
now = timestamp = Date.parse(new Date()) / 1000;
var policyText = {
"expiration": "2019-09-04T06:41:11Z", //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了,记得改成返回的:ExpireUTCTime
"conditions": [
["content-length-range", 0, 1048576000] // 设置上传文件的大小限制
]
};
var policyBase64 = Base64.encode(JSON.stringify(policyText))
message = policyBase64
var bytes = Crypto.HMAC(Crypto.SHA1, message, accesskey, { asBytes: true }) ;
var signature = Crypto.util.bytesToBase64(bytes);
function check_object_radio() {
var tt = document.getElementsByName('myradio');
for (var i = 0; i < tt.length ; i++ )
{
if(tt[i].checked)
{
g_object_name_type = tt[i].value;
break;
}
}
}
function get_dirname()
{
dir = document.getElementById("dirname").value;
if (dir != '' && dir.indexOf('/') != dir.length - 1)
{
dir = dir + '/'
}
//alert(dir)
g_dirname = dir
}
function random_string(len) {
len = len || 32;
var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
var maxPos = chars.length;
var pwd = '';
for (i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
function get_suffix(filename) {
pos = filename.lastIndexOf('.')
suffix = ''
if (pos != -1) {
suffix = filename.substring(pos)
}
return suffix;
}
function calculate_object_name(filename)
{
if (g_object_name_type == 'local_name')
{
g_object_name += "${filename}"
}
else if (g_object_name_type == 'random_name')
{
suffix = get_suffix(filename)
g_object_name = g_dirname + random_string(10) + suffix
}
return ''
}
function get_uploaded_object_name(filename)
{
if (g_object_name_type == 'local_name')
{
tmp_name = g_object_name
tmp_name = tmp_name.replace("${filename}", filename);
return tmp_name
}
else if(g_object_name_type == 'random_name')
{
return g_object_name
}
}
function set_upload_param(up, filename, ret)
{
g_object_name = g_dirname;
if (filename != '') {
suffix = get_suffix(filename)
calculate_object_name(filename)
}
new_multipart_params = {
'key' : key,
'policy': policyBase64,
'OSSAccessKeyId': accessid,
'success_action_status' : '200', //让服务端返回200,不然,默认会返回204
'signature': signature,
'x-oss-security-token':token
};
console.log(new_multipart_params);
up.setOption({
'url': host,
'multipart_params': new_multipart_params
});
up.start();
}
var uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight,html4',
browse_button : 'selectfiles',
//multi_selection: false,
container: document.getElementById('container'),
flash_swf_url : 'lib/plupload-2.1.2/js/Moxie.swf',
silverlight_xap_url : 'lib/plupload-2.1.2/js/Moxie.xap',
url : 'http://oss.aliyuncs.com',
init: {
PostInit: function() {
document.getElementById('ossfile').innerHTML = '';
document.getElementById('postfiles').onclick = function() {
set_upload_param(uploader, '', false);
return false;
};
},
FilesAdded: function(up, files) {
plupload.each(files, function(file) {
document.getElementById('ossfile').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>'
+'<div class="progress"><div class="progress-bar" style="width: 0%"></div></div>'
+'</div>';
});
},
BeforeUpload: function(up, file) {
check_object_radio();
get_dirname();
set_upload_param(up, file.name, true);
},
UploadProgress: function(up, file) {
var d = document.getElementById(file.id);
d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
var prog = d.getElementsByTagName('div')[0];
var progBar = prog.getElementsByTagName('div')[0]
progBar.style.width= 2*file.percent+'px';
progBar.setAttribute('aria-valuenow', file.percent);
},
FileUploaded: function(up, file, info) {
if (info.status == 200)
{
document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'upload to oss success, object name:' + get_uploaded_object_name(file.name);
}
else
{
document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response;
}
},
Error: function(up, err) {
document.getElementById('console').appendChild(document.createTextNode("\nError xml:" + err.response));
}
}
});
uploader.init();
3、详细代码
文明上网理性发言!