UNPKG

vedio

Version:

Ali cloud video on demand SDK

433 lines (391 loc) 11.7 kB
var OSS = require('ali-oss') var crypto = require('crypto') var querystring = require('querystring') var request = require('request') var fs = require('fs') var rp = require('request-promise'); var AliCloudVideo = function (options) { // 定义默认配置 this._options = { AccessKeyId: '', // 必填 AccessKeySecret: '', // 必填 Format: 'JSON', Version: '2017-03-21', SignatureMethod: 'HMAC-SHA1', SignatureVersion: '1.0' } this.BASE_URL = 'https://vod.cn-shanghai.aliyuncs.com' // 传入的配置优先级高于默认 Object.assign(this._options, options) // 检查默认为空的是否有填充 var isPass = this._checkOptions(this._options) if (!isPass) { throw new Error('please check the params!') } } AliCloudVideo.prototype = { /** * 获取视频点播auth参数 * @param {string} videoId 视频上传后得到的id * @param {Function} callback */ getPlayAuth: function (videoId, callback) { if (typeof videoId !== 'string') { return callback(new TypeError('getPlayAuth() first argument must be a String')) } var url = this._getUrl({ Action: 'GetVideoPlayAuth', VideoId: videoId }) this.request(url, callback) }, getPlayAddress: function (options, callback) { var videoId = options.VideoId if (typeof videoId !== 'string') { return callback(new TypeError('getPlayAddress() VideoId must be a String')) } var newOptions = { Action: 'GetPlayInfo', VideoId: videoId } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['Formats', 'AuthTimeout'] }) var url = this._getUrl(newOptions) this.request(url, callback) }, /** * 上传视频前先获取上传地址和上传凭证 * @param {object} options 配置参数 * @param {Function} callback */ getUploadAuth: function (options, callback) { if (typeof options !== 'object') { return callback(new TypeError('getUploadAuth() first argument must be an Object')) } var title = 'new_video_' + Date.now() var newOptions = { Action: 'CreateUploadVideo', Title: options.Title || title, FileName: options.FileName || title + '.mp4' } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['FileSize', 'Description', 'CoverURL', 'CateId', 'Tags'] }) var url = this._getUrl(newOptions) console.log(url) const obj = { uri: 'https://vod.cn-shanghai.aliyuncs.com', qs: url, headers: { 'User-Agent': 'Request-Promise' }, json: true } console.log(obj); rp(obj).then(function(repos) { console.log('User has %d repos', repos.length); }).catch(function(err){ console.log(err) }) }, /** * 上传视频凭证失效后需刷新凭证 * @param {string} videoId 视频id * @param {Function} callback */ refreshUploadAuth: function (videoId, callback) { if (typeof videoId !== 'string') { return callback(new TypeError('refreshUploadAuth() required a String videoId')) } var url = this._getUrl({ Action: 'RefreshUploadVideo', VideoId: videoId }) this.request(url, callback) }, /** * 上传图片前先获取上传地址和上传凭证 * @param {string} options 配置参数 * @param {Function} callback */ getUploadImageAuth: function (options, callback) { if (typeof options !== 'object') { return callback(new TypeError('getUploadImageAuth first argument must be an Object')) } var newOptions = { Action: 'CreateUploadImage', ImageType: options.ImageType || 'cover' } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['ImageExt'] }) var url = this._getUrl(newOptions) this.request(url, callback) }, uploadFile: function (options, callback) { var filePath = options.FilePath delete options.FilePath if (typeof filePath !== 'string') { return callback(new TypeError('uploadFile() FilePath must be a String')) } var progress = function () {} if (typeof options.progress === 'function') { progress = options.progress delete options.progress } var that = this fs.access(filePath, function (err) { if (err) { return callback(err) } that.getUploadAuth(options, function (err, result) { if (err) { return callback(err) } var VideoId = result.VideoId var UploadAddress = result.UploadAddress var UploadAuth = result.UploadAuth var addressObj = null var authObj = null try { addressObj = JSON.parse(Buffer.from(UploadAddress, 'base64')) authObj = JSON.parse(Buffer.from(UploadAuth, 'base64')) } catch(err) { return callback(err) } var config = { accessKeyId: authObj.AccessKeyId, accessKeySecret: authObj.AccessKeySecret, endpoint: addressObj.Endpoint, stsToken: authObj.SecurityToken, bucket: addressObj.Bucket } var oss = new OSS.Wrapper(config) oss.multipartUpload(addressObj.FileName, filePath, { progress: function (p) { return function (done) { progress(p) done() } } }).then(result => { callback(null, VideoId) }).catch(callback) }) }) }, deleteFiles: function (videos, callback) { if (!(videos instanceof Array)) { return callback(new TypeError('deleteFile() first argument must be an Array')) } var newOptions = { Action: 'DeleteVideo', VideoIds: videos.join(',') } var url = this._getUrl(newOptions) this.request(url, callback) }, getVideoInfo: function (videoId, callback) { if (typeof videoId !== 'string') { return callback(new TypeError('getVideoInfo() first argument must be a String')) } var newOptions = { Action: 'GetVideoInfo', VideoId: videoId } var url = this._getUrl(newOptions) this.request(url, callback) }, getVideoList: function (options, callback) { var newOptions = { Action: 'GetVideoList' } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['Status', 'StartTime', 'EndTime', 'CateId', 'PageNo', 'PageSize', 'SortBy'] }) var url = this._getUrl(newOptions) this.request(url, callback) }, updateVideoInfo: function (options, callback) { var videoId = options.VideoId if (typeof videoId !== 'string') { return callback(new TypeError('updateVideoInfo() VideoId must be a String')) } var newOptions = { Action: 'UpdateVideoInfo', VideoId: videoId } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['Title', 'Description', 'CoverURL', 'CateId', 'Tags'] }) var url = this._getUrl(newOptions) this.request(url, callback) }, addCategory: function (options, callback) { var cateName = options.CateName if (typeof cateName !== 'string') { return callback(new TypeError('addCategory() CateName must be a String')) } var newOptions = { Action: 'AddCategory', CateName: cateName } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['ParentId'] }) var url = this._getUrl(newOptions) this.request(url, callback) }, getCategories: function (options, callback) { if (typeof options !== 'object') { return callback(new TypeError('GetCategories() first argument must be an Object')) } var newOptions = { Action: 'GetCategories' } this.copyFieldIfExists({ target: newOptions, source: options, fields: ['CateId', 'PageNo', 'PageSize'] }) var url = this._getUrl(newOptions) this.request(url, callback) }, updateCategory: function (options, callback) { var cateId = options.CateId var cateName = options.CateName if (typeof cateId !== 'string') { return callback(new TypeError('updateCategory() CateId must be a String')) } if (typeof cateName !== 'string') { return callback(new TypeError('updateCategory() cateName must be a String')) } var newOptions = { Action: 'UpdateCategory', CateId: cateId, CateName: cateName } var url = this._getUrl(newOptions) this.request(url, callback) }, deleteCategory: function (cateId, callback) { if (typeof cateId !== 'string') { return callback(new TypeError('deleteCategory() first argument must be a String')) } var newOptions = { Action: 'DeleteCategory', CateId: cateId } var url = this._getUrl(newOptions) this.request(url, callback) }, request: function (url, callback) { var that = this request(url, function (err, response, body) { if (err) { return callback(err) } if (that._options.Format === 'XML') { return callback(null, body) } try { body = JSON.parse(body) } catch (err) { return callback(err) } if (body.Message) { return callback(new Error(body.Message)) } callback(null, body) }) }, copyFieldIfExists: function (options) { var fields = options.fields var target = options.target var source = options.source fields.forEach(function (field) { var value = source[field] if (typeof value === 'string') { target[field] = value } }) }, // 检查是否有漏填的选项 _checkOptions: function (options) { options = options || this._options for (let key in options) { if (!options[key]) { return false } } return true }, /** * 生成格式化时间字符串 * @return {string} 格式化时间 */ _generateTimestamps: function () { return new Date().toISOString() }, /** * 生成随机字符串 * @return {string} 随机字符串 */ _generateNonce: function () { return Date.now() + '' + parseInt(Math.random() * 10000) }, /** * 传入配置,返回结合公共配置生成的对象 * @param {object} options 配置对象 * @return {object} 新的配置对象 */ _getOptions: function (options) { var newOptions = Object.assign({}, this._options, options) newOptions.Timestamp = this._generateTimestamps() newOptions.SignatureNonce = this._generateNonce() return newOptions }, /** * 传入配置对象,通过编码、排序、加密过程生成signature * @param {object} options 配置对象 * @return {string} signature */ _generateSignature: function (options) { var query = [] for (var key in options) { query.push(encodeURIComponent(key) + '=' + encodeURIComponent(options[key])) } query.sort() var str = query.join('&') var stringToSign = 'GET&%2F&' + encodeURIComponent(str) var signature = crypto .createHmac('sha1', this._options.AccessKeySecret + '&') .update(stringToSign) .digest('base64') return signature }, /** * 生成最终访问url * @param {object} options 配置对象 * @return {string} 最终访问url */ _getUrl: function (options) { var newOptions = this._getOptions(options) newOptions.Signature = encodeURIComponent(this._generateSignature(newOptions)) return newOptions } } module.exports = AliCloudVideo