背景
业务需求,产品希望通过后台接口上传视频后,能立即获取视频切片的地址。然后将地址插入到相关业务的表中。
但是七牛的视频处理(切片、转码等)是异步执行,那么如何才能直接获取到经过七牛视频处理后的资源地址呢?
解决思路
在做七牛普通上传的 token
时,我们可以提前设定上传后的文件名(key)。当前端向后端获取token时,一并将资源地址和token返回前端。前端利用 token
进行文件直传到CDN,上传成功后,将已获得的资源地址进行相关业务处理(资源地址上报等)。
那么,可以不可以将类似的思路,复用到带数据处理的token生成中。
我们在生成token的时,将两种文件名(源资源文件名和经处理的资源名)信息保存到token中。前端在获取token时,提前获取到文件访问地址。
但是有一个问题,音视频处理是一个很耗时的操作,不像文件直传CDN进行保存,可以立即得到反馈。那么,如何确定视频处理成功呢?可以通过直传返回的persistentId
,定期轮询「持久化处理状态查询接口」。来判断是否处理完毕。
步骤
Step1 生成带数据处理的凭证
const qiniu = require("qiniu");
const accessKey = 'XXXXX';
const secretKey = '私钥XXX';
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const bucket = '存储空间名';
const origin_filename = 'prTEDwvJY18YBD_720_p1.mp4';
const save_as_filename = 'hls_prTEDwvJY18YBD_720_p1.m3u8';
const save_hls_entry = qiniu.util.urlsafeBase64Encode(`${bucket}:${save_as_filename}`);
const avthumbMp4Fop = `avthumb/m3u8/noDomain/1/segtime/15/vb/440k|saveas/${save_hls_entry}`;
const options = {
scope: `${bucket}:${origin_filename}`,
persistentOps: avthumbMp4Fop,
persistentPipeline: 'video_pipeline',
};
var putPolicy = new qiniu.rs.PutPolicy(options);
console.log(putPolicy.uploadToken(mac));
Step2 前端使用token直传CDN
POST http://up.qiniu.com
格式: form-data
参数:
key: 文件名,上文代码中的 `origin_filename`
token: 上传token
file: 具体文件
// 上传成功的响应体
// 状态码 200
{
"hash": "luVJbz9RtE3Ha7c9XaDerE6rPyvP",
"key": "prTEDwvJY18YBD_720_p1.mp4",
"persistentId": "z0.5b56c9b938b9f324a573edb4" // 可以使用persistentId,检测当前处理状态
}
Step3 轮询检测当前作业处理状态
GET api.qiniu.com/status/get/prefop?id=${persistentId}
{
"code": 0, // 状态码0成功,1等待处理,2正在处理,3处理失败,4通知提交失败。
"desc": "The fop was completed successfully",
"id": "z0.5b56c9b938b9f324a573edb4",
"inputBucket": "ocean",
"inputKey": "prTEDwvJY18YBD_720_p1.mp4",
"items": [
{
"cmd": "avthumb/m3u8/noDomain/1/segtime/15/vb/440k|saveas/b2NlYW46aGxzX3ByVEVEd3ZKWTE4WUJEXzcyMF9wMS5tM3U4",
"code": 0,
"desc": "The fop was completed successfully",
"hash": "FraV6PX6Xp7mYYgAnY0sniTK-pPt",
"key": "hls_prTEDwvJY18YBD_720_p1.m3u8",
"returnOld": 0
}
],
"pipeline": "1381326751.k12_video",
"reqid": "FQIAAKAxpZfFOkQV"
}