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'});
            }
        }

 

經過三個小時的摸索,終於成功了,雖然代碼也是東拼西湊這一點兒那兒一點兒看過來的,不過好歹是完成了客戶“偷懶”的需求,開熏!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM