zoukankan      html  css  js  c++  java
  • 七牛云上传视频并转码

    概述:

    很多用户使用七牛的云存储服务,存放很多mp4文件到七牛的存储空间,但是通过复制外链,然后在浏览器中播放,经常会遇到“只有音频,没有视频”的情况;
    其实这个不是七牛的存储有问题,而是视频的编码方式,浏览器不支持,如:MPEG-4 在googel Chrome 、IE这些浏览器中都是不支持视频播放的,但通过苹果的Safari浏览器是能正常播放的;

    思路:
    1.上传一个视频到七牛的空间,然后再进行转码操作;
    2,上传的同时指定预处理操作,进行转码处理后,上传;
    3.查看七牛的avthumb接口说明和支持的编码说明,链接如下:
    http://developer.qiniu.com/code/v6/api/dora-api/av/avthumb.html
    https://support.qiniu.com/hc/kb/article/182142/?from=draft

    第一种方法,代码示例如下:

    package com.qiniu.dora;
    
    import com.qiniu.base.AccountMgr;
    import com.qiniu.common.QiniuException;
    import com.qiniu.common.Zone;
    import com.qiniu.processing.OperationManager;
    import com.qiniu.storage.Configuration;
    import com.qiniu.util.Auth;
    import com.qiniu.util.StringMap;
    import com.qiniu.util.UrlSafeBase64;
    
    /**
     * 很多浏览器不支持 MPEG-4编码的视频,所以上传到七牛,用类似google 这样的浏览器是不能正常播放的,只有音频,没有视频
     * 所以可以使用七牛的转码接口
     * 
     * @author xuhuanchao
     *
     */
    public class AVthumbForMpeg4 {
    
        //获取授权对象
        Auth auth = Auth.create(AccountMgr.ACCESS_KEY, AccountMgr.SECRET_KEY);
        //执行操作的管理对象
        OperationManager operationMgr = new OperationManager(auth, new Configuration(Zone.zone0()));
        /**
         * Test Method
         * @param args
         */
        public static void main(String[] args) {
            new AVthumbForMpeg4().transcoding();
        }
        /**
         * 转码
         */
        void transcoding() {
            String bucket = "java-bucket";          //存储空间名称
            String key = "mpeg_4_type.mp4";         //存储空间中视频的文件名称
            String newKey = "H264_type.mp4";        //转码后,另存的文件名称
            String pipeline = "admin_merge_radio";  //处理队列
    
            String saveAs = UrlSafeBase64.encodeToString(bucket + ":" + newKey);        //saveas接口 参数
            String fops = "avthumb/mp4/vcodec/libx264|saveas/" + saveAs;                //处理命令 avthumb 和 saveas 通过管道符 |  进行连接
    
            try {
                //执行转码和另存 操作
                String persistentId = operationMgr.pfop(bucket, key, fops, new StringMap().put("persistentPipeline", pipeline));
                System.out.println(persistentId);
            } catch (QiniuException e) {
                String errorCode = String.valueOf(e.response.statusCode);
                System.out.println(errorCode);
                e.printStackTrace();
            }
        }  
    }
    

    第二种方法,代码示例如下:

    import com.qiniu.util.Auth;
    import com.qiniu.util.StringMap;
    import com.qiniu.util.UrlSafeBase64;
    
    import java.io.IOException;
    
    import com.qiniu.common.QiniuException;
    import com.qiniu.http.Response;
    import com.qiniu.storage.UploadManager;
    
    public class UploadDemo {
      //设置好账号的ACCESS_KEY和SECRET_KEY
      String ACCESS_KEY = "Access_Key";
      String SECRET_KEY = "Secret_Key";
      //要上传的空间
      String bucketname = "Bucket_Name";
      //上传到七牛后保存的文件名
      String key = "my-java.png";
      //上传文件的路径
      String FilePath = "/.../...";
    
      //设置转码操作参数
      String fops = "avthumb/mp4/s/640x360/vb/1.25m";
      //设置转码的队列
      String pipeline = "yourpipelinename";
    
      //可以对转码后的文件进行使用saveas参数自定义命名,当然也可以不指定文件会默认命名并保存在当前空间。
      String urlbase64 = UrlSafeBase64.encodeToString("目标Bucket_Name:自定义文件key");
      String pfops = fops +"|saveas/"+ urlbase64;
    
      //密钥配置
      Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
      //创建上传对象
      UploadManager uploadManager = new UploadManager();
    
      //上传策略中设置persistentOps字段和persistentPipeline字段
      public String getUpToken(){
          return auth.uploadToken(bucketname,null,3600,new StringMap()
              .putNotEmpty("persistentOps", pfops)
              .putNotEmpty("persistentPipeline", pipeline), true);
      }
    
      public void upload() throws IOException{
        try {
          //调用put方法上传
          Response res = uploadManager.put(FilePath, null, getUpToken());
          //打印返回的信息
          System.out.println(res.bodyString()); 
          } catch (QiniuException e) {
              Response r = e.response;
              // 请求失败时打印的异常的信息
              System.out.println(r.toString());
              try {
                  //响应的文本信息
                System.out.println(r.bodyString());
              } catch (QiniuException e1) {
                  //ignore
              }
          }       
      }
    
      public static void main(String args[]) throws IOException{  
        new UploadDemo().upload();
      }
    
    }
    
    
    注:上面的Demo只是针对视频转码,如果需要别的功能比如音视频切片、视频截图、视频拼接只需要修改下上面的fops后面的参数就可以了,
    eg: fops = "vframe/jpg/offset/1/w/480/h/360/rotate/90"就表示视频截图了。
    下面给出一些常见的数据处理功能,可以根据需要进行选择:
    //------------------图片缩放-------------------
    fops ="imageView/2/w/200/h/200";
    
    //------------------视频转码-------------------
    // fops ="avthumb/flv/vb/229k/vcodec/libx264/noDomain/1";
    
    //------------------图片水印-------------------
    String pictureurl = UrlSafeBase64.encodeToString("http://developer.qiniu.com/resource/logo-2.jpg");
    fops = "watermark/1/image/" + pictureurl;
    
    //------------------视频切片-------------------
    fops = "avthumb/m3u8";
    //切片与加密参数
    fops = "avthumb/m3u8/vb/640k/hlsKey/MDEyMzQ1Njc4OTEyMzQ1Ng==/hlsKeyUrl/aHR0cDovLzd4bGVrYi5jb20yLnowLmdsYi5xaW5pdWNkbi5jb20vcWluaXV0ZXN0LmtleQ==";
    
    //------------------文档转换-------------------
    fops = "yifangyun_preview";
    
    //------------------视频截图-------------------
    fops = "vframe/jpg/offset/1/w/480/h/360/rotate/90";
    
    //------------------视频拼接-------------------
    //拼接视频片段时要保证所有源的画面长宽值一致
    //除去作为数据处理对象的源文件以外,还可以指定最多5个源文件(即总计6个片段)
    //所有源文件必须属于同一存储空间
    //格式:avconcat/<Mode>/format/<Format>/<encodedUrl0>/<encodedUrl1>/<encodedUrl2>/...
    String encodedUrl1 = UrlSafeBase64.encodeToString("http://7xl4c9.com1.z0.glb.clouddn.com/pingjie2.flv");
    String encodedUrl2 = UrlSafeBase64.encodeToString("http://7xl4c9.com1.z0.glb.clouddn.com/pingjie3.avi");
    fops = "avconcat/2/format/mp4/"+encodedUrl1+encodedUrl2;
    
    //------------------多文件压缩-------------------
    //可将若干七牛空间中的资源文件,在七牛服务端压缩后存储
    //格式:mkzip/<mode>/url/<Base64EncodedURL>/alias/<Base64EncodedAlias>/url/<Base64EncodedURL>
    String encodedfile1 = UrlSafeBase64.encodeToString("http://7xl4c9.com1.z0.glb.clouddn.com/photo1.jpg");
    String encodedfile2 = UrlSafeBase64.encodeToString("http://7xl4c9.com1.z0.glb.clouddn.com/vedio1.mp4");
    String encodedfile3 = UrlSafeBase64.encodeToString("http://7xl4c9.com1.z0.glb.clouddn.com/audio1.mp3");
    fops = "mkzip/2/url/"+encodedfile1+"url/"+encodedfile2+"url/"+encodedfile3;
    

    补充说明案例:

    页面ajax

     <input type="file" class="form-control" name="file" id="filedata" placeholder="upload"
          style="margin-bottom:5px;">
     <button onclick="uploadfile(this);">上传视频文件</button>
     <input type="hidden" class="form-control" name="videoUrl" id="urlId" placeholder="请输入视频链接"
            style="margin-bottom:5px;">
     <span id="isfile"></span>
     <div id="successAlertFile" class="alert alert-success"
          style="display:none;">
         <span id="successAlertFile_msg"></span>
     </div>
                    
    
    function uploadfile(el) {
            var formData = new FormData();
            var file = $(el).siblings().filter('#filedata').prop('files')[0];
            formData.append("file", $(el).siblings().filter('#filedata').prop('files')[0]);
            if(file != null && file != ''){
                if (file.size < 104857600) {
                    $.ajax({
                        url: '${s.base}/video/upload.html',
                        type: 'POST',
                        data: formData,
                        processData: false, // 不要对data参数进行序列化处理,默认为true
                        contentType: false, // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码
                        xhr: function () {
                            myXhr = $.ajaxSettings.xhr();
                            if (myXhr.upload) {
                                myXhr.upload.addEventListener('progress', function (e) {
                                    if (e.lengthComputable) {
                                        var percent = Math.floor(e.loaded / e.total * 100);
                                        $(el).siblings().filter('#isfile').html(percent.toString() + '%');
                                        if (percent == 100) {
                                            $(el).siblings().filter('#isfile').html("正在上传:" + "<img src='${s.base}/res/i/loading.gif'/>");
                                        }
                                    }
                                }, false);
                            }
                            return myXhr;
                        },
                        success: function (respText) {
                            var resp = $.parseJSON(respText);
                            if (resp.errcode == 0) {
                                console.log(resp,"---success----");
                                $(el).siblings().filter('#isfile').html('');
                                $(el).siblings().filter('#successAlertFile').show().fadeOut(3000);//显示模态框
                                $(el).siblings().filter('#successAlertFile').children().css('color', 'green').html('上传成功!');
                                $(el).siblings().filter('#urlId').val(resp.data.path);
                            } else {
                                $(el).siblings().filter('#successAlertFile').show().fadeOut(3000);
                                $(el).siblings().filter('#successAlertFile').children().css('color', 'red').html('文件名称重复,请重新上传!');
                                $(el).siblings().filter('#isfile').html('');
                            }
                        },
                        error: function (res) {
                            // 请求失败
                            console.log(res);
                            $(el).siblings().filter('#successAlertFile').show().fadeOut(3000);
                            $(el).siblings().filter('#successAlertFile').children().css('color', 'red').html('上传失败,请重新上传!');
                            $(el).siblings().filter('#isfile').html('');
                        }
                    });
                } else {
                    $(el).siblings().filter('#successAlertFile').show().fadeOut(3000);
                    $(el).siblings().filter('#successAlertFile').children().css('color', 'red').html('上传视频不能大于100MB!');
                }
            } else {
                $(el).siblings().filter('#successAlertFile').show().fadeOut(3000);
                $(el).siblings().filter('#successAlertFile').children().css('color', 'red').html('上传视频不能为空!');
            }
            /* var demo =  $(el).siblings().filter('#urlId').val()
             console.log(demo,"----demo---")*/
        }
    

    controller

      package com.online.college.opt.controller;
    
    import com.online.college.common.storage.QiniuStorage;
    import com.online.college.common.web.JsonView;
    import com.online.college.core.consts.domain.CollegeClassTeacher;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.commons.CommonsMultipartFile;
    import org.springframework.web.servlet.ModelAndView;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @Author: LBX
     * @Date: 2018/12/24 14:07
     */
    @Controller
    @RequestMapping("/video")
    public class UploadFileController {
    
        @RequestMapping("/upload")
        @ResponseBody
        public String upload(@RequestParam("file") CommonsMultipartFile picture){
            Map<String,Object> map = new HashMap<>();
            if (null != picture && picture.getBytes().length > 0) {
                String key = QiniuStorage.uploadVideo(picture);
                map.put("key",key);
            }
            return JsonView.render(map);
        }
    }
    

    service

    	 /**
    	 * 上传视频
    	 * @param picture
    	 */
    	public static String uploadVideo(CommonsMultipartFile picture){
    		String key = QiniuKeyGenerator.generateKey();
    		key = QiniuWrapper.uploadVideo(picture, key);
    		return key;
    	}
    

    serviceimpl

      /**
         * 上传视频
         *
         * @return
         */
        public static String uploadVideo(CommonsMultipartFile picture, String key) {
            DiskFileItem diskFileItem = (DiskFileItem) picture.getFileItem();
            File file = diskFileItem.getStoreLocation();
            try {
                String fileName = picture.getOriginalFilename();
                //设置转码操作参数
                String fops = "avthumb/mp4/vcodec/libx264";
                //可以对转码后的文件进行使用saveas参数自定义命名,当然也可以不指定文件会默认命名并保存在当前空间。
                String urlbase64 = UrlSafeBase64.encodeToString(bucketName + ":" + fileName + ".mp4");
                String pfops = fops + "|saveas/" + urlbase64;
                String upToken = auth.uploadToken(bucketName, null, 3600, new StringMap().putNotEmpty("persistentOps", pfops));
                key = key + ".mp4";
                //调用put方法上传
                Response response = uploadManager.put(file, key, upToken);
                //打印返回的信息
                System.out.println("-----success---" + response.bodyString());
                DefaultPutRet ret = response.jsonToObject(DefaultPutRet.class);
                return ret.key;
            } catch (QiniuException e) {
                logger.error("upload file to qiniu cloud storage failed", e);
            }
            return null;
        }
    
  • 相关阅读:
    awt
    登录校验 简单实现
    事务隔离级别
    事务的四大特性(ACID)
    多线程简单了解
    Eureka bug
    什么是存储过程
    filter和servlet的区别
    说说你对多线程锁机制的理解
    session的生命周期,session何时创建,何时销毁,session销毁的方式
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13300593.html
Copyright © 2011-2022 走看看