更改动画精灵表时,HTML5 Canvas挂起(逐帧视频播放)

Ban*_*ath 5 video mobile jquery html5

我需要使用HTML5在移动设备上播放具有透明背景的视频.在Windows Phone上,我可以捕获视频标签的当前帧并在画布中显示.但这在Android和iOS设备上不起作用(我认为出于安全原因?)

我的解决方案是使用FFMPEG分割.flv,然后将这些帧拼接成大图像,如精灵表.

问题是当我切换到新的框架表时动画"挂起".我只是通过视觉和控制台检查了这一点(当我更改当前的精灵表行时通过记录.)我通过查看当我更改精灵表时它是如何挂起来测试它,以及当我更改它时它是如何挂起的只是一遍又一遍地循环同一张纸.

我预先加载了所有图像:

var frameImages = [];

for(var i = 0; i < 35; i++)
{
  frameImages.push(new Image());
  frameImages[i].src = 'frame' + i + '.png';

  console.log(frameImages[i].src);

  frameImages[i].onload = function()
  {
    // Notify us that it's been loaded.
    console.log("Image loaded");
  }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样玩:

processFrame = function()
{
    outputCanvas.width = outputCanvas.width;
    output.drawImage(frameImages[currentFrame], (curCol*153), (curRow*448), 153, 448, 0, 0, 153, 448);
    curCol += 1;

    if(curCol >= maxCol)
    {
      curCol = 0;
      curRow += 1;

      if(curRow >= maxRow)
      {
        curRow = 0;
        currentFrame++;
      }
    }
  }
}

var mozstart = window.mozAnimationStartTime;

step = function(timestamp) {

  var diff = (new Date().getTime() - start) - time;
  if(diff >= frameDelay)
  {
    processFrame();
    time += frameDelay;
  }
}
Run Code Online (Sandbox Code Playgroud)

我在Win 7机器和带Chrome的Nexus 7上的Chrome v 23.0.1271.97 m中尝试了这个.

在这里看到它的运行:
http://savedbythecode.com/spokes/mozanimation.php - 这是使用mozAnimationStartTime
http://savedbythecode.com/spokes/newplayer.php - 这是使用经常调整的每个步骤的JS计时器(来自http://www.sitepoint.com/creating-accurate-timers-in-javascript/)

有任何想法吗?问题是否足够明确?

谢谢,凯文

Cri*_*low 2

很酷的代码。为什么不能只使用视频标签(参见选项 6)?无论如何,我只是列出我能想到的问题,希望对你有帮助:

  1. 更改+++= 1: 是为了与您之前的代码保持一致,并且因为引导 Doug Crockford 的仁慈鬼魂可能有助于消除您的 javascript 代码中的故障。

  2. 您将一堆图像拼接到一个“精灵表”中。当您想要转到下一张纸时,代码就会挂起。因此,因为您的代码尚未工作,所以作为测试,请删除循环遍历每个帧中的子图像的所有循环,并在每次渲染时直接将 frameImages 数组中的每个帧输出到画布,以查看它是否仍然挂起。其结果将让您知道您的代码是否可以到达frameImages 中的下一帧,或者是否不能。这可能会让您更接近错误的根源。

  3. currentFrame 是否用 var 声明且在 processFrame 的范围内?如果没有,只需将 var currentFrame = 0;其放在您定义的上方即可function processFrame(...

  4. 当您说“然后我像这样播放它”时,您是否使用承诺在所有 onloads 触发后等效地调用您的动画启动函数?一种方法是:您可以在每次触发加载时递增计数器一次,每次检查计数器是否等于所需的加载总数,然后才调用动画开始。 我的预感是这是一个缓存问题,因为由于内部结构不同,这些似乎是不同浏览器之间变化最大的问题。

  5. 尝试在drawImage调用之间以及更新currentFrame时清除画布,因为它可能有助于在更改图像时重置画布的内部状态。

  6. 可以使用 HTML5 视频标签实现 Alpha 和透明度。只需使用一些 svg 转换即可。正如这个答案中所说,这些很容易做到