0

我将 Github xAPI 脚本用于“播放 youtube 视频”并尝试对其进行修改以显示两个视频而不是一个。最终,我想在此页面中列出五六个视频。不幸的是,我不能让它一次显示多个视频。相反,它只显示一个视频,这是我列出的第二个视频。有人可以告诉我如何修改此代码以列出多个视频吗?此外,出于显而易见的原因,我在发布此问题之前更改了我的 LRS 凭据。非常感谢。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1.0, maximum-scale=2.0">
  <meta name="description" content="A shorthand syntax for communicating xAPI Statements">
  <meta name="author" content="ADL">
  <link rel="icon" href="favicon.ico">

  <title>xAPI Youtube Video Tracking</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
</head>

<body>

  <section class="container">

    <div class="page-header">
      <h1 class="text-primary"><i class="fa fa-youtube"></i> xAPI Youtube Video Tracking</h1>
      <h3 class="text-muted">Send Youtube Video interactions to an LRS with xAPI</h3>
    </div>

    <div class="row">

      <div class="form-group col-md-12">

        <div id="player"></div>

        <div id="player2"></div>

        <p>This example uses minimal javascript and the youtube <a href="https://developers.google.com/youtube/iframe_api_reference" target="_blank">iframe API</a>.</p>
        <p>Statements are built with xapi-youtube-statements.js and dispatched to an LRS with xapiwrapper.min.js using a custom ADL.XAPIYoutubeStatements.onStateChangeCallback function.</p>
        <p>You can view statements <a href="http://adlnet.github.io/xapi-statement-viewer/">with the statement viewer</a>.</p>

      </div><!-- .col-md-12 -->

    </div><!-- .row -->

  </section><!-- .container -->

  <script type="text/javascript" src="lib/xapiwrapper.min.js"></script>
  <script type="text/javascript" src="src/xapi-youtube-statements.js"></script>

  <script>

    var video = "6hwHKOYCYL4"; // Change this to your video ID
    var videoName = "Microlearning vs Traditional Learning";


    var video2 = "SUJkBCHB4vQ"; // Change this to your video ID
    var videoName2 = "Micro Learning is a BIG deal";





    // "global" variables read by ADL.XAPIYoutubeStatements
    ADL.XAPIYoutubeStatements.changeConfig({
      "actor":  {"mbox":"mailto:john.menken@syniverse.com", "name":"John M."},
      "videoActivity": {"id":"https://www.youtube.com/watch?v=" + video, "definition":{"name": {"en-US":videoName}} }
    });

    ADL.XAPIYoutubeStatements.changeConfig({
      "actor":  {"mbox":"mailto:john.menken@syniverse.com", "name":"John M."},
      "videoActivity": {"id":"https://www.youtube.com/watch?v=" + video2, "definition":{"name": {"en-US":videoName2}} }
    });





    function initYT() {
      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }

    var player;
    function onYouTubeIframeAPIReady() {
      player = new YT.Player('player', {
        height: '390',
        width: '640',
        videoId: video,
        playerVars: { 'autoplay': 0 },
        events: {
          'onReady': ADL.XAPIYoutubeStatements.onPlayerReady,
          'onStateChange': ADL.XAPIYoutubeStatements.onStateChange
        }
      });
    }


    var player2;
    function onYouTubeIframeAPIReady() {
      player2 = new YT.Player('player2', {
        height: '390',
        width: '640',
        videoId: video2,
        playerVars: { 'autoplay': 0 },
        events: {
          'onReady': ADL.XAPIYoutubeStatements.onPlayerReady,
          'onStateChange': ADL.XAPIYoutubeStatements.onStateChange
        }
      });
    }



    initYT();



    // Auth for the LRS
    var conf = {
        "endpoint" : "https://www2.test.com/test/ScormEngineInterface/TCAPI/",
        "auth" : "Basic " + toBase64("test:test"),
    };

    ADL.XAPIWrapper.changeConfig(conf);

    /*
     * Custom Callbacks
     */
    ADL.XAPIYoutubeStatements.onPlayerReadyCallback = function(stmt) {
      console.log("on ready callback");
    }

    // Dispatch Youtube statements with XAPIWrapper
    ADL.XAPIYoutubeStatements.onStateChangeCallback = function(event, stmt) {
      console.log(stmt);
      if (stmt) {
        stmt['timestamp'] = (new Date()).toISOString();
        ADL.XAPIWrapper.sendStatement(stmt, function(){});
      } else {
        console.warn("no statement found in callback for event: " + event);
      }
    }

  </script>

</body>
</html>
4

1 回答 1

1

onYouTubeIframeAPIReady在设置第一个回调后立即覆盖回调,因此当 iframe 准备好时,第一个回调不再是该函数的值。(必须异步思考。)该函数应该只被调用一次,并且应该只有一个定义。为了使这项工作,您需要将实例化移动player2onYouTubeIframeAPIReady函数中。(这部分是onYouTubeIframeAPIReady 调用一次但页面上需要多个视频的副本)

另请注意,ADL 的包装器有效地使用单例与 LRS 通信,因此您将获得两个视频的所有语句,其中活动作为第二个视频的对象(因为它是稍后调用changeConfig)。除了使用您自己的函数包装他们的状态更改处理程序之外,我没有看到解决此问题的方法,该函数在changeConfig每次事件发生时调用,即使那样您也有可能出现竞争条件。

于 2016-10-21T19:42:04.267 回答