Windows 8 Metro js アプリ (HTML/Javascript/CSS を使用して作成され、今後の Windows 8 の Windows ストアで公開されることを意図したもの) の機能を少し試しながら、非常に単純なテスト アプリケーションを作成しました。特定のビデオに関連付けられた iframe ベースの YouTube プレーヤーを動的に作成します。ここまでは順調ですね。
後で、その iframe で再生されているビデオからフィードバックを取得できるようにしたいと考えました。Google はこれを達成するための広範な支援を提供しており、YouTube iframe API を指すタグを動的に作成する必要があると説明しています。読み込みが完了すると、コードで「onYouTubeIframeAPIReady()」関数が自動的に呼び出されます。プレーヤーを操作する関数を呼び出したり、統計情報を返したり、プレーヤーの状態を監視するイベント ハンドラーをアタッチしたりすることによって、API が最近作成されたプレーヤーで動作する準備ができていることを認識します。簡単ですよね?
残念ながら、これは Windows 8 Metro js アプリには当てはまりません。
アプリは「Web コンテキスト」とは別に、いわゆる「ローカル コンテキスト」で実行されているため、Web 上のリモートリソースを指す < script > タグをこれらのアプリに実際に挿入することはできません。つまり、YouTube iframe API にアクセスしてプレーヤーを処理することはできません。
< script > タグで参照されているコードを調べると、今日の時点で 2 つの関連する .js ファイルがあり、1 つは実際にもう 1 つのファイルを起動しようとしており、その 1 つは (明らかに) 自己完結型であることがわかりました。これを見て、両方の .js ファイルのコピーを取得し、それらをプロジェクトに保存し、すべての変更を行って、プロジェクトがそれらをリモートではなくローカルで参照するようにしました。これで、iframe YouTube プレーヤーから完全に機能するフィードバックが得られました。
しかし、成功したとはいえ、私はここで浮気をしていると思わずにはいられません。制御できない 2 つの .js ファイルのコピーを保存しています。これはすべて、私のアプリで機能させるためだけの「汚いハック」のように感じます。
それで、これを知って、私はあなたに尋ねます: Windows 8 Metro js アプリに埋め込まれた iframe ベースの YouTube プレーヤーを照会および制御できる他の方法はありますか? Google から iframe API を参照できませんか?
また、iframe ベースのプレーヤーは、私が達成しようとしていること (つまり、プレーヤーからタイムリーなフィードバックを得ることができる) に対する真の解決策ではない可能性が非常に高いです。もしそうなら、他に何をお勧めしますか?私はここでほとんどの提案を受け入れます。
興味があれば、これらは私のテスト アプリの「default.html」と「default.js」なので、私が話していることがわかります。
default.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>PruebaYouTube</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!-- PruebaYouTube references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
</head>
<body>
<p id="contentGoesHere">Content goes here</p>
<div id="playerPlaceholder"></div>
<button id="createPlayer" style="display: none">Create Player</button>
</body>
</html>
default.js: ( yt_iframe_api.jsとyt_widgetapi.jsは YouTube API ファイルの私のコピーです)
// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
var currentPlayer,
embeddedText;
function initApp() {
var ytScript = document.createElement('script');
ytScript.src = "/js/yt_iframe_api.js";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(ytScript, firstScriptTag);
}
function onYouTubeIframeAPIReady() {
var createPlayerButton = document.getElementById("createPlayer");
createPlayerButton.style.display = "";
}
function onPlayerReady(event) {
while (embeddedText.firstChild) {
embeddedText.removeChild(embeddedText.firstChild);
}
embeddedText.appendChild(document.createTextNode("Listo!"));
}
function onPlayerStateChange(event) {
while (embeddedText.firstChild) {
embeddedText.removeChild(embeddedText.firstChild);
}
embeddedText.appendChild(document.createTextNode("Estado: " + event.data));
}
function createYouTubePlayer(mouseEvent) {
var playerPlaceholder = document.getElementById("playerPlaceholder");
while (playerPlaceholder.firstChild) {
playerPlaceholder.removeChild(playerPlaceholder.firstChild);
}
var playerFrame = document.createElement("iframe");
playerFrame.id = "playerFrame";
playerFrame.setAttribute("type", "text/html");
playerFrame.style.position = "absolute";
playerFrame.style.top = "100px";
playerFrame.style.left = "100px";
playerFrame.width = "640px";
playerFrame.height = "390px";
playerFrame.src = "http://www.youtube.com/embed/u1zgFlCw8Aw?controls=0&autoplay=1";
playerFrame.frameBorder = "0";
playerPlaceholder.appendChild(playerFrame);
embeddedText = document.createElement("p");
embeddedText.style.fontSize = "24px";
embeddedText.style.position = "absolute";
embeddedText.style.top = "150px";
embeddedText.style.left = "150px";
playerPlaceholder.appendChild(embeddedText);
currentPlayer = new YT.Player('playerFrame', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function attachAllEvents() {
var createPlayerButton = document.getElementById("createPlayer");
createPlayerButton.addEventListener("click", createYouTubePlayer, false);
}
(function () {
"use strict";
WinJS.Binding.optimizeBindingReferences = true;
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
initApp();
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
args.setPromise(WinJS.UI.processAll().done(attachAllEvents));
}
};
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state
// that needs to persist across suspensions here. You might use the
// WinJS.Application.sessionState object, which is automatically
// saved and restored across suspension. If you need to complete an
// asynchronous operation before your application is suspended, call
// args.setPromise().
};
app.start();
})();