【问题标题】:how to make a video preview with canvas?如何使用画布进行视频预览?
【发布时间】:2021-09-20 12:53:25
【问题描述】:

这是我的第一个问题! 我正在尝试制作一个显示我制作的视频的网站,并且我希望我的观众在将鼠标悬停在元素或元素上时可以看到视频预览。 我只是这样做,但我有一些问题和疑问。让我先给你看代码示例,然后我问我的问题。

    <!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <div id="thumbs"  style="width:216px;height:468px;border: 5px solid blue;background-color:red;"><canvas onmouseover="getid1(this);" onmouseout="getid2(this);" id="canvas1"></canvas></div>

        <script>
            var thumbsList = [];
            var delay = 100;
            var i = 0;
            var video = document.createElement("video");
            var a = 0;
            var m = document.getElementById("canvas1");
            var mtx = m.getContext("2d");
            var generate = true;
            var animstop = false;
            var vidFrames = 64;
        
            m.width = 216;
            m.height = 468;
            video.preload = "auto";
            video.src = "aaaa.mp4";
            
            function stranim(bb){
                    if(generate){
                        animstop = false;
                        video.currentTime = i;
                        generateVid();
                        generate = false;
                    }else{
                        animstop = false;
                        startAnim();
                    }
            }
            
            function stpanim(bb) {
                
                clearTimeout();
                animstop = true;
                mtx.drawImage(thumbsList[0], 0, 0); 
            }
            // if i replace this section with generateVid() the code is working
            /*video.addEventListener('seeked', function() {
                var d = (video.duration / vidFrames) * 2;
                generateThumbnail();
                i += video.duration / vidFrames;
                if (i <= video.duration) {
                    video.currentTime = i;
                    generateVid()
                    if(d == i){
                        startAnim();
                    }
                }
            });*/

            function generateVid() {
                var d = (video.duration / vidFrames) * 2;
                generateThumbnail();
                i += video.duration / vidFrames;
                if (i <= video.duration) {
                    video.currentTime = i;
                    generateVid();
                    if(d == i){
                        startAnim();
                    }
                }
            }
            
            
                
            function generateFirstThumbnail() {
                var c = document.createElement("canvas");
                var ctx = c.getContext("2d");
                c.width = 216;
                c.height = 468;
                ctx.drawImage(video, 0, 0, 216, 468);
                thumbsList.push(c); 
                thumbs.appendChild(m);
                mtx.drawImage(thumbsList[0], 0, 0); 
                i += video.duration / vidFrames;
            }
                
            function generateThumbnail() {
                var c = document.createElement("canvas");
                var ctx = c.getContext("2d");
                c.width = 216;
                c.height = 468;
                ctx.drawImage(video, 0, 0, 216, 468);
                thumbsList.push(c); 
            }

            function startAnim() {
                var currentFrame = 0;
                function anim() {               
                    if(currentFrame != (vidFrames - 1) && animstop == false){
                        currentFrame = (currentFrame + 1) % thumbsList.length;
                        mtx.drawImage(thumbsList[currentFrame], 0, 0);                          
                        setTimeout(anim, delay); 
                    }
                }
                anim(); 
            }
            
            function getid1(obj) {
                stranim(obj.id)
            }
            
            function getid2(obj) {
                stpanim(obj.id)
            }
            window.onload = function(){
                
                generateFirstThumbnail();
            };
            
        </script>
    </body>
</html>

问题是: 1-为什么我的 generatevid() 函数不起作用?这个函数就像那个事件监听器。 2-我想在一个类上添加这个代码以在多个视频中使用它,但是我知道如何,我认为这不能用 js 类来完成。(我搜索了很多网站) 3-我可以使用二维数组来保存我的视频预览,但它不会降低我的网站的加载速度还是不会填满用户的内存? 4-有什么方法可以让这段代码变得更好更简单?(我不想无缘无故地使用jquery)。

【问题讨论】:

  • 这似乎如果你不使用搜索事件视频当前时间不会改变,它会在所有数组上保存第 0 帧。我只是在我的函数及其工作 rn 上添加了事件监听器,但我对此感到难过我认为这不是一个好方法。但无论如何它的工作 rn

标签: javascript html canvas html5-canvas video-thumbnails


【解决方案1】:

对于纯 js 方法,您可以检查一下这不是我的顺便说一句:https://codepen.io/tepexic/pen/BazYgJe

html:

<input type="file" accept="video/*" id="input-tag"/>
<hr>
<video controls id="video-tag">
  <source id="video-source" src="splashVideo">
  Your browser does not support the video tag.
</video>

JS

const videoSrc = document.querySelector("#video-source");
const videoTag = document.querySelector("#video-tag");
const inputTag = document.querySelector("#input-tag");

inputTag.addEventListener('change',  readVideo)

function readVideo(event) {
  console.log(event.target.files)
  if (event.target.files && event.target.files[0]) {
    var reader = new FileReader();
    
    reader.onload = function(e) {
      console.log('loaded')
      videoSrc.src = e.target.result
      videoTag.load()
    }.bind(this)

    reader.readAsDataURL(event.target.files[0]);
  }
}

但对于其他方法,我可能会使用 http://ffmpeg.org/ 库来生成预览视频(例如 10 秒视频)和 https://videojs.com 库用于视频播放器,因此您可以在用户悬停播放器时进行控制。

【讨论】:

  • 我不想制作视频播放器。我只想将我的视频预览为画布元素,我希望它成为画布的原因是我不希望我的用户下载所有视频主页。如果您使用我评论过的那部分,我的代码可以工作,但我不想使用 addeventlistener 以及为什么我们不能在课堂上使用它。无论如何感谢您的回复。
【解决方案2】:

我刚刚对您的代码进行了一些测试,您的视频仅被搜索一次。之后不会引发任何事件,这意味着您的缩略图将保持不变。

这是我如何修复它的方法

    function generateVid() {
            var d = (video.duration / vidFrames) * 2;
             generateThumbnail();
            i += video.duration / vidFrames;
            
            if (i <= video.duration) {
               video.currentTime = i;
                console.log("starting seeking");
                
                if(d == i){
                    startAnim();
                }
                 
            }
            
        }
        
        video.onseeked = (event) => {
        if (animstop == false)
            {
            setTimeout(generateVid, delay); 
            }

        console.log("seeked");
        };

【讨论】:

  • 我的代码中有一个 seek 事件,我在其中发表了评论,但我不想使用事件监听器。
  • @Ram 如果您不想使用事件侦听器,那么您的脚本将启动并运行得太快。它甚至会在您的第一个缩略图被渲染之前完成。
猜你喜欢
  • 2017-08-25
  • 2013-01-28
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多