在Windows 8 Metro js应用程序中控制iframe YouTube播放器



在尝试Windows 8 Metro js应用程序(使用HTML/Javascript/CSS创建的应用程序,旨在发布在即将推出的Windows 8的Windows应用商店上)的功能时,我去创建了一个非常简单的测试应用程序,它可以动态创建一个基于iframe的YouTube播放器,并与特定的视频绑定。到目前为止,一切都很好。

后来,我希望能够从iframe上播放的视频中获得反馈。谷歌为实现这一点提供了广泛的帮助,并解释说,你需要动态创建一个指向YouTube iframe API的标签,然后,一旦它完成加载,它将自动调用代码中的"onYouTubeIframeAPIReady()"函数,这样它就知道API已经准备好与你最近创建的播放器一起操作,以及除返回统计信息之外的其他信息,甚至附加监视玩家状态的事件处理程序。很简单,对吧?

不幸的是,Windows 8 Metro js应用程序并非如此。

事实证明,由于应用程序运行在所谓的"本地上下文"中,与"网络上下文"不同,您实际上无法插入<script>标记指向这些应用程序在Web上的远程资源。这意味着,我将永远无法访问YouTube iframe API来处理我的播放器。

现在,检查<script>tag,我意识到,截至今天,有两个相关的.js文件,一个实际上试图启动另一个,其中一个(显然)是自包含的。看到这一点后,我获取了两个.js文件的副本,将它们存储到我的项目中,完成了所有的更改,因此项目在本地引用了它们,而不是远程引用,瞧!现在我有了来自iframe YouTube播放器的全功能反馈!

然而,尽管我已经成功了,我还是忍不住认为我在这里作弊。我正在保存两个我不应该控制的.js文件的副本。所有这些感觉就像是一个"肮脏的黑客",只是为了让我的应用程序正常工作。

因此,知道这一点,我问你:有没有其他方法可以让我查询并控制嵌入到我的Windows 8 Metro js应用程序中的基于iframe的YouTube播放器,因为我知道由于"本地上下文"的限制,我根本无法引用谷歌的iframe API?

此外,基于iframe的播放器很可能不是我想要实现的目标的真正解决方案(也就是说,能够及时从玩家那里获得反馈)。如果是,你还推荐什么?我对这里的大多数建议持开放态度。


如果你感兴趣,这些是我的测试应用程序的"default.html"one_answers"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.jsyt_widgetapi.js

// 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();
})();

我是这样做的,希望能对你有所帮助。我使用jQuery进行ajax调用,并使用Player Framework显示视频:

$.ajax({
url: "http://www.youtube.com/watch?NR=1&v=ZBDmUqp0JTU&feature=endscreen&nomobile=1",
success: function (request) {
var reg = new RegExp(/url_encoded_fmt_stream_map=(.*?)(&|")/);
var match = reg.exec(request);
var data = decodeURIComponent(match[1]);
var arr = data.split(",");
var youtube = [];
var cont = 0;
for (var d in arr) {
var url = "";
var signature = "";
var tuple = {};
var _d = arr[d].split('&');                    
for (var p in _d) {
var _p = _d[p];                        
var index = _p.indexOf('=');                        
if (index != -1 && index < _p.length) {
try {
var key = _p.substring(0, index);
var value = decodeURIComponent(_p.substring(index + 1));
if (key == 'url') {
url = value;
} else if (key == 'itag') {
tuple.Itag = parseInt(value);
} else if (key == 'type' && value.indexOf("video/mp4") > -1) {
tuple.Type = value;
} else if (key == 'sig') {
signature = value;
}
} catch(e) {}                                                        
}
};
tuple.url = url + "&signature=" + signature;
if (url != null && tuple.Itag > 0 && tuple.Type != null && tuple.Type.indexOf("video/mp4") > -1) {
youtube.push(tuple.url);
}
cont++;
if (cont == arr.length) {                        
var xvideo = document.getElementById("xvideo");
var control = new PlayerFramework.MediaPlayer(xvideo);
control.height = 600;
control.width = 800;
control.src = youtube[0];
control.load();
console.log("rVideo MP4:r", youtube[0]);
};
};

}
});

这并不完美,但你有这个想法。

这是我取代码的地方:https://mytoolkit.svn.codeplex.com/svn/Shared/Multimedia/YouTube.cs

附言:很抱歉我的英语不好,我来自秘鲁;)

最新更新