一、对接说明
- 前端安装好oss依赖,npm install ali-oss
- 请求PHP接口得到临时凭证,把临时凭证传入并初始化OSS对象
- 执行OSS对象的multipartUpload方法,并传入附件、文件参数、上传进度监听函数等值即可实现上传。
- 上传成功后,将VideoId存入数据库。视频点播与对象存储不同,对象存储上传成功后会返回存储文件的相对路径。但视频点播只会返回VideoId,然后通过VideoId取得播放地址。
阿里云node.js分片上传文件(官方文档):https://help.aliyun.com/document_detail/111268.html
阿里云PHP生成视频点播上传凭证(官方文档):https://help.aliyun.com/document_detail/61069.html
二、上传实现
- 前端代码(组件)
<template>
<div>
<div class="oss_file">
<input
type="file"
:disabled="percentage != 0 && percentage != 100"
:id="id"
:multiple="multiple"
@change="doUpload"
/>
<template v-if="percentage != 0 && percentage != 100">
上传进度:{{ percentage }}%
<Button type="error" @click="cancelUpload()" ghost size="small"
>取消上传</Button
>
</template>
<template v-else-if="percentage == 100"> <span style="color:green;">上传成功</span> </template>
</div>
</div>
</template>
<script>
import { SET_SIGN } from "@/utils";
import OSS from "ali-oss";
export default {
data() {
return {
percentage: 0, //上传进度
client: {}, //OSS对象
uploadId: "", //上传标识
multiple: true,
VideoId: "", //视频ID
id: "videoId",
fileName: "", //上传对象名
};
},
methods: {
//取消上传文件
cancelUpload() {
this.percentage = 0;
this.client.abortMultipartUpload(this.fileName, this.uploadId);
this.cancelFile();
},
//清空文件
cancelFile() {
var file = document.getElementById(this.id);
file.value = "";
},
//文件上传
doUpload() {
const _this = this;
const fileLen = document.getElementById(_this.id).files;
const file = fileLen[0];
let res = this.filesAdded(file);
if (!res) {
this.cancelFile();
return;
}
const progress = (p, _checkpoint) => {
_this.uploadId = _checkpoint.uploadId;
_this.percentage = parseInt(p * 100);
if (_this.percentage == 100) {
_this.fileSuccess(_this.VideoId);
}
};
this.$axios
.post(
_this.$api.knowledgeSystem_createUploadVideo,
Object.assign({ fileName: file.name }, SET_SIGN())
)
.then((res) => {
if (res.data.status == "200") {
var data = res.data.data;
_this.VideoId = data.VideoId;
var UploadAuth = data.UploadAuth;
var UploadAddress = data.UploadAddress;
//从视频点播服务获取的uploadAuth、uploadAddress和videoId,设置到SDK里
_this.fileName = UploadAddress.FileName;
_this.client = new OSS({
region: "oss-cn-shanghai",
accessKeyId: UploadAuth.AccessKeyId,
accessKeySecret: UploadAuth.AccessKeySecret,
stsToken: UploadAuth.SecurityToken,
bucket: UploadAddress.Bucket,
});
try {
// object-name可以定义为文件名(例如file.txt)
const result = _this.client.multipartUpload(
UploadAddress.FileName,
file,
{
progress,
// meta是用户自定义的元数据,通过head接口可以获取到Object的meta数据。
meta: {
year: 2020,
people: "test",
},
}
);
} catch (e) {
// 捕获超时异常。
if (e.code === "ConnectionTimeoutError") {
console.log("TimeoutError");
// do ConnectionTimeoutError operation
}
console.log(e);
}
} else {
_this.$Message.error("请求失败");
}
});
},
},
props: {
fileSuccess: {
//定义一个外来方法
type: Function, //参数类型:函数
required: true, //是否必填:是
},
filesAdded: {
//定义一个外来方法
type: Function, //参数类型:函数
required: true, //是否必填:是
},
},
async mounted() {
this.cancelFile();
},
};
</script>
- 后端代码
先下载好oss的PHP SDK,这里放在extend目录
<?php
namespace app\knowledge\controller;
require_once dirname(ROOT_PATH) . DIRECTORY_SEPARATOR . \'crmapi\' . DIRECTORY_SEPARATOR . \'extend\' . DIRECTORY_SEPARATOR . \'voduploadsdk\' . DIRECTORY_SEPARATOR . \'aliyun-php-sdk-oss\' . DIRECTORY_SEPARATOR . \'autoload.php\'; //当前服务器上的位置
use aliyunapi\oss\FileManage;
use think\Cache;
use think\Controller;
class Upload extends Controller
{
/**
* 得到视频上传地址与凭证
*/
public function createUploadVideo()
{
$fileObj = new \aliyunapi\vod\FileManage();
$fileName = input(\'fileName\');
if (empty($fileName)) {
success_msg(200, \'ok\', []);
}
$res = $fileObj->createUploadVideo($fileName);
success_msg(200, \'ok\', $res);
}
}
里面的函数
<?php
namespace aliyunapi\vod;
require_once dirname(ROOT_PATH) . DIRECTORY_SEPARATOR . \'crmapi\' . DIRECTORY_SEPARATOR . \'extend\' . DIRECTORY_SEPARATOR . \'voduploadsdk\' . DIRECTORY_SEPARATOR . \'Autoloader.php\'; //当前服务器上的位置
use AliyunVodUploader;
use OSS\Core\OssException;
use OSS\OssClient;
use UploadVideoRequest;
use think\Exception;
use vod\Request\V20170321\GetMezzanineInfoRequest;
use vod\Request\V20170321\GetPlayInfoRequest;
use vod\Request\V20170321\RefreshUploadVideoRequest;
/**
* 阿里云文件管理
*/
class FileManage
{
/**
* 获取视频上传地址和凭证
* @param client 发送请求客户端
* @return CreateUploadVideoResponse 获取视频上传地址和凭证响应数据
*/
function createUploadVideo($object) {
$ali_vod_endpoint1 = config(\'general.ali_vod_endpoint1\');
$uploader = new AliyunVodUploader(config(\'general.ali_vod_access_key_id\'),
config(\'general.ali_vod_access_key_secret\'), $ali_vod_endpoint1);
$uploadVideoRequest = new UploadVideoRequest($object);
$userData = array(
"Vod"=>[],
);
$uploadVideoRequest->setUserData(json_encode($userData));
$uploadInfo = $uploader->createUploadVideo($uploadVideoRequest);
$uploadInfo = json_decode(json_encode($uploadInfo), true);
return $uploadInfo;
}
}
返回的结果
{
"status": 200,
"msg": "ok",
"data": {
"VideoId": "c27349fac2cb440e835e3259ddb73076",
"UploadAddress": {
"Endpoint": "https://oss-cn-shanghai.aliyuncs.com",
"Bucket": "outin-7770f6706e4211ea8ad600163e1c8dba",
"FileName": "sv/601b2f0e-17b580e350b/601b2f0e-17b580e350b.mp4"
},
"RequestId": "42CD05DF-CDA0-527F-B723-0EE5269F7990",
"UploadAuth": {
"SecurityToken": "SecurityToken的值",
"AccessKeyId": "STS.NUWjw28NBfUZ9qzgWYpLUA6Tw",
"ExpireUTCTime": "2021-08-18T07:58:51Z",
"AccessKeySecret": "FguyjDtoHq3iSbhCPKxPEREMctA7H58P6sfBv6L229Mo",
"Expiration": "3600",
"Region": "cn-shanghai"
},
"OriUploadAddress": "OriUploadAddress的值",
"OriUploadAuth": "OriUploadAuth的值",
"MediaType": "video",
"MediaId": "c27349fac2cb440e835e3259ddb73076"
}
}
三、前端播放
- 播放说明
阿里云视频点播支持的音视频扩展有很多种,但视频查看接口只支持(mp4、m3u8、mp3、mpd),否则会调用GetPlayInfo会出现:The video has no stream to play for the request parameter \'StreamType : audio \'。其它格式需要播放,第一种方法是上传时都转码成mp4,第二种方法是调用GetMezzanineInfo方法,得到源文件信息。源文件信息含有播放地址。 - 通过GetPlayInfo得到音视频信息
https://help.aliyun.com/document_detail/61070.html - 通过GetMezzanineInfo得到音视频源信息
https://help.aliyun.com/document_detail/59624.html
请发表评论