在Javascript中实现倒带功能

时间:2013-12-11 00:44:15

标签: javascript video

我已经用Javascript编写了一个视频播放器,我正在尝试实现一个倒带/转发功能。

目标是按住按钮时视频将重绕。我编写了一个这样的版本,当点击按钮时它将倒回一次,但是你必须不断点击它来连续倒带。

到目前为止,我已经这样做了:

HTML

<video id="media" width="600" height="400" preload="none">
    <source src="files/Best of 60s.m4v">
</video>    

<input type="button" id="skipTrackBackward" value="Backward" onmousedown="rewind()" onmouseup="stoprewind()"/>

使用Javascript:

    var skipB
    function initiate(){
    mmedia = document.getElementById('media');
    skipB = document.getElementById('skipTrackBackward');

function rewind(){
        while (!mmedia.paused && !mmedia.ended){
            for (var i = mmedia.currentTime; i != 0; i--){
                mmedia.currentTime=i;   
            }
        }   
    }

    function stoprewind(){
        mmedia.play();
    }

上面的代码会导致我的Chrome标签崩溃,所以很明显我做错了!但我的理解是,如果视频尚未到达终点或已暂停,我只希望启动回放功能。因此,当它处于该状态时,它应该运行for循环,该循环考虑已经过去的currentTime并且在按下鼠标时减去1秒(currentTime采用被解释为秒的整数)。只要它没有达到0秒,它应该继续更新currentTime。

为方便起见,上面的代码已经过最小化。任何建议都非常感谢。

1 个答案:

答案 0 :(得分:1)

我认为你创建了一个无限循环你的设置mmedia.currentTime为伪造的价值。

首先让我们来解决问题。查看控制台输出的内容,添加一些console.log语句以查看运行时的值以及崩溃前的值是什么,逐步调试调试器中的代码(使用条件断点来滤除噪声)

现在进行代码分析。尝试用硬编码值替换变量,看看逻辑是否平仓:

while (!mmedia.paused && !mmedia.ended) {
 ^1       ^2                  ^3
  1. 为什么一会儿?是否需要运行for循环直到mmedia.pausedmmedia.ended
  2. 此变量何时更改为突破循环?
  3. 或者这个变量?
  4. 因此,当执行for循环时,没有任何内容可以导致mmedia.pausedmmedia.ended false 更改为 true ,这是一个无限循环。

    另外,您检查i != 0是否可以< 0?如果是这样,mmedia.currentTime会处理小于0的值吗?

    最后但并非最不重要的是,如果您要暂停while / for循环,则它处于阻塞过程中。这意味着如果您依赖用户交互来翻转其中一个取消标记,那么它将永远不会发生,因为线程在注册用户执行某些操作之前等待while / for循环完成。如果修复了无限循环,则单击将阻止暂停/停止按钮被点击直到它到达开头(显然这很愚蠢,因为你可以先将currentTime设置为0)。另一个影响是你不会看到倒带过程,因为在线程完成代码完成之前它不会更新显示。

    您需要以非阻塞方式重写逻辑。这称为异步代码,比简单循环复杂得多。

    var stopRewinding;
    
    function rewind() {
      var timeout = 100;
      stopRewinding = false;
    
      if (mmedia.paused || mmedia.ended) {
        console.log("Media state unable to rewind");
        return;
      }
    
      function worker() {
        if (stopRewinding || mmedia.currentTime <= 0) {
          return; // All done so get outa here
        }
    
        mmedia.currentTime--;
    
        setTimeout(worker, timeout);
      }
    
      worker();
    }
    

    现在,您可以通过将stopRewinding设置为 true currentTime达到0来中断循环。

    然后,您可以使用按钮或使用mousedownmouseup事件触发rewind()stopRewinding = true