七牛云实现视频拼接和转码

最近做的功能需要拼接视频,使用七牛云的智能多媒体服务可以满足大部分音视频处理需求,收费也还可以。

需求:直播课上完,将录制的直播视频存起来,以便用户回放观看。

解决方案:

使用七牛云,直播课上完,将录制的直播视频,分段上传(防止文件过大上传出问题);上传后,拼接视频。由于录制的课程格式是 webm 类型,若想在ios与安卓端播放,需要转码为mp4格式,所以需要做视频转码,还好七牛都给提供了!!!

【PS1:分段后其实每个文件也不算小,所以上传的时候我们用了分片上传。比较简单,可以看文档->分片上传

【PS2:视频可以边录制边上传,但是由于目前带宽较小,网速也不算太快,为了保证直播质量,就等到课程完毕上传】

音视频转码api地址:https://developer.qiniu.com/dora/api/1246/audio-and-video-stitching-avconcat

过程:

1.看了文档,接口只能用于预转持久化处理持久化数据处理(即触发持久化)。个人理解:预转持久化处理就是文件上传之前,先把文件上传后要做的动作告诉七牛,然后等文件上传后,七牛会给自动处理(所以使用到了七牛的队列)。所以就想先试用预转持久化处理来做。文档中无相关请求示例。自己摸索了很久,试+猜,实现了拼接,但是视频拼接顺序是错乱的,或者视频拼接多了一个(例如:拼接了两个文件(文件1、文件2),结果是文件2+文件1+文件2)提了工单,也没给个靠谱的答复,还是败给了七牛(吐槽下:文档写的是真真真不详细)。

2.换成持久化数据处理的方式,终于实现。

示例代码(需先加载七牛PHP sdk):

/**
     * 触发持久化拼接视频
     * @param $data
     * @return array|bool
     */
    public function concatVideosExample($data)
    {
        if (!$data['key_arr']) {          //待合并的视频文件key
            $this->addError('参数错误');
            return false;
        }

        $mainData = $data['key_arr'][0]; //第一个视频

        unset($data['key_arr'][0]);

        $url = ''; //视频key 按照顺序拼接
        foreach ($data['key_arr'] as $value) {
            $url .=  \Qiniu\base64_urlSafeEncode('kodo://' . 七牛存储空间名称. '/' . $value) . '/';
        }

        $url = rtrim($url, '/');

        // 合并视频key
        $concatVideoKey = Uuid::uuid(); //随机生成一个key,作为合并后的视频key

        $itemValue['bucket_name']    = 七牛存储空间名称;
        $itemValue['key']       = $mainData;
        $itemValue['fops']      = "avconcat/2/format/mp4/s/1280x720/" . $url .  '|saveas/' . \Qiniu\base64_urlSafeEncode($this->option['Bucket_Name'] . ":" . $concatVideoKey . ".mp4");  //转码为mp4 分辨率1280x720 保存
        $itemValue['notifyURL'] = 回调接口地址;

        $pfop = new PersistentFop((new Auth('Access_Key','Secret_Key')), null);

        // 触发持久化拼接视频
        list($id, $err) = $pfop->execute(七牛存储空间名称, $mainData, $itemValue['fops'], 七牛专用队列, $itemValue['notifyURL'], false);

        Log::info(['持久化拼接视频:' . print_r([$data, $itemValue, $id, $err, $concatVideoKey], true)], 'concatVideos'); //log

        // 创建文件
        if ($id) {
            // 保存拼接后的文件
            $service = new File;

            $saveData['persistent_id'] = $id ?: '';

            $saveData['file_name']     = $concatVideoKey . '.mp4';
            $saveData['file_original'] = $concatVideoKey . '.mp4';
            $saveData['file_url']      = $concatVideoKey . '.mp4';
            $saveData['type']          = 'video/mp4';

            。。。保存下来,供回调使用
           
        }

        return true;
    }

/**
     * 七牛异步视频转码回调接口示例
     * @return bool
     */
    public function saveCallbackDataExample()
    {
        $request    = []; //post参数

        if (!$request['id'] || !$request['inputBucket']) {
            $this->addError('参数错误');
            return false;
        }

        Log::info(['七牛回调接口调起:' . print_r($request, true)], 'persistentNotifyTest');

        if ($request['code'] != 0) {
            $this->addError('转码失败');
            return false;
        }

        // 查找文件 上面保存的数据
        $file = File::find(['persistent_id' => $request['id']]);

        if (!$file) {
            $this->addError('文件数据未找到');
            return false;
        }

        // 获取转码视频信息
        $videoData = $request['items'][0];

        $file->transcoding_url = $videoData['key'];
        $save = $file->save();

        if (!$save) {
            $this->addError('更新文件失败');
            return false;
        }

        return true;
    }

拼接并转码无法设置视频的帧率。

看了下视频转码接口,功能很强大。api地址-> https://developer.qiniu.com/dora/api/1248/audio-and-video-transcoding-avthumb示例如下(使用的预转持久化处理方式):

public function example($data)
    {
        $policy = array(
            'returnBody' => '{"state":"SUCCESS","key":"$(key)","hash":"$(etag)","fsize":$(fsize)......回传字段}',
            'callbackUrl' => $this->_callBackUrl,//上传回调地址
            'callbackBody' => 'token=' . .....拼接到回调地址后的参数;
            "persistentOps" => "avthumb/mp4/s/1280x720/r/21|saveas/" . \Qiniu\base64_urlSafeEncode(七牛存储空间名称 . ":" . 随机值(作为key) . ".mp4"),
            "persistentNotifyUrl"=> $this->_notifyUrl,//转码后的回调地址
            'persistentPipeline' => 专用队列,
            );
       
        return ['token'=>(new Auth('Access_Key','Secret_Key'))->uploadToken(七牛存储空间名称, null, 最长请求时间, $policy)];
    }

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值