POLYV Video Upload SDK
The Polyv JavaScript Upload SDK provides a development toolkit for uploading media files to the Polyv Cloud Video Platform.
Features
- Quickly upload media files in various formats.
- Supports various upload settings, such as file title, description, tags, upload directory, and whether to enable courseware optimization processing.
- Defaults to chunked concurrent upload, supporting resumable upload.
Usage
Prerequisites
- Before using this SDK, you must first activate the Polyv Cloud Video Service. If you are not familiar with this service, please visit the product homepage for details: Cloud Video.
- Obtain the secretKey and other related information for user identity verification. You can find this information on the "Cloud Video Management Console -> Settings -> API Interface" page, click here to log in to the console.
Browser Support
- IE (>=10) and Edge.
- Current major versions of Chrome, Firefox, Safari.
- Browsers based on the current major version of Chrome, such as the latest versions of QQ Browser, 360 Browser, etc.
Integrating the SDK
You can choose any of the following methods to use this SDK:
Method 1: Include Online Resources
<!-- 指定版本 -->
<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>
Method 2: Install via npm
Step 1, run the installation command in your project directory:
npm install @polyv/vod-upload-js-sdk
Step 2, import it into your page (requires build tool support):
import PlvVideoUpload from '@polyv/vod-upload-js-sdk'
// 此npm包默认采用commonjs2方式,如在项目中引入报错的话可更改成
import PlvVideoUpload from "@polyv/vod-upload-js-sdk/vod-upload-js-sdk.min.js";
Or
const PlvVideoUpload = require('@polyv/vod-upload-js-sdk');
// 此npm包默认采用commonjs2方式,如在项目中引入报错的话可更改成
const PlvVideoUpload = require('@polyv/vod-upload-js-sdk/vod-upload-js-sdk.min.js');
Quick Start
Initialize the Upload Instance
First, create a PlvVideoUpload instance.
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: () => {} // 全部上传任务完成回调
}
});
Call updateUserData() to set the account authorization verification information, and update it every 3 minutes.
// 授权验证信息3分钟内有效,当 sign 过期时需要调用该方法更新
videoUpload.updateUserData({
userid: <userid> , // Polyv云点播账号的ID
ptime: <timestamp> , // 时间戳
sign: <sign> , // 是根据将secretkey和ts按照顺序拼凑起来的字符串进行MD5计算得到的值(小写)
hash: <hash> , // 是根据将ts和writeToken按照顺序拼凑起来的字符串进行MD5计算得到的值(小写)
});
Where ptime, sign, and hash must all be obtained from the server. A server-side code example (PHP) is as follows:
/*
* userid、secretkey、writeToken 都可以在「云点播管理后台 -> 设置 -> API接口」页面中找到。
*/
$userid = "your userid";
$secretkey = "your sercrety";
$writeToken = "your writeToken";
$ptime = time() * 1000;
$sign = md5($secretkey . $ptime);
$hash = md5($ptime . $writeToken);
Add Files to the Upload List
fileSetting = { // 文件上传相关信息设置
title: <title>, // 标题
desc: <desc>, // 描述
cataid: <cataid>, // 上传分类目录ID
tag: <tag>, // 标签
luping: 0, // 是否开启视频课件优化处理,对于上传录屏类视频清晰度有所优化:0为不开启,1为开启
keepsource: 0, // 是否源文件播放(不对视频进行编码):0为编码,1为不编码
state:<customMessage> //用户自定义信息,如果提交了该字段,会在服务端上传完成回调时透传返回。
};
Call the addFile(file, events, fileSetting) method of the PlvVideoUpload instance to add a file to the file list. This method returns a UploadManager object:
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 Documentation
Note: Due to business requirements, the code and documentation for the open-source version are no longer being updated and are for reference only. See the docs folder in the source code or click here.
Example Code
1. JS Example
The demo folder in the source code contains two examples:
- dev.html & dev.js: An example of importing the SDK in a modular way. You need to modify the account information in the webpack.dev.config.js file under the build folder, then run
npm run devin the project root directory, and open your browser to accesshttp://127.0.0.1:14002/index.html. - index.html & index.js: An example of importing the SDK via a script tag. You need to modify the
getPolyvAuthorizationvariable in the JS file to a valid request address for normal use.
2. Vue Example
- Fill in the userid, secretkey, and writeToken from the example. These can be obtained from the Polyv Cloud Video Management Console under Settings -> API Interface.
- You need to install the element-ui and md5 dependencies.
<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 Codes
Known error types for the Error event:
| code | Description |
|---|---|
| 102 | Insufficient user storage space |
| 110 | Duplicate file |
| 111 | File type intercepted, not in acceptedMimeType |
| 112 | File upload has already started or completed, modification of file info is prohibited |
Known error types for the FileFailed event:
| type | code | Description |
|---|---|---|
| InitUploadError | 3001 | Category does not exist |
| InitUploadError | 405 | Video upload initialization failed |
| InitUploadError | 406 | Video size cannot be 0 |
| InitUploadError | 408 | Account service status abnormal, please contact customer service |
| MultipartUploadError | Error during resumable upload | |
| UpdateTokenError | Failed to obtain token when updating upload token | |
| NoSuchUploadError | Multipart Upload ID does not exist |
Version History
v1.12.0
- Internal optimizations
- Fixed an issue where frequently calling the
stopFileinterface caused abnormal task queues
v1.10.1
- Optimized the token update mechanism for large file uploads
v1.7.0
- Added support for uploading .m4a format media files
v1.6.0
- Fixed an issue with abnormal retry after line authorization expiration
v1.5.0
- Fixed an issue with abnormal resumable upload under specific circumstances
v1.4.1
- Internal optimizations
- Fixed default line issues
v1.3.0
- Upload line upgrade
v1.2.3
- Added region parameter
v1.2.2
- Returns a prompt when cataid does not exist.
- Standardized the data format and field names returned by the FileFailed event.
v1.2.1
- Bug fixes
v1.2.0
- Added support for uploading video files using sub-account information
v1.1.3
- Optimized the callback message when file upload fails
v1.1.2
- Added support for uploading files with uppercase file name extensions, e.g., file_example.MP3
- Modified example code
v1.1.1
- Optimized the retry logic when file upload fails
- Added the
errDataattribute to the error information returned when file upload fails
v1.1.0
- Added support for custom information fields
