创建画布时IE中的InvalidStateError

时间:2017-07-28 13:38:37

标签: javascript jquery html5 html5-canvas html5-video

我正在尝试按用户上传的视频创建缩略图。 它是chrome和firefox中的工作文件,但是当我在IE中执行相同的代码时,它会抛出异常 InvalidStateError

我发现同一问题已被问到here,但所有人都在使用预加载的视频。 但在我的情况下,我必须使用文件输入上传视频。

这是我的JS代码

 var VideoSnapper = {

     captureAsCanvas: function(video, options, handle) {

         // Create canvas and call handle function
         var callback = function() {
             // Create canvas
             var canvas = $('<canvas />').attr({
                 width: options.width,
                 height: options.height
             })[0];
             // Get context and draw screen on it
             canvas.getContext('2d').drawImage(video, 0, 0, options.width, options.height);
             // Seek video back if we have previous position 
             if (prevPos) {
                 // Unbind seeked event - against loop
                 $(video).unbind('seeked');
                 // Seek video to previous position
                 video.currentTime = prevPos;
             }
             // Call handle function (because of event)
             handle.call(this, canvas);
         }

         // If we have time in options 
         if (options.time && !isNaN(parseInt(options.time))) {
             // Save previous (current) video position
             var prevPos = video.currentTime;
             // Seek to any other time
             video.currentTime = options.time;
             // Wait for seeked event
             $(video).bind('seeked', callback);
             return;
         }

         // Otherwise callback with video context - just for compatibility with calling in the seeked event
         return callback.apply(video);
     }
 };


 $(document).ready(function() {
     $('#newlocalFILE').on('change', function() {
         var player = document.getElementById("videoPlayer");
         var currentVID = document.getElementById('currentVID');
         var selectedLocalVID = document.getElementById('newlocalFILE').files[0];


         currentVID.setAttribute('src', URL.createObjectURL(selectedLocalVID));
         player.load();
         player.play();

         var canvases = $('canvas');
         VideoSnapper.captureAsCanvas(document.getElementById("videoPlayer"), {
             width: 160,
             height: 68,
             time: 40
         }, function(canvas) {
             var dataUrl = canvas.toDataURL();
             $('#tst').attr("src", dataUrl);
             //$('#screen').append(canvas);   

         });
     });
 })

JSFiddle

1 个答案:

答案 0 :(得分:0)

对于IE,您需要添加“loadedmetadata”事件侦听器以确保加载视频元数据,以便您可以访问currentTime属性。

从这个回答:Start HTML5 video at a particular position when loading?我尝试将标记重复,但它没有让我。

我认为这可以帮助您使功能按预期工作:https://jsfiddle.net/q9sLwr73/5/

var VideoSnapper = {
    captureAsCanvas: function(video, options, handle) {
        var waitForMetadata = function() {
            video.currentTime = options.time;
        };

        // Create canvas and call handle function
        var callback = function() {

            // Create canvas
            var canvas = $('<canvas />').attr({
                width: options.width,
                height: options.height
            })[0];

            // Get context and draw screen on it
            canvas.getContext('2d').drawImage(video, 0, 0, options.width, options.height);
            // Seek video back if we have previous position 
            if (prevPos) {
                // Unbind seeked event - against loop
                $(video).unbind('seeked');
                video.removeEventListener('loadedmetadata', waitForMetadata, false);
                // Seek video to previous position
                video.currentTime = prevPos;
            }
            // Call handle function (because of event)
            handle.call(this, canvas);
        }

        // If we have time in options 
        if (options.time && !isNaN(parseInt(options.time))) {
            // Save previous (current) video position
            var prevPos = video.currentTime;

            // Seek to any other time
            video.addEventListener('loadedmetadata', waitForMetadata, false);
            //OLD CODE: video.currentTime = options.time;

            // Wait for seeked event
            $(video).bind('seeked', callback);
            return;
        }

        // Otherwise callback with video context - just for compatibility with calling in the seeked event
        return callback.apply(video);
    }
};