一、對接說明
- 前端安裝好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