2

cue.onenter関数を HTML5 のイベントに動的に割り当てようとしています。これは非常に新しい機能で、現在、特定のフラグが有効になっている 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 アプリケーションとして実行されます。キューを処理する Media Player の完全なソースを以下に示します。

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 に答える