经过

我们最近的一次开发过程中,发现存在如下一个问题:iOS上传的视频是MOV格式的,Android上传的视频是MP4格式的,本来iOS和Android之间视频是相互兼容的,也就是iOS端也可以播放Andorid的mp4格式的视频,Android也可以播放iOS端MOV格式的视频,本来相安无事,最近因为需要做分享,做成H5分享成Web页面,那么Web页面就需要兼容MOV和MP4两种格式的视频,查了一下,发现H5的video 标签是默认不支持MOV格式的视频的,因此有如下几种方式去实现:

  1. 开发兼容MOV格式的VideoPlayer,这种最简单,移动端和后端都不需要更改代码;
  2. iOS端口在上传时,自行将MOV格式转码为MP4格式,这样也只需要iOS大改;
  3. 后端直接进行转码,直接将MOV格式的视频转码为MP4,这样可以做到前端无感。

思前想后这三种方案之后,由于历史原因和工期比较紧,因此我们采用了第三种方式,直接在后端进行转码,对前端无感发布。所幸我们使用的存储服务是七牛云,这次转存需求非常顺利,因此就记录下来,希望帮助到有需要的人。

准备阶段

首先,我们现在的需求是稍微有些尴尬的,是因为我们七牛云存储库里面已经存在了大量的MOV文件了,那么这里的转码就存在两种情况了:

  1. 对于存量的MOV文件,如何将已经存在MOV文件转存成MP4文件;
  2. 对于未上传的MOV文件,如果做到上传完成时及时转存。
a. 存量文件处理

其实七牛提供了相应的API:

1.转码规格参数 fops 可以替换,转码参数规格文档参考这里
https://developer.qiniu.com/dora/manual/1248/audio-and-video-transcoding-avthumb
实例
java-sdk: https://github.com/qiniu/java-sdk/blob/master/examples/pfop_vframe.java
php-sdk:https://github.com/qiniu/php-sdk/blob/master/examples/pfop_vframe.php
pythons-sdk: https://github.com/qiniu/python-sdk/blob/master/examples/pfop_vframe.py
node-sdk: https://github.com/qiniu/nodejs-sdk/blob/master/examples/video_pfop.js
go-sdk: https://github.com/qiniu/api.v7/blob/master/examples/video_pfop.go

下面就以Java-sdk为例子,简单说明一下如何转存:

  1. 首先,我们需要理解,七牛并没有提供相应的SDK,来说明它的存储空间(bucket)中哪些文件是MOV格式的,也就是说七牛并不提供查找的策略,我想这也可能是为了安全着想。但是万幸的是,我们自己系统的数据库中存储了这些MOV文件,数据库中把这些文件拉一下即可:
    在这里插入图片描述
    然后我们可以使用代码:
public static void main(String[] args) throws QiniuException {
        //设置账号的AK,SK
        String ACCESS_KEY = "Access_Key";
        String SECRET_KEY = "Secret_Key";
        Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
        //新建一个OperationManager对象
        OperationManager operater = new OperationManager(auth);
        //设置要转码的空间和key,并且这个key在你空间中存在
        String bucket = "Bucket_Name";
        String key = "Bucket_key";
        //设置转码操作参数
        String fops = "avthumb/mp4/avsmart/1";
        //设置转码的队列
        String pipeline = "yourpipelinename";
        //可以对转码后的文件进行使用saveas参数自定义命名,当然也可以不指定文件会默认命名并保存在当前空间。
        String urlbase64 = UrlSafeBase64.encodeToString("目标Bucket_Name:自定义文件key");
        String pfops = fops + "|saveas/" + urlbase64;
        //设置pipeline参数
        StringMap params = new StringMap().putWhen("force", 1, true).putNotEmpty("pipeline", pipeline);
        try {
            String persistid = operater.pfop(bucket, key, pfops, params);
            //打印返回的persistid
            System.out.println(persistid);
        } catch (QiniuException e) {
            //捕获异常信息
            Response r = e.response;
            // 请求失败时简单状态信息
            System.out.println(r.toString());
            try {
                // 响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
    }

这里分别解释一下上述参数值:

  1. ACCESS_KEY 和 SECRET_KEY

七牛上传凭证,七牛后端可以提供

  1. Bucket_Name 和 Bucket_Key
    这里的Bucket_Name就是你的空间名称,例如在七牛后台,你创建的空间:

    这里的 Bucket_Key 就是此空间下你需要转存的地址,比如存在一个地址:https://www.image.com/abc.mov, 那么此时你的Bucket_Key应该为 abc.mov;

  2. fops
    转码参数,具体参数详解可以参考文档:https://developer.qiniu.com/dora/6097/perceptive-transcoding-avsmart-1
    avthumb/mp4/avsmart/1说明我启用了锐智转码,可以在不同的网络环境下节省流量;

  3. pipeline
    设置转码的队列,这个地方如果你没有设置的话,可以填写默认的:default.sys,当然我们可以自定我们自己的队列:
    先找到智能多媒体:
    在这里插入图片描述
    在智能多媒体中,找到队列,然后就可以新建队列了。
    在这里插入图片描述
    个人的建议是新建一个私有队列,私有队列的处理速度要快于默认队列“default.sys”。

  4. 目标Bucket_Name:自定义文件key
    你转码之后,需要存储的空间名称,然后转码之后的文件名称。
    比如你在A空间的中存在a.mov文件,此时要转码存储到B空间中,文件名更改为b.mp4。那么此时可以写为:B:b.mp4;

基本上逻辑就介绍完毕了,然后代码执行就可以了。因为执行是异步的,所以不会一下就能转码完成,此时我们可以通过后台来查看转码队列中的任务转码情况。
在这里插入图片描述

b.即将上传的文件

本来是想在移动端上传时,在移动端进行转码再提交,但是效率低下,iOS客户端改动量也比较大,因此还是选择在后端进行监听转码。至于监听转码是什么意思呢?就是我上传了一个视频,首先我检测一下这个视频是否是MOV格式的,如果是,那么我就进行MP4的转码,如果是其它文件就不进行任务操作。这种逻辑类似于Android中的监听器,数据库中的触发器。当然,七牛云后台也提供了类似的服务:我们找到智能多媒体服务,然后再新增触发器任务:


在这里插入图片描述
然后点击新建任务,开始创建任务:
在这里插入图片描述
这里是进行了任务的自定义,以图示的方式展现了代码的原理,首先我们拿到任务之后开始锐智转码,然后进行输出即可。

任务创建完成之后,我们可以触发器任务列表看到任务列表。上图可以看到,我创建了两条任务,一条是针对 .mov文件格式,一条是针对 .MOV 格式文件,因为七牛暂时还不支持 大小写不区分的功能,因此我们需要创建两条。

创建任务完成之后,我们可以测试一下触发器任务是否成功。操作很简单,直接在七牛云后台上传一个MOV文件:
在这里插入图片描述
上传完成之后,我们可以去转码队列中查看一下任务,这里有一个待转码的任务,说明我们的触发器任务创建成功了。
在这里插入图片描述
等到任务完成之后,我们再找到一下这个 test_mov文件,看看是否存在:
在这里插入图片描述
这里可以看到,我们的MOV文件被转码成了mp4文件,因此整个逻辑是正常的,现在小伙伴们可以像以前一样正常的上传文件了。

基本逻辑完成了,问题并不是特别困难,但是其中也踩了一些坑,希望能帮助到大家,如果有问题,可以联系我:

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐