2

我正在尝试将函数动态分配给 HTML5 的cue.onenter事件。这是一个非常新的功能,目前仅在启用了特定标志的 Chrome 中支持(请参阅此处的 HTML5 Rocks 示例)。

但是,由于早期开发,它确实存在错误,或者我做错了什么。基本上,我在普通的 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

4

1 回答 1

0

从原始问题复制的内容


显然,音频/轨道元素确实有很多问题。然而,“oncuechange”似乎运作良好。我现在是这样的:

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
于 2015-10-22T18:15:41.020 回答