美文网首页
js 仿微博video截取封面

js 仿微博video截取封面

作者: 羊羊羊0703 | 来源:发表于2017-06-30 18:19 被阅读0次

封装视频截取封面函数:

/**
 * 视频屏幕截图
 * @param {object} file 视频文件对象
 * @param {object} options 配置项
 * @param {function} options.error 错误回调
 * @param {function} options.success 成功回调
 * @param {object} wrapper 可选 dom对象 默认body
 */
function videoScreenshot(file, options, wrapper) {
    options = options || {};
    options.error = options.error || $.noop;
    options.success = options.success || $.noop;
    wrapper = wrapper || document.body;

    var videoUrl, video, canvas, duration, interval, currentTime = 0,
        imgs = [],
        result = {};
    if(navigator.userAgent.indexOf('Chrome') < 0 && navigator.userAgent.indexOf('Safari') < 0) {
        options.error('浏览器不支持视频截图,请使用 Chrome 浏览器!');
    } else {
        try {
            videoUrl = (typeof file === 'string') ? file : window.URL.createObjectURL(file);
            video = document.createElement('video');
            canvas = document.createElement('canvas');

            video.style.visibility = 'hidden';
            wrapper.appendChild(video);

            video.src = videoUrl;
            video.muted = true;

            video.addEventListener('seeked', videoSeeked, false);
            var ctx = canvas.getContext("2d");

            var k = 20;
            var timeoutInterval = setInterval(function() {
                if(!k) {
                    clearInterval(timeoutInterval);
                    options.error('视频截图失败')
                } else {
                    if(video.readyState >= 1) {
                        clearInterval(timeoutInterval);
                        if(video.videoWidth == 0 || video.videoHeight == 0 || video.duration == 0) {
                            options.error('视频截图失败');
                            return
                        }
                        // 封面尺寸 375x200,使用2倍图
                        var scale = Math.max(750 / video.videoWidth, 400 / video.videoHeight);
                        scale > 1 && (scale = 1);
                        video.width = canvas.width = result.width = Math.floor(video.videoWidth * scale);
                        video.height = canvas.height = result.height = Math.floor(video.videoHeight * scale);
                        duration = video.duration;
                        interval = duration / 10;
                        video.currentTime = currentTime;
                    }
                    k--
                }
            }, 100);

            function videoSeeked() {
                try {
                    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                    imgs.push(canvas.toDataURL("image/jpeg"));
                    if(imgs.length == 1 && isDrawSuccess()) {
                        options.error('视频截图失败');
                        return;
                    }
                    if(imgs.length == 10) {
                        imgs.splice(0, 1);
                        play();
                        return;
                    }
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    currentTime += interval;
                    video.currentTime = currentTime
                } catch(a) {
                    options.error('视频截图失败')
                }
            }

            function videoPlaying() {
                setTimeout(function() {
                    video.pause();
                    video.removeEventListener("playing", videoPlaying);
                    if(video.currentTime < video.duration) {
                        result.imgs = imgs;
                        options.success(result);
                        destroy();
                    } else {
                        options.error('视频截图失败');
                    }
                }, 50)
            }

            function isDrawSuccess() {
                var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                return imageData.data[imageData.data.length - 1] == 0 ? true : false;
            }

            function play() {
                var time = duration - .5;
                video.removeEventListener("seeked", videoSeeked);
                video.addEventListener("playing", videoPlaying, false);
                video.currentTime = time;
                video.play()
            }

        } catch(err) {
            options.error(err);
        }
    }

    // 销毁
    function destroy() {
        try {
            wrapper.removeNode(video);
            window.URL.revokeObjectURL(videoUrl);
        } catch(err) {}
    }
}

调用函数:

videoScreenshot(file, {
    error: function(err) {
        toastr.error(err);
    },
    success: function(data) {
        $.each(data.imgs, function(i, item) {
            //在此处添加到Dom对象里
        });
    }
});

相关文章

网友评论

      本文标题:js 仿微博video截取封面

      本文链接:https://www.haomeiwen.com/subject/aleicxtx.html