node-qiniu-sdk
Version:
nodejs,七牛云异步操作模块
391 lines (333 loc) • 14.6 kB
JavaScript
const fs = require('fs');
const rp = require('./request');
const Auth = require('qiniu-auth');
const Extends = require('./extends');
const debug = require('debug')('qiniu-sdk');
/**
* 视频三鉴
* 官方文档:https://developer.qiniu.com/dora/manual/4258/video-pulp
* @param {String} options.vid 调用者设置的视频唯一标识,异步处理的返回结果中会带上该信息
* @param {qiniu} options.sdk 本模块的实例
* @param {Object} options.body 请求参数,参数细节请看官网API
*/
exports.review = function(options){
if (!options) return Promise.reject('options is required');
if (!options.vid) return Promise.reject('options.vid is required');
if (!options.body) return Promise.reject('options.body is required');
if (!options.sdk) return Promise.reject('options.sdk is required');
// 构造请求参数和获取http请求鉴权
let request_options = {
url: 'http://ai.qiniuapi.com/v1/video/' + options.vid,
method: 'POST',
host: 'ai.qiniuapi.com',
path: '/v1/video/' + options.vid,
body: options.body,
headers: {
'Content-Type': 'application/json',
'Authorization': null
}
};
request_options.headers.Authorization = Auth.qiniu_token.call(options.sdk, request_options);
return rp(request_options);
};
/**
* 获取单个视频的识别结果或者获取处理任务列表
* 官方文档:https://developer.qiniu.com/dora/manual/4258/video-pulp
* @param {String} job_id 指定job_id获取单个视频的识别结果
* @param {String} status 可选,任务状态 WAITING/DOING/RESCHEDULED/FAILED/FINISHED,RESCHEDULED是指等待重试中
* @param {qiniu} sdk 本模块实例
*/
exports.jobs = function(options){
if (!options) return Promise.reject('options is required');
if (!options.sdk) return Promise.reject('options.sdk is required');
// 构造请求参数
let request_options = {
method: 'GET',
host: 'ai.qiniuapi.com',
headers: {
'Content-Type': 'application/json',
'Authorization': null
}
};
// 构建path和url参数
if (options.job_id) {
// 指定job_id后获取单个任务状态
request_options.path = '/v1/jobs/video/' + options.job_id;
} else {
// 不指定任务返回所有任务状态
request_options.path = '/v1/jobs/video';
// 指定status返回相应状态的任务
if (options.status) {
request_options.path += '?status=' + options.status;
}
}
request_options.url = 'http://ai.qiniuapi.com' + request_options.path;
// 生成HTTP 请求鉴权
request_options.headers.Authorization = Auth.qiniu_token.call(options.sdk, request_options);
debug('video.job 请求参数:%S', request_options);
return rp(request_options);
};
/**
* 锐智转码
* 官方文档:https://developer.qiniu.com/dora/manual/5135/avsmart#3
*/
exports.avsmart = function(options){
if (!options) return Promise.reject('options is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
// format默认是mp4
options.format = options.format || 'mp4';
options.oau = options.oau || '0';
// 构建fops参数
let fops = 'avsmart/' + options.format + '/oau/' + options.oau;
// 忽略压缩视频体积时的错误,1为忽略,0为不忽略。如果没能压缩视频大小, 则忽略该错误并且返回原视频
if (options.ignoreError) {
fops += '/ignore-error/' + options.ignoreError
}
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 普通音视频转码
* 官方文档:https://developer.qiniu.com/dora/manual/1248/audio-and-video-transcoding-avthumb
* 现在视频水印功能已经和转码avthumb功能合并,可以同时转码以及做水印。
*/
exports.avthumb = function(options){
if (!options) return Promise.reject('options is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
if (!options.format) return Promise.reject('options.format is required');
// 构建fops参数
let fops;
try {
fops = Extends.AV.getAvthumbFops('avthumb', options);
} catch (error) {
return Promise.reject(error);
}
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
debug('avthumb fops: s%', fops);
return options.pfop(fops);
};
/**
* 音视频分段
* 官方文档:https://developer.qiniu.com/dora/manual/4154/dora-segment
*/
exports.segment = function(options){
if (!options) return Promise.reject('options is required');
if (!options.format) return Promise.reject('options.format is required');
if (!options.pattern) return Promise.reject('options.pattern is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
// 构建fops参数
let fops = 'segment/' + options.format + '/pattern/' + Auth.urlsafe_base64_encode(options.pattern);
if (options.segtime) {
fops += '/segtime/' + options.segtime;
}
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 音视频切片(HLS)
* 官方文档:https://developer.qiniu.com/dora/manual/1485/audio-and-video-slice
*/
exports.hls = function(options){
if (!options) return Promise.reject('options is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
// 默认为 0
options.noDomain = options.noDomain || '0';
// 构建fops参数
let fops;
try {
fops = Extends.AV.getAvthumbFops('avthumb/m3u8', options);
} catch (error) {
return Promise.reject(error);
}
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 视频水印
* 官方文档:https://developer.qiniu.com/dora/manual/1314/video-watermarking
* 现在视频水印功能已经和转码avthumb功能合并,可以同时转码以及做水印。
*/
exports.watermark = exports.avthumb;
/**
* 音视频拼接
* 官方文档:https://developer.qiniu.com/dora/manual/1246/audio-and-video-stitching-avconcat
* 音视频拼接接口(avconcat)用于将指定的数个音频片段拼接成一段音频,或者将数个视频片段拼接成一段视频。
*/
exports.concat = function(options){
if (!options) return Promise.reject('options is required');
if (!options.format) return Promise.reject('options.format is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
if (!Array.isArray(options.urls)) return Promise.reject('options.urls is invalid');
// mode默认是2
options.mode = options.mode || '2';
// index默认是1
options.index = options.index || '1';
// 构建fops参数
let fops = 'avconcat/' + options.mode + '/index/' + options.index + '/format/' + options.format;
options.urls.forEach(item => {
fops += Auth.urlsafe_base64_encode(item);
});
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 音视频元信息
* 官方文档:https://developer.qiniu.com/dora/manual/1247/audio-and-video-metadata-information-avinfo
* 音视频元信息接口(avinfo)用于获取指定音频、视频资源的元信息。
*/
exports.avinfo = function(url){
return rp({ url: url + '?avinfo' });
};
/**
* 视频帧缩略图
* 官方文档:https://developer.qiniu.com/dora/manual/1313/video-frame-thumbnails-vframe
* 视频帧缩略图接口(vframe)用于从视频流中截取指定时刻的单帧画面并按指定大小缩放成图片。
*/
exports.vframe = function(options){
if (!options) return Promise.reject('options is required');
if (!options.format) return Promise.reject('options.format is required');
if (!options.offset) return Promise.reject('options.offset is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
// 构建fops参数
let fops = 'vframe/' + options.format + '/offset/' + options.offset;
if (options.w) fops += '/w/' + options.w;
if (options.h) fops += '/h/' + options.h;
if (options.rotate) fops += '/rotate/' + options.rotate;
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 视频采样缩略图
* 官方文档:https://developer.qiniu.com/dora/manual/1315/video-sampling-thumbnails-vsample
* 视频采样缩略图接口(vsample)用于从视频文件中截取多帧画面并按指定大小缩放成图片。
*/
exports.vsample = function(options){
if (!options) return Promise.reject('options is required');
if (!options.format) return Promise.reject('options.format is required');
if (typeof options.ss === 'undefined') return Promise.reject('options.ss is required');
if (typeof options.t === 'undefined') return Promise.reject('options.t is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
// 构建fops参数
let fops = 'vsample/' + options.format + '/ss/' + options.ss + '/t/' + options.t;
if (options.s) fops += '/s/' + options.s;
if (options.rotate) fops += '/rotate/' + options.rotate;
if (options.interval) fops += '/interval/' + options.interval;
if (options.pattern) fops += '/pattern/' + Auth.urlsafe_base64_encode(options.pattern);
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 实时音视频转码
* 官方文档:https://developer.qiniu.com/dora/manual/1249/real-time-audio-and-video-transcoding-avvod
* 实时音视频转码(avvod)用于对已经上传到七牛云的音频、视频,在终端播放时按照指定参数进行实时转码。注意:该功能目前支持华东和华北的 bucket。
*/
exports.avvod = function(options){
if (!options) return Promise.reject('options is required');
options.format = options.format || 'm3u8';
// 构建fops参数
let fops = 'avvod/' + options.format;
if (options.ab) fops += '/ab/' + options.ab;
if (options.aq) fops += '/aq/' + options.aq;
if (options.ar) fops += '/ar/' + options.ar;
if (options.r) fops += '/r/' + options.r;
if (options.vb) fops += '/vb/' + options.vb;
if (options.vcodec) fops += '/vcodec/' + options.vcodec;
if (options.acodec) fops += '/acodec/' + options.acodec;
if (options.s) fops += '/s/' + options.s;
if (options.autosave) fops += '/autosave/' + options.autosave;
// 返回实时音视频转码(avvod)的url或fops参数
return options.url? url + '?' + fops : fops;
};
/**
* 多码率自适应转码
* 官方文档:https://developer.qiniu.com/dora/manual/1245/multiple-rate-adaptive-transcoding-adapt
* 多码率自适应转码(adapt)用于对已经上传到七牛云的视频转码成包含多种码率的HLS视频流。以便能随着终端网络带宽的变化动态选择适应的码率播放。
*/
exports.adapt = function(options){
if (!options) return Promise.reject('options is required');
if (!options.envBandWidth) return Promise.reject('options.envBandWidth is required');
if (!options.pfop) return Promise.reject('options.pfop is required');
options.format = options.format || 'm3u8';
// 构建fops参数
let fops = 'adapt/' + options.format + '/envBandWidth/' + options.envBandWidth;
if (options.multiAb) fops += '/multiAb/' + options.multiAb;
if (options.multiVb) fops += '/multiVb/' + options.multiVb;
if (options.multiResolution) fops += '/multiResolution/' + options.multiResolution;
if (options.multiPrefix) {
fops += '/multiPrefix/' + options.multiPrefix.map(item => Auth.urlsafe_base64_encode(item)).join(',');
}
if (options.vb) fops += '/vb/' + options.vb;
if (options.ab) fops += '/ab/' + options.ab;
if (options.resolution) fops += '/resolution/' + options.resolution;
if (options.hlstime) fops += '/hlstime/' + options.hlstime;
// 如果有saveas需要曾加saveas操作
if (options.saveas) {
if (typeof options.saveas === 'object') {
options.saveas = options.saveas.bucketName + ':' + options.saveas.fileName;
}
fops += '|saveas/' + Auth.urlsafe_base64_encode(options.saveas);
}
return options.pfop(fops);
};
/**
* 私有M3U8
* 官方文档:https://developer.qiniu.com/dora/manual/1292/private-m3u8-pm3u8
* pm3u8 接口只能用于私有空间中的 m3u8 文件,作用是对 m3u8文件中的 ts 资源进行批量下载授权。通过将 ts 资源的 url 改写成私有 url,以临时获取访问权限。
*/
exports.pm3u8 = function(options){
if (!options) return Promise.reject('options is required');
if (!options.url) return Promise.reject('options.url is required');
if (!options.qiniu) return Promise.reject('options.qiniu is required');
if (!options.pipe && !options.path) return Promise.reject('options.pipe and options.path have at least one');
let pipe = options.pipe || fs.createWriteStream(options.path);
let M3U8DownloadURI = Auth.download_token.call(options.qiniu, options);
// 默认是0
options.mode = options.mode || '0';
// 构建fops参数
let fops = 'pm3u8/' + options.mode;
if (options.expires) fops += '/expires/' + options.expires;
if (options.deadline) fops += '/deadline/' + options.deadline;
return rp({ url: M3U8DownloadURI + '&' + fops, pipe: pipe });
};