HTML5 Track Element Cue Events Buggy?

时间:2012-09-20 18:12:30

标签: javascript node.js html5 html5-audio

我正在尝试动态地为HTML5的cue.onenter事件分配函数。这是一项非常新的功能,目前仅在启用了特定标记的Chrome中受支持(请参阅HTML5 Rocks上的示例here)。

然而,由于早期开发或者我做错了,它确实是错误的。基本上,我在普通的HTML页面上有一个track元素。没什么特别的。

<audio id="audiocast" controls oncanplay="setReadyToPlay();">
            <source id="audiosource" src="SomeWorkingUrlwithaudio" ></source>
            <track kind="metadata" id="audioTrack" label="slides" src="/data.vtt" default >
            </track>
            Your Browser does not support HTML5
        </audio>

我通过JavaScript访问它,如下:

//(...)
var trackElements = $("#audiocast")[0].children("track")[0];
        _track = trackElements.track;
        _cues = _track.cues;

        for (var j = 0; j < _cues.length; ++j) {
            var cue = _cues[j];
            cue.onenter = getOnEnter(j);
        }

//(...)
function getOnEnter(idx) {
    return function() {
        setCueIdx(idx);
        updateURL(idx);
        var json = JSON.parse(this.text);

        _currImgSrc = json.src;
        drawIt();
    }
};

然而,这只在某些时候起作用。有时我必须重新加载浏览器3次才能使用(例如,当我输入提示时绘制图像),或它工作时,它随机工作直到达到10的提示4和然后停止工作。

这没有任何意义,但也许你们中的一些人知道如何为此提供后备和稳定性解决方案。

其他信息:这是作为Node.js应用程序运行的。处理提示的媒体播放器的完整来源如下。

请注意,由于Stack Overflow的脚本沙盒,该代码段无法正常工作。

/*
 * slideCastController.js
 * © by pschne2s, nkopp2s, 2012
 *
 * Basically encapsulates the Media Player Object, handling the function of the HTML5-Player
 */

/****************************OBJECT DEFINITION***********************************/

CanvasRenderingContext2D.prototype.clear = CanvasRenderingContext2D.prototype.clear ||
  function(preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }

    this.clearRect(0, 0, this.canvas.width, this.canvas.height);

    if (preserveTransform) {
      this.restore();
    }
  };

var mediaPlayer = (function() {
  //Members
  var _cueIdx = 0;
  var _cues = [];
  var _target;
  var _track;
  var _readyToPlay = false;
  var _currImgSrc;

  function setupCues() {
    if (_readyToPlay) {
      if (_track === undefined) {
        // var trackElements = document.getElementById("audioTrack");
        var trackElements = $(_target).children("track")[0];
        _track = trackElements.track;
      }
      _cues = _track.cues;

      $("#maxcues").text(_cues.length - 1);
      for (var j = 0; j < _cues.length; ++j) {
        var cue = _cues[j];
        cue.onenter = getOnEnter(j);
      }

      _track.oncuechange = function() {
        //updateURL(mediaPlayerInfo.cueIdx);
      };

      checkFragments();
    } else {
      setTimeout(setupCues, 1);
    }
  };

  function getOnEnter(idx) {
    return function() {
      setCueIdx(idx);
      updateURL(idx);
      var json = JSON.parse(this.text);

      _currImgSrc = json.src;
      drawIt();
    }
  };

  function drawIt() {
    var ctx = $("#slide")[0].getContext('2d');
    ctx.clear();

    var tmpImg = new Image();
    tmpImg.onload = function() {
      ctx.drawImage(tmpImg, 0, 0, 592, 256);
    }

    tmpImg.src = _currImgSrc;

  }

  function checkFragments() {
    var fragments = purl(window.document.URL);
    var slide = fragments.fparam("slide");
    if (slide !== undefined) {
      gotoCue(slide);
    }
    var action = fragments.fparam("action");
    if (action == "play") {
      _target.play();
    }
  };

  function setCueIdx(idx) {
    //alert("Cue idx set to: " + idx);
    _cueIdx = idx;
    $("#cueidx").text(idx);
  };

  function gotoCue(index) {
    if (index >= 0 && index < _cues.length) {
      _cueIdx = index;
      var audioElement = $("#audiocast").get(0);
      //mediaPlayerInfo.cues[mediaPlayerInfo.cueIdx].onenter();
      audioElement.currentTime = _cues[index].startTime;
    }
  };

  var updateURL = (function() {
    // set Base-URL (without query/hash-String)
    var url = location.protocol + "//" + location.host + location.pathname;
    var html5 = window.history.replaceState !== undefined ? true : false;

    return function(slideIdx) {
      if (html5)
        window.history.replaceState(null, document.title + " | Slide #" + slideIdx, url + "#slide=" + slideIdx);
      else
        location.href = url + "#slide=" + slideIdx;
      // No nice browser history
    };
  })();

  return {
    init: function() {
      setupCues();
    },
    setTarget: function(obj) {
      _target = obj;
    },
    setTrack: function(obj) {
      _track = obj;
    },
    setReadyToPlay: function() {
      _readyToPlay = true;
    },
    gotoNextCue: function() {
      gotoCue(_cueIdx + 1);
    },
    gotoPrevCue: function() {
      gotoCue(_cueIdx - 1);
    }
  };
})();

$(document).ready(function() {
  // "Unobstrusive" Function-Bindings
  $("#btnPrevCue").bind("click", mediaPlayer.gotoPrevCue);
  $("#btnNextCue").bind("click", mediaPlayer.gotoNextCue);

  mediaPlayer.setTarget($("#audiocast")[0]);
  mediaPlayer.init();
});

window.setReadyToPlay = mediaPlayer.setReadyToPlay;
// does not work using other ways atm

1 个答案:

答案 0 :(得分:0)

从原始问题复制的内容

显然,音频/音轨元素确实非常错误。然而,&#34; oncuechange&#34;似乎工作得很好。我现在就这样做了:

var _cueLookup = new Object();

_cues = _track.cues;  //track-element cues.
for (var j = 0; j < _cues.length; ++j) {
            var cue = _cues[j];
            //cue.onenter = getOnEnter(j);
            _cueLookup[cue.id] = j;
            //alert(_cueLookup[cue.id]);
        }

_track.oncuechange = function() {
            // "this" is a textTrack
            var cue = this.activeCues[0]; // assuming there is only one active cue