这段时间公司要做一个把上传的ppt文件转换成为一组jpg文件的功能,我查了查资料,发现可以使用libreoffice先把ppt转成pdf,然后再用imagemagick把pdf转换成为jpg来实现,在机子上测试了一下,的确可行,但是服务搭建起来挺麻烦的,还得考虑解决libreoffice字体的问题。后来翻了翻七牛的服务,正好发现他们提供了这样的服务(其实是属于亿方云提供的,不过接入了七牛),而且正好我们的上传数据也在七牛上,这倒是省事儿了,直接决定了使用该服务。
怎么开启这个服务就不在这里说了,文档上写的也算明白,可能会令人感到困惑的地方是,这个服务要怎么调用的问题了。现在回过头来看,其实调用的方法很直观,很容易。不过当时我对七牛那里的“预转持久化处理”和“持久化数据处理”是完全没有概念的,看到文档上给出的调用方式完全是束手无策,所以还是记录在这里以后忘了可以来查。
估计在开发的时候大家都会使用七牛提供的SDK,所以这里就假设大家已经弄到了七牛的SDK了,这里先说下“预转持久化处理”是一个什么样的东西吧,这里直接上代码可能更好理解一些,我用的是PHP开发的。
require 'qiniu/sdk/autoload.php'; //引入七牛SDK
use Qiniu\Auth; //引入要使用的类
$accessKey = 'YOUR_ACCESSKEY'; //你的ACCESSKEY
$secretKey = 'YOUR_SECRETKEY'; //你的SECRETKEY
$bucket = 'BUCKET_NAME'; //你要上传到的那个储存空间的名字
$auth = new Auth($accessKey, $secretKey);
$policy = [
'persistentOps' => 'yifangyun_preview/v2/format=jpg',
'persistentNotifyUrl' => 'YOUR_NOTIFY_URL'
];
$token = $auth->uploadToken($bucket, null, 7200, $policy);
以上差不多就是代码的全部了,最后我们获取到了一个token,然后拿着这个token去上传文件就行了,上传后的ppt文件就会自动转换成jpg文件,转换完成后,七牛那边就会把转换的结果通知给'persistentNotifyUrl'中填写的那个URL,这里我们还可以在$policy中加上'persistentPipeline'这个项目来指定私有的队列(Pipeline),如果不指定私有队列而是用默认的公有队列的话,可能要等上很久才能轮到你这个文件去转换,也就是说,$policy如果可能的话,最好变成这个样子:
$policy = [
'persistentOps' => 'yifangyun_preview/v2/format=jpg',
'persistentNotifyUrl' => 'YOUR_NOTIFY_URL',
'persistentPipeline' => 'YOUR_PIPELINE_NAME'
];
可能大家还会比较关心一个问题就是七牛在转换完成后,到底给我填写的persistentNotifyUrl发送了什么数据,这里我把我收到的数据贴在这里,仅供参考:
{
"id": "z0.57c6a3927823de7b57af9380",
"pipeline": "1380310700.myline",
"code": 0,
"desc": "The fop was completed successfully",
"reqid": "fjMAACOHKeiB2m8U",
"inputBucket": "sbin-media",
"inputKey": "o_1arfrhrfak9g1i1f16qkqb1ncc9.ppt",
"items": [
{
"cmd": "yifangyun_preview/v2/format=jpg",
"code": 0,
"desc": "The fop was completed successfully",
"hash": "FlR93trssv4f236bwTLH-93Lsg6R",
"key": "o_1arfrhrfak9g1i1f16qkqb1ncc9.2.jpg",
"keys": [
"o_1arfrhrfak9g1i1f16qkqb1ncc9.9.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.1.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.12.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.20.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.13.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.19.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.16.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.8.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.6.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.17.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.11.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.22.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.23.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.18.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.10.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.21.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.27.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.7.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.3.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.5.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.24.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.4.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.26.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.25.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.15.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.14.jpg",
"o_1arfrhrfak9g1i1f16qkqb1ncc9.2.jpg"
],
"returnOld": 0
}
]
}
基本上我想要的东西都返回回来了,不过因为业务需要,我还是不能使用“预转持久化处理”这种方式的,我得“手动控制”转换的时间和条件,防止产生一些垃圾数据,所以“持久化数据处理”的方式对我来说更合适,至于什么是“持久化数据处理”的方式,还是直接贴代码吧。
require 'qiniu/sdk/autoload.php'; //引入七牛SDK
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop; //引入要使用的类
$accessKey = 'YOUR_ACCESSKEY'; //你的ACCESSKEY
$secretKey = 'YOUR_SECRETKEY'; //你的SECRETKEY
$bucket = 'BUCKET_NAME'; //你要上传到的那个储存空间的名字
$key = 'YOUR_FILE_KEY'; //就是你在上传后那个文件的名字,一般会在上传成功后返回
$auth = new Auth($accessKey, $secretKey);
$pfop = new PersistentFop($auth, $bucket, 'YOUR_PIPELINE_NAME', 'YOUR_NOTIFY_URL');
$fops = 'yifangyun_preview/v2/format=jpg';
$pfop->execute($key, $fops);
其实仔细看看的话,这种方式需要的参数和“预转持久化处理”所需要的参数差不多,只不过放的位置不太一样罢了,而且也没有获取token(引入的类中有没有干这事儿我还得再看看,至少这段代码中没有明显的token),所以可以在文件上传之后,再调用这段代码,然后等着七牛那边通知吧。
还有一点需要注意的就是只有存储区域为华东的储存空间才能使用这个文档转换服务,这个坑刚开始卡了我好久,再从头开始读文档的过程中才了解到这个问题。
其实在使用的过程中,还有一个坑是我想吐槽的地方,但是在看“预转持久化处理”和“持久化数据处理”这两个概念的时候,官方给的例子是这样的
"persistentOps":"avthumb/mp4;avthumb/m3u8/noDomain/1/segtime/15/vb/440k",
让我以为这种命令必须是"参数1/值1/参数2/值2/参数3/值3"这样的格式,然而文档转换服务给出的请求方法是这样的
yifangyun_preview/v2
/ext=<Ext>
/action=<Action>
/format=<DestFormat>
/page_number=<PageNumber>
也就是说是"参数1=值1/参数2=值2/参数3=值3"这样的格式,我一度以为是不是这个文档给错了,然后还是按照"参数1/值1/参数2/值2/参数3/值3"这样的格式去请求,坑了不少时间。