POLYV 影片上傳 SDK
更新時間:2025-04-01 14:21:09
Polyv JavaScript 上傳 SDK 為您提供上傳媒體檔案到保利威雲點播平台的開發工具包。
功能
- 快速上傳多種格式的媒體檔案。
- 支援上傳時的各種設定,如檔案標題、描述、標籤、上傳目錄、是否開啟課件優化處理等。
- 預設採用分片並發上傳的方式,支援斷點續傳。
使用方法
前提條件
- 使用本 SDK 前,需先開通保利威雲點播服務。如果您還不瞭解該服務,請登入產品主頁查看,詳見:雲點播。
- 取得 secretKey 等相關資訊用於使用者身份驗證,您可以在「雲點播管理後台 -> 設定 -> API 接口」頁面中找到相關資訊,點擊這裡登入後台。
瀏覽器支援
- IE(>=10) 和 Edge。
- 主流版本的 Chrome、Firefox、Safari。
- 以主流版本 Chrome 為核心的瀏覽器,如最新版本的 QQ 瀏覽器、360 瀏覽器等。
整合 SDK
您可以選擇以下任意一種方法呼叫本 SDK:
方法一:引入線上資源
<!-- 指定版本 -->
<script src="//player.polyv.net/resp/vod-upload-js-sdk/1.2.3.3/vod-upload-js-sdk.min.js"></script>
<!-- 注意,1.4.0版本或后续的版本, SDK的静态资源地址有变化 -->
<!-- 1.4.0或后续的指定版本 -->
<script src="https://websdk.videocc.net/vod-upload-js-sdk/1.12.0/vod-upload-js-sdk.min.js"></script>
<!-- 最新版本(推荐使用) -->
<script src="https://websdk.videocc.net/vod-upload-js-sdk/latest/vod-upload-js-sdk.min.js"></script>
方法二:透過 npm 安裝
第一步,在專案目錄下執行安裝指令:
npm install @polyv/vod-upload-js-sdk
第二步,在頁面中引入(需要建置工具支援):
import PlvVideoUpload from '@polyv/vod-upload-js-sdk'
// 此npm包默认采用commonjs2方式,如在项目中引入报错的话可更改成
import PlvVideoUpload from "@polyv/vod-upload-js-sdk/vod-upload-js-sdk.min.js";
或者
const PlvVideoUpload = require('@polyv/vod-upload-js-sdk');
// 此npm包默认采用commonjs2方式,如在项目中引入报错的话可更改成
const PlvVideoUpload = require('@polyv/vod-upload-js-sdk/vod-upload-js-sdk.min.js');
快速開始
初始化上傳實例
首先,建立 PlvVideoUpload 實例。
const videoUpload = new PlvVideoUpload({
region: 'line1', // auto:自动选择。根据IP的地区自动选择,当IP解析不出时使用默认值。
// line1(默认值):华南OSS bucket,对应ab-upload.polyv.net。
// line2:华北OSS bucket,对应ab-upload2.polyv.net。
events: {
Error: (err) => { // 错误事件回调
console.log(err);
},
UploadComplete: () => {} // 全部上传任务完成回调
}
});
呼叫 updateUserData() 設定帳號授權驗證資訊,並每隔 3 分鐘更新一次
// 授权验证信息3分钟内有效,当 sign 过期时需要调用该方法更新
videoUpload.updateUserData({
userid: <userid> , // Polyv云点播账号的ID
ptime: <timestamp> , // 时间戳
sign: <sign> , // 是根据将secretkey和ts按照顺序拼凑起来的字符串进行MD5计算得到的值(小写)
hash: <hash> , // 是根据将ts和writeToken按照顺序拼凑起来的字符串进行MD5计算得到的值(小写)
});
其中 ptime、sign 和 hash 都要從伺服器端取得,伺服器端的程式碼範例(PHP)如下:
/*
* userid、secretkey、writeToken 都可以在「云点播管理后台 -> 设置 -> API接口」页面中找到。
*/
$userid = "your userid";
$secretkey = "your sercrety";
$writeToken = "your writeToken";
$ptime = time() * 1000;
$sign = md5($secretkey . $ptime);
$hash = md5($ptime . $writeToken);
添加上傳檔案進入上傳列表
fileSetting = { // 文件上传相关信息设置
title: <title>, // 标题
desc: <desc>, // 描述
cataid: <cataid>, // 上传分类目录ID
tag: <tag>, // 标签
luping: 0, // 是否开启视频课件优化处理,对于上传录屏类视频清晰度有所优化:0为不开启,1为开启
keepsource: 0, // 是否源文件播放(不对视频进行编码):0为编码,1为不编码
state:<customMessage> //用户自定义信息,如果提交了该字段,会在服务端上传完成回调时透传返回。
};
呼叫 PlvVideoUpload 實例的 addFile(file, events, fileSetting) 方法,新增檔案到檔案列表,該方法回傳一個 UploadManager 物件:
var uploadManager = videoUpload.addFile(
file, // file 为待上传的文件对象
{
FileStarted: function(uploadInfo) { // 文件开始上传回调
console.log("文件上传开始: " + uploadInfo.fileData.title);
},
FileProgress: function(uploadInfo) { // 文件上传过程返回上传进度信息回调
console.log("文件上传中: " + (uploadInfo.progress * 100).toFixed(2) + '%');
},
FileStopped: function(uploadInfo) { // 文件暂停上传回调
console.log("文件上传停止: " + uploadInfo.fileData.title);
},
FileSucceed: function(uploadInfo) { // 文件上传成功回调
console.log("文件上传成功: " + uploadInfo.fileData.title);
// 视频vid:uploadInfo.fileData.vid
},
FileFailed: function(uploadInfo) { // 文件上传失败回调
console.log("文件上传失败: " + uploadInfo.fileData.title);
}
},
fileSetting
);
API 文件
註:由於業務需求,開源版本的程式碼和文件目前已不再更新,僅供參考。 請參閱原始碼中的 docs 資料夾或 點擊此處開啟。
範例程式碼
1、JS 範例
原始碼中的 demo 資料夾包含兩個範例:
- dev.html & dev.js:以模組化方式引入 SDK 的範例。需修改 build 資料夾下的 webpack.dev.config.js 檔案中的帳號資訊,然後在本專案根目錄下執行
npm run dev,開啟瀏覽器訪問http://127.0.0.1:14002/index.html即可。 - index.html & index.js:以 script 標籤引入 SDK 的範例。需修改 JS 檔案中的 getPolyvAuthorization 變數為有效的請求地址,才能正常使用。
2、Vue 範例
1、補充範例中的 userid、secretkey、writeToken 即可,在保利威點播後台 設定->API 接口 取得。
2、需安裝 element-ui 和 md5 依賴。
<template>
<div class="hello">
<div>
<input type="file" class="upload" @change="doUpload" ref="inputer" multiple />
<el-button type="primary" size="small" @click="startAll">全部开始</el-button>
<el-button type="warning" size="small" @click="pauseAll">全部暂停</el-button>
<el-button type="danger" size="small" @click="clearAll">全部删除</el-button>
</div>
<div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="id" label="ID" width="180">
</el-table-column>
<el-table-column prop="fileName" label="文件名" width="180">
</el-table-column>
<el-table-column prop="size" label="文件大小" width="180">
<template slot-scope="scope">{{ transformSize(scope.row.size)}}</template>
</el-table-column>
<el-table-column prop="progress" label="进度" width="180">
<template slot-scope="scope">
<el-progress :text-inside="true" :stroke-width="26" :percentage="scope.row.progress"></el-progress>
</template>
</el-table-column>
<el-table-column prop="progress" label="操作" width="180">
<template slot-scope="scope">
<el-button type="text" size="small" @click="start(scope.row.id)">开始</el-button>
<el-button type="text" size="small" @click="stop(scope.row.id)">暂停</el-button>
<el-button type="text" size="small" @click="remove(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import md5 from 'js-md5'
import PlvVideoUpload from '@polyv/vod-upload-js-sdk';
export default {
name: 'demo',
data() {
return {
videoUpload: null, // 视频上传实例
userid: '',//从点播后台查看获取
secretkey: '',//从点播后台查看获取
writeToken: '',//从点播后台查看获取
ptime: '', // 当前时间戳
tableData: [] //表格数据
}
},
created() {
this.videoUpload = new PlvVideoUpload({
region: 'line1', // (可选)上传线路, 默认line1
events: {
Error: (err) => { // 错误事件回调
console.log(err);
let errMag = `(错误代码:${err.code})${err.message}`;
this.$alert(errMag, '标题名称', {
confirmButtonText: '确定',
type: 'error',
});
},
UploadComplete: () => { // 全部上传任务完成回调
console.info('上传结束:', this.videoUpload);
console.log(this.tableData)
this.$message({
message: '全部上传任务完成',
type: 'success'
});
}
}
});
},
mounted() {
this.autoUpdateUserData(null, this.videoUpload);
},
methods: {
start(uploaderid) {// 单个上传
console.log(uploaderid)
this.videoUpload.resumeFile(uploaderid);
},
stop(uploaderid) {// 单个暂停
console.log(uploaderid)
this.videoUpload.stopFile(uploaderid);
},
remove(uploaderid) {// 单个删除
console.log(uploaderid)
this.videoUpload.removeFile(uploaderid);
this.tableData = this.tableData.filter((item) => item.id !== uploaderid)
},
startAll() {// 全部上传
if (this.videoUpload) {
this.videoUpload.startAll();
}
},
pauseAll() {// 全部暂停
if (this.videoUpload) {
this.videoUpload.stopAll();
}
},
clearAll() {// 全部删除
if (this.videoUpload) {
this.videoUpload.clearAll();
this.tableData = []
this.$refs.inputer.value =''
}
},
doUpload() {// 选择文件
let inputDOM = this.$refs.inputer; // 通过DOM取文件数据
console.log(inputDOM.files)
if (inputDOM.files.length > 0) {
inputDOM.files.forEach((file, index, arr) => {
let fileSetting = { // 文件上传相关信息设置
title: file.name, // 标题
desc: 'jssdk插件上传', // 描述
cataid: '', // 上传分类目录ID
tag: '', // 标签
luping: 0, // 是否开启视频课件优化处理,对于上传录屏类视频清晰度有所优化:0为不开启,1为开启
keepsource: 0, // 是否源文件播放(不对视频进行编码):0为编码,1为不编码
state: '' //用户自定义信息,如果提交了该字段,会在服务端上传完成回调时透传返回。
}
let uploadManager = this.videoUpload.addFile(
file, // file 为待上传的文件对象
{
FileStarted: this.onFileStarted,// 文件开始上传回调
FileProgress: this.onFileProgress,// 文件上传中回调
FileSucceed: this.onFileSucceed,// 文件上传成功回调
FileFailed: this.onFileFailed,// 文件上传失败回调
FileStopped: this.onFileStopped,// 文件上传停止回调
},
fileSetting
);
this.addTableData(uploadManager)
})
}
},
onFileStarted(data) {
console.log("文件上传开始: ", data);
this.tableData.filter((item) => item.id === data.uploaderid)[0].progress = 0
},
onFileProgress(data) {
let p = parseInt(data.progress * 100);// 上传的进度条
console.log("文件上传中: ", data);
this.tableData.filter((item) => item.id === data.uploaderid)[0].progress = p
},
onFileSucceed(data) {
console.log("文件上传成功: ", data);
// 视频vid:data.fileData.vid
},
onFileFailed(data) {
console.log("文件上传失败: ", data);
},
onFileStopped(data) {
console.log("文件上传停止: ", data);
},
addTableData(data) { // 增加表格数据
let obj = {
id: data.id,
fileName: data.fileData.title,
size: data.fileData.size,
progress: 0
}
this.tableData.push(obj)
},
autoUpdateUserData(timer, videoUpload) { // 启动获取用户信息
this.getUserData(videoUpload);
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
this.autoUpdateUserData(timer, videoUpload);
}, 3 * 50 * 1000);
},
getUserData() { // 获取用户详细信息
this.ptime = new Date().getTime()
let userData = {
userid: this.userid,
ptime: this.ptime,
sign: this.getSignData().sign,
hash: this.getSignData().hash
};
this.videoUpload.updateUserData(userData);
},
getSignData() { // 加密信息参数
let hash = md5(this.ptime + this.writeToken)
let sign = md5(this.secretkey + this.ptime)
return {
hash: hash,
sign: sign,
}
},
transformSize(bytes) {// 文件大小转换
const bt = parseInt(bytes);
let result;
if (bt === 0) {
result = '0B';
} else {
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bt) / Math.log(k));
if (typeof i !== 'number') {
result = '-';
} else {
result = (bt / Math.pow(k, i)).toFixed(2) + sizes[i];
}
}
return result;
}
},
}
</script>
<style scoped>
</style>
錯誤代碼
Error 事件已知錯誤類型:
| code | 描述 |
|---|---|
| 102 | 使用者剩餘空間不足 |
| 110 | 檔案重複 |
| 111 | 攔截檔案類型不在 acceptedMimeType 中的檔案 |
| 112 | 檔案已開始上傳或已上傳完畢,禁止修改檔案資訊 |
FileFailed 事件已知錯誤類型:
| type | code | 描述 |
|---|---|---|
| InitUploadError | 3001 | 分類不存在 |
| InitUploadError | 405 | 上傳影片初始化失敗 |
| InitUploadError | 406 | 影片大小不能為 0 |
| InitUploadError | 408 | 帳戶服務狀態異常,請聯絡客服 |
| MultipartUploadError | 斷點續傳時出錯 | |
| UpdateTokenError | 更新上傳 token 時取得 token 失敗 | |
| NoSuchUploadError | Multipart Upload ID 不存在 |
版本更新
v1.12.0
- 內部最佳化
- 修復頻繁呼叫介面 stopFile 導致任務佇列異常的情況
v1.10.1
- 最佳化大檔案上傳 token 更新的機制
v1.7.0
- 支援 .m4a 格式媒體檔案上傳
v1.6.0
- 修復線路授權過期重試異常的問題
v1.5.0
- 修復特定情況下斷點續傳異常的問題
v1.4.1
- 內部最佳化
- 預設線路問題修復
v1.3.0
- 上傳線路升級
v1.2.3
- 增加 region 參數
v1.2.2
- cataid 不存在時回傳提示。
- 規範 FileFailed 事件回傳的資料格式與欄位名稱。
v1.2.1
- 問題修復
v1.2.0
- 支援使用子帳號資訊上傳影片檔案
v1.1.3
- 最佳化檔案上傳失敗時的回調 message
v1.1.2
- 增加支援檔案名稱後綴大寫的檔案上傳,如 file_example.MP3
- 修改範例程式碼
v1.1.1
- 最佳化檔案上傳失敗時的重試邏輯
- 檔案上傳失敗時回傳的錯誤資訊中增加 errData 屬性
v1.1.0
- 增加對自訂資訊欄位的支援
