canvas将视频截图并上传服务器

       今天准备整理一篇关于《video使用HTML5的canvas画布功能实现视频在线截图功能,并把相关图片上传服务器》

        ·思路分析

             1. 使用canvas画布功能画出当前video实时界面,并将画布图片转为base64数据;

             2.  通过ajax传到后端,再做图片生成并上传服务器对应位置;

             3. 把相关数据存储记录表并反馈处理结果。

        ·效果展示

将画布产生的base64数据在img中展示查看截图效果:

·canvas画布资源获取

<video  crossOrigin="anonymous" id="my_video_1" style="width: 300px;height: 480px;" preload="metadata" autoplay="autoplay"   class="video-js vjs-fluid"></video>

     JS数据处理:

// 截图当前视频画面,预览后传递后端进行服务器保存
    var base64Url= "";  //定义为全局变量
    function screenshotsVideo() {
        base64Url = getScreenshotsVideoImg();
	var imgObj=document.getElementById("screenshotsVideoImg");
        //生成img展示    
        imgObj.src=base64Url;
    }

    // 构造canvas 生成图片base64数据 
    function getScreenshotsVideoImg() {
        var _videoWidth = 0;
        var _videoHeight = 0;
        var _canvas ;
        var _ctx ;
        var _video;
		_canvas = document.createElement('canvas');
        _ctx = _canvas.getContext("2d");
        _video = document.querySelectorAll('video')[0];
		_videoWidth = _video.videoWidth ;//视频原有尺寸
        _videoHeight = _video.videoHeight;//视频原有尺寸
        _canvas.width =_videoWidth;
        _canvas.height =_videoHeight;
		_ctx.drawImage(_video, 0, 0,_videoWidth,_videoHeight);
        var base64 = _canvas.toDataURL('image/jpeg');
		console.log("toDataURL save complete!");
		return base64;
    }

  点击按钮,触发数据传送:

    // 将截图base64资源,传递后端处理 
    function saveScreenshots(){
        myModalData = "";
            if (null != contentData) {
                var photoDescribeText =  $('#photoDescribeText').val();
                if(null == photoDescribeText || '' == photoDescribeText){
                    toastr.info('请填写截图问题描述!');
                    return;
                }
                $.ajax({
                   type : "post",    //请求类型
                   url : "../../../****.json",//请求的 URL地址
                   data:{
                       base64Url : base64Url,
                       videoPlayUrl : videoPlayUrl.substring(0,videoPlayUrl.length-1),
                       auditType : '1', //审核类型  1:复审
                       photoDescribe:photoDescribeText,
                       contentCode : contentData.contentCode,
                       contentName : contentData.contentName,
                   },
                   dataType : "json",//返回的数据类型
                   success: function (data) {
                       console.log("data"+data);
                       if(data.success){
                           $('#photoDescribeText').val(""); //清空图片问题描述
                           $("#screenshotsVideoModal").modal('hide'); //关闭模态框
                           toastr.success('截图保存成功!');
                       }else{
                           toastr.error('截图保存失败!');
                       }
                   },
                   error:function (data) {
                       console.log("data"+data);
                       toastr.error('截图保存失败!');
                   }
               });

            }
	}

·后端图片上传和数据保存处理

 //保存视频截图接口
    public String mgdmSaveVideoScreenshots() {
        try {
            getParams();
            String base64Url = this.getParam("base64Url");
            base64Url = base64Url.split(",")[1];
            String photoAddress = handlePicAdds(base64Url); // 获取本地存储图片相对地址
            if (StringUtil.isNullStr(photoAddress)){
                //如果图片没有上传成功,直接返回错误结束方法
                resultMap.put("success", false);
                resultMap.put("resultMessage",this.getText("operateFailed"));
                return SUCCESS;
            }
            params.put("photoAddress", photoAddress);
            params.put("operId", this.getUserId());
            params.put("operator", this.getUsername() + "_YSSHY");
            Boolean saveResult = auditPhotoScreenshotManager.saveAuditPhotoScreenshot(params);
            if(saveResult){
                resultMap.put("success", true);
                resultMap.put("resultMessage",this.getText("operateSuccess"));
            }else{
                resultMap.put("success", false);
                resultMap.put("resultMessage",this.getText("operateFailed"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("success", false);
            resultMap.put("resultMessage",this.getText("operateFailed"));
        }
        return SUCCESS;
    }


    public String handlePicAdds(String base64Url){
        String localPicAdds =   params.get("contentCode")+"-"+DateUtil.formatDate(DateUtil.DATE_TIME_HHMMSS,new Date());
        String todayPath = nowDatePath();
        String localPicName = todayPath+localPicAdds+CmsConstants.PIC_JPG;
        Boolean downLoad = writeFileToLocal(base64Url,localPicAdds); //将图片上传到服务器
        String localPicAdd = "";
        if(downLoad){
            localPicAdd = localPicName;
        }
        return  localPicAdd;
    }


    //将图片下载到本地
    public Boolean writeFileToLocal(String base64Url,String localPath){
        try {

            BASE64Decoder decoder = new BASE64Decoder();
            // Base64解码
            byte[] buffer = decoder.decodeBuffer(base64Url);
            for (int i = 0; i < buffer.length; ++i) {
                if (buffer[i] < 0) {// 调整异常数据
                    buffer[i] += 256;
                }
            }
            String todayPath = nowDatePath();
            String serverPicPath = SyncConstants.POMS_MGDM_SERVER_PIC_PATH+todayPath;   //服务器图片存储文件路径
            File file = new File(serverPicPath);
            if(!file .exists()){
                file.mkdirs();
            }
            FileOutputStream fileOutputStream = new FileOutputStream(new File(serverPicPath+localPath+CmsConstants.PIC_JPG));
            fileOutputStream.write(buffer);
            fileOutputStream.close();
            return  true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public String nowDatePath(){
        //根据日期创建 图片存储路径
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH) + 1;
        Integer date = calendar.get(Calendar.DAY_OF_MONTH);
        String pathStr = CmsConstants.PATH_SEPARATOR;
        String severPath = pathStr+year+pathStr+month+pathStr+date+pathStr;
        return  severPath;
    }

·注意问题

      1.在处理的过程中,遇到video视频资源跨域导致canvas画布污染的问题,处理的时候可以参考下面:

         https://www.jianshu.com/p/6fe06667b748

       很长一段时间没有记录博客了,上半年因为换工作和准备软考的事情一度停更了半年,接下来希望能在这里将工作和学习中好的知识点总结下来,以供自己和朋友们参考。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值