zoukankan      html  css  js  c++  java
  • js获取视频第一帧生成图片

    好久没上来博客园都落灰了,最近太忙,今天搞的一个视频小程序,由于小程序性能问题,一次加载很多视频会卡,所以需要先展示图片,于是我在后端加了上传封面图的按钮。本来一切很自然,but...客户不愿意上传图片。他说“你知道要增加多少工作量吗”?wtf??好吧,我给你生成图片,不要你自己上传。

    but客户的视频是直接上传的腾讯云的cos的对象储存的,他要是存到云点播我还有有法儿拿封面截图媒体信息啥的,但是现在我除了拿点儿文件信息也拿不到别的了。

    脑海里闪出两个idea:

    第一:迂回式。 前端视频文件传到后台,我先存在本地,然后用php的视频插件去生成图片保存在本地,完事儿两个一起上传到腾讯云cos,等他俩返回链接我再删掉本地的文件...emmmm...有点鸡肋,我也嫌麻烦,果断采用第二种方法曲线救国

    第二:曲线救国式。既然不想用后端完成,那就走前端js,大概的流程应该是用户选择文件后生成blob预览,同时传到后台放到cos上,然后把video放到canvas上面做个快照,然后就能拿到图片预览

    上面是废话,下面是重点

    ----------------------------------------------------------------------------------------------------------废话分割线--------------------------------------------------------------------------------------------------------

    代码如下:

    1、将用户选择的文件转为blob生成预览,uploadFile2是fromData上传文件的方法

            $('#file').on('change', function() {
                var files = this.files,
                    video = $('#video').find('video'),
                    videoURL = null,
                    windowURL = window.URL || window.webkitURL;
                if(files && files[0]) {
    
                    uploadFile2(files[0],1);
                    videoURL = windowURL.createObjectURL(files[0]);
                    $('#imgSmallView span').html('请等待图片生成');
                    $('#video video').attr('src', videoURL);
                    $('#video video').trigger('click');
                    setTimeout(function() {
                        createIMG(files[0].name.split('.')[0]+'.png');
                    }, 3500);
                }
            }).trigger('change');

    2、生成图片

            function createIMG(name) {
                var scale = 0.35,
                    video = $('#video').find('video')[0],
                    canvas = document.createElement("canvas");
    
                canvas.width = video.videoWidth * scale;
                canvas.height = video.videoHeight * scale;
                var flag = true;
                for(var flag = true; flag; ) {
                    if(canvas.width > 400) {
                        canvas.width *= 0.9;
                        canvas.height *= 0.9;
                    } else {
                        flag = false;
                    }
                }
                canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
                saveImage(canvas, name);
            }

    3、保存图片预览

      第一步把刚才画出来的转成base64

      第二步把base64转为file送到后台上传

      前端同时生成预览

            function saveImage(_canvas, _name) {
                var imagebase64 = _canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream');
                var imgURL = image.getFileFromBase64(imagebase64, 'imgName');
                console.log(imgURL);
                uploadFile2(imgURL,2)
                $('#imgSmallView span').html('图片生成完成,可以进行下一步操作');
            }

    本来不打算转base64,但是叭直接传给cos他返回的图片是空的,无奈只能手动转成file

            var image= {
                /* 将图片(路径)转换为Base64 */
                getBase64FromImageURL(url, callback) {
                    var canvas = document.createElement('canvas'),
                        ctx = canvas.getContext('2d'),
                        img = new Image;
                    img.crossOrigin = 'Anonymous';
                    img.onload = function () {
                        canvas.height = img.height;
                        canvas.width = img.width;
                        ctx.drawImage(img, 0, 0);
                        var base64URL = canvas.toDataURL('image/png');
                        callback(base64URL);
                        canvas = null;
                    };
                    img.src = url;
                },
                /* 将base64转换为file类型 */
                getFileFromBase64(base64URL, filename) {
                    var arr = base64URL.split(','),
                        mime = arr[0].match(/:(.*?);/)[1],
                        bstr = atob(arr[1]),
                        n = bstr.length,
                        u8arr = new Uint8Array(n);
                    while (n--) {
                        u8arr[n] = bstr.charCodeAt(n);
                    }
                    // alert(mime)
                    return new File([u8arr], filename, {type: 'image/png'});
                }
            }

    经过三个小时的摸索,终于成功了,虽然代码也是东拼西凑这一点儿那儿一点儿看过来的,不过好歹是完成了客户“偷懒”的需求,开熏!

    技术最菜,头发最少
  • 相关阅读:
    Camel routes in Spring config file
    Construct a basic automation test framework
    Java custom annotations
    Java Abstract Class
    Hibernate之mappedBy
    hibernate FetchType理解
    hibernate 双向 OneToOne fetchType lazy 问题
    日常总结
    hibernate二级缓存
    sql子查询和嵌套查询
  • 原文地址:https://www.cnblogs.com/gushengyan/p/13284414.html
Copyright © 2011-2022 走看看