Soapbox 视频小工具






4.97/5 (33投票s)
2007 年 3 月 7 日
7分钟阅读

200628

753
将 MSN 视频的强大功能集成到您的 Windows Vista 边栏中,尽在 Soapbox。创建和分享您最喜爱的视频列表
- 下载小工具的源代码 - 193 KB
- 将最新小工具安装到您的边栏 - 193 KB
- 收藏的视频列表示例(XML 文件)- 45 KB (右键单击,另存为…,然后在“小工具设置 -> 视频源下拉菜单 -> 共享收藏”中单击打开)
引言
当我刚开始边栏小工具开发1时,我觉得小工具很酷且富有创新性。但随着我对它们了解越多,我越意识到它们的实用性。小工具开发提供了一个全新的平台,以意想不到的方式提高了生产力。一方面,它是一个可以托管网页、调用 Web 服务并使用 AJAX 读取 RSS 源的迷你 Web 应用程序。另一方面,它可以通过 .NET 语言的力量与 Windows API 进行交互。哇!这是两全其美,您同意吗?
最重要因素是小工具在 Web、Windows 和用户之间提供交互的独特方式。在此示例中,我试图利用这一点,赋予用户边栏中的“视频力量”。请查看下面的架构。
为了保持您的兴趣,这是它在边栏中的样子。
关于小工具:视频的力量
在我开始之前,我必须警告您:这个小工具非常容易上瘾。只在您的空闲时间沉迷其中。
在 MSN 视频 Beta 页面上的 Soapbox 上有许多可用的 RSS 源,它们提供了用户上传的视频内容。一些比较有趣的包括:“最受欢迎的视频”、“评分最高的视频”和“最新视频”。甚至还有一个“按标签搜索视频”的源,我们将用它来搜索视频。其背后的想法是使用这些定期更新的源来向用户显示边栏上的他/她选择的视频。如果您想知道创建小工具所需的基本要素,请参阅我的第一篇文章 Daily Dilbert。这篇文章实际上是那篇第一篇文章的扩展;我只尝试解释那些可以进一步改进小工具的额外功能。
- 创建一个可以在弹出窗口中播放视频的小工具
- 如何处理读取 XML 文件时的分页
- 设置和搜索视频
- 将视频添加到“收藏夹列表”
- 从边栏小工具创建、读取、更新和删除本地 XML 文件(新)
- 一些通用技巧
架构概述
让我们开始...
创建视频小工具
需要一个名为 Gadget.xml 的标准 XML 文件,如下所示
有关此内容的更多信息,请在此处 获取。
小工具的名称是“Soapbox @ MSN”(如上所示)。命名空间基本上是为了将多个小工具(保留供将来使用)分组,您可以将其写入“mynamespace
”。MinPlatformVersion. Required. 预期值为“1.0
。”
“Permission”控制小工具的权限级别。“Full”权限如果您想通过小工具访问网页是必需的。有了这两个文件,您就可以在边栏中部署和测试您的小工具了。<permission>
标签和 <type>
标签在未来版本的小工具开发中会更加灵活。
我们的视频小工具将包含以下文件
Gadget.xml | 一个 XML 文件,定义小工具的属性,包括名称、图标和描述 |
main.html | 主 HTML 页面 |
main.js | 小工具的核心代码/脚本 |
Settings.html | 暴露小工具设置供用户更改 |
Settings.js | 设置文件的脚本 |
soapboxFlyout.html | 将在弹出窗口中使用 HTML 文件 |
图标、图像等 | 用于小工具选择框 |
您可以在此处 获取 更多关于这些的详细信息。
获取 RSS 源
Main.html 文件将包含五个元素(“DIV
”)来获取源数据:cell0
、cell1
等。我们可以将视频显示为五个视频的列表(如下所示)或单个视频。
小工具的源
我们有一个 URL,我们使用 MSXML2.XMLHTTP
对象进行调用。这是 AJAX 的核心,直到源加载为止。这是神奇的 JavaScript
function getRSS()
{
document.getElementById("mylogo").Title =
System.Gadget.Settings.
read("feedText");
try
{
error.style.visibility = "hidden";
loading.style.visibility = "visible";
rssObj = new ActiveXObject("Msxml2.XMLHTTP");
rssObj.open("GET",
System.Gadget.Settings.read("videoFeed") , true);
rssObj.onreadystatechange = function() {
if (rssObj.readyState = == 4)
{ if (rssObj.status == 200)
{ loading.innerText = "";
error.innerText = "";
error.style.visibility= "hidden";
loading.style.visibility = "hidden";
rssXML = rssObj.responseXML;
page = 0;
parseRSS();
if
(chkConn) { setInterval(getRSS, 60 * 60000);
loading.style.visibility = "hidden";
}
}
else
{
var chkConn;
loading.style.visibility = "visible";
chkConn = setInterval(getRSS, 30 * 60000);
}
} else {
loading.style.visibility = "visible";
}
}
rssObj.send(null);
}
catch(err)
{
loading.style.visibility = "hidden";
error.innerText = " Service not available";
error.style.visibility = "visible";
}
}
服务不可用
如您所见,如果在连接源时出现错误或互联网连接出现错误,我们希望显示“服务不可用”屏幕。
解析 XML 文件
这是 XML 文件中单个项目的 RSS 源的一部分,以及相应的“部分”ParseXML 文件,让您了解我们如何处理源。
function parseRSS(page)
{
rssItems = rssXML.getElementsByTagName("item");
rssTitle = null; rssAuthors = null; rssDescription = null;
rssLink = null;
rssTitle = escape(rssItems[i].firstChild.text);
rssLink =rssItems[i].getElementsByTagName("guid")[0]
.firstChild.nodeValue;
rssViews = rssItems[i].getElementsByTagName("vidAt:playCount")[0]
.firstChild.nodeValue;
rssDateUpdate = rssItems[i].getElementsByTagName("vidAt:pubDate")[0]
.firstChild.nodeValue;
rssRatingValue = rssItems[i].getElementsByTagName("vidAt:rating")[0]
.firstChild.nodeValue;
rssDuration = rssItems[i].getElementsByTagName("vidAt:duration")[0]
.firstChild.nodeValue;
rssVDescription= escape(rssItems[i].getElementsByTagName
("vidAt:description")[0].firstChild.nodeValue);
rssDescription=rssItems[i].getElementsByTagName("description")[0]
.firstChild
.nodeValue;
myTitle = unescape(rssTitle)
myTitle1 = myTitle.substr(0,16);
myRatingTip = "Rating: " + rssRatingValueFormated2 + ",
View: "
+ rssViews + ", Duration: " + rssDurationFormated ;
document.getElementById("cell" + (cell)).innerHTML =
"onclick="
showFlyout(\'' + rssTitle + '\',\'' + rssVDescription + '\',
\'' + rssLink + '\',\'' + rssImage + '\',\'' + rssRImage + '\',\''
+ rssViews + '\',
\'' + rssDateUpdate + '\',\'' + rssDurationFormated + '\',
\'' + rssRatingValueFormated2 + '\');" >
}
既然我们有了所需的源,我们就可以从视频创建弹出窗口。这是 showFlyout
函数,它是动态创建的,用于将所有参数从项目传递到弹出窗口页面。
function showFlyout(sTitle,sDescription,sGuid, sImage, sRImage,sView,
sDateUpdate,sDuration,sRatingFormated)
{
if (System.Gadget.Settings.read("sTitle")==sTitle)
{
System.Gadget.Settings.write("sTitle", "myTitle");
hideFlyout();
}
else
{
System.Gadget.Settings.write("sTitle", sTitle);
System.Gadget.Settings.write("sView", sView);
System.Gadget.Settings.write("sDateUpdate", sDateUpdate);
System.Gadget.Settings.write("sGuid", sGuid);
System.Gadget.Settings.write("sDescription", sDescription);
System.Gadget.Settings.write("sImage", sImage);
System.Gadget.Settings.write("sRImage", sRImage);
System.Gadget.Settings.write("sRatingFormated",
sRatingFormated);
System.Gadget.Settings.write("sDuration", sDuration);
System.Gadget.Flyout.file = "soapboxFlyout.html";
System.Gadget.Flyout.show = true;
}
}
小工具的其他设置
除了在 showFlyout
函数上设置的设置外,还有其他设置可以由用户管理。用户可以在“视频”下搜索或从其中一个视频源中选择。
一旦我们获得所有设置,我们就会在弹出窗口中 Build
video
对象。
function BuildVideoObject()
{
try
{
if (System.Gadget.Settings.read("videoSize")
=="large")
{
Video_HtmlString = '‹OBJECT id="VIDEO"
width="640" height="480" ';
}
else
{
Video_HtmlString = '‹OBJECT id="Body1"
width="320" height="240" ';
}
Video_HtmlString += 'style="position:absolute; left:0;top:0;"';
Video_HtmlString += 'CLASSID="CLSID:6BF52A52-394A-11d3-B153-"';
Video_HtmlString += 'type="application/x-oleobject"
VIEWASTEXT›';
Video_HtmlString += '‹PARAM NAME="URL" VALUE="';
Video_HtmlString +=
"http:/soapbox.msn.com/StreamingUrl.aspx?vid="
+ System.Gadget.Settings.read("sGuid");
Video_HtmlString += '"›‹param NAME="stretchToFit"
VALUE="1"›';
Video_HtmlString += '‹param name="AutoSize"
value="1"›
‹PARAM NAME="SendPlayStateChangeEvents"
VALUE="True"›';
Video_HtmlString += '‹PARAM NAME="AutoStart"
VALUE="True"›';
Video_HtmlString += '‹PARAM name="uiMode"
value="none"›';
Video_HtmlString += '‹PARAM name="PlayCount"
value="9999"›';
Video_HtmlString += '‹/OBJECT›';
document.write(Video_HtmlString);
}
catch (err)
{
document.write("Problem with the machine's Windows Media
Player");
}
}
有关弹出窗口的更多信息,请在此处 获取。
分页
由于 XML 文件可能包含数百个项目,我们需要能够分页。因此,我们在 main.html 文件中添加了一个 DIV
项,内容如下
‹div id="tbar" title=""›
‹table width="100%" height="100%" border="0" cellpadding="2" cellspacing="0"
ID="Table2"›
‹tr align="center" valign="middle"›
‹td width="12" class="arrow" onclick="chPage(-999);" align="right"›
«‹/td›
‹td width="12" class="arrow" onclick="chPage(-1);" align="right"›
‹b›‹‹/b›‹/td›
‹td class="sub" id="pageNum"›1/1‹/td›
‹td width="12" class="arrow" onclick="chPage(+1);" align="left"›
‹b››‹/b›‹/td›
‹td width="12" class="arrow" onclick="chPage(+999);" align="left"›
»‹/td›
‹/tr›
‹/table›
‹/div›
更改页面函数将解析内容的项目到该页面。
function chPage(off)
{
try
{
if (System.Gadget.Settings.read("listview"))
{
if (rssItems.length < 100)
{
myval = Math.ceil (rssItems.length/5);
}
else
{myval = 20;}
}
else
{
if (rssItems.length < 100)
{
myval = rssItems.length;
}
else
{myval = 100;}
}
if (off === -999)
{
off = myval-page;
}
if (off === 999)
{
off = myval-page-1;
}
try
{
if (((page + off) > -1) && ((page + off) < myval))
{
page = page + off;
parseRSS(page);
} else if ((page + off) === myval)
{
page = 0;
parseRSS(page);
} else if ((page + off) === 0)
{
page = myval;
parseRSS(page);
}
}
catch (err)
{
}
}
catch (err)
{
}
}
制作您自己的收藏视频列表
现在,每个视频的底部都会有一个加号图标,您可以将视频添加到您的收藏夹列表。
部分后台代码
function addtoFavorites(sGuid)
{
var variableName = "userprofile";
var mytext ="Testing";
try
{
var variableName = "userprofile";
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.load(System.Environment.getEnvironmentVariable
(variableName) + "\\Videos\\SoapBoxFavorites.xml");
xmlObj=xmlDoc.documentElement;
rssAddItems = xmlObj.getElementsByTagName("channel");
rssAddedItems= xmlObj.getElementsByTagName("item");
var varAlreadythere = false;
if (rssItems[i].getElementsByTagName("guid")[0]
.firstChild.nodeValue == sGuid)
{
if (!varAlreadythere)
{
rssAddItems[0].appendChild(rssItems[i]);
}
break;
}
xmlDoc.save(System.Environment.getEnvironmentVariable
(variableName) + "\\Videos\\SoapBoxFavorites.xml");
当您单击“添加到收藏夹”图标时,它会将该视频的 XML 源信息从在线源添加到本地 XML 文件中。
%userprofile%/Video/soapboxfavorites.xml
这里是查看您收藏视频的新设置。选择“我的收藏视频”以查看书签视频。
如果选择了任何“我的收藏”,小工具将从本地 XML 文件中读取。
部分后台代码
if (System.Gadget.Settings.read("feedText").indexOf("My favorite") >=0)
{
try
{
var variableName = "userprofile";
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.load(System.Environment.getEnvironmentVariable(variableName)
+ "\\Videos\\SoapBoxFavorites.xml");
rssXML=xmlDoc;
parseRSS();
}
默认情况下,“我的收藏视频”列表将显示来自“当前精选源”的九个视频。
首次从“当前精选源”创建 XML 文件。
部分后台代码
var variableName = "userprofile"
var SoapboxFavoritesPath = System.Environment.getEnvironmentVariable
(variableName) + "\\Videos\\SoapBoxFavorites.xml";
rssObj = new ActiveXObject("Msxml2.XMLHTTP");
rssObj.open("GET",System.Gadget.Settings.read("videoFeed"),true);
rssObj.onreadystatechange = function()
{
if (rssObj.readyState === 4)
{
if (rssObj.status === 200)
{
try
{
System.Shell.itemFromPath(SoapboxFavoritesPath);
return;
}
catch (notFound)
{
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1;
stream.Open();
stream.Write(rssObj.responseBody);
stream.SaveToFile(SoapboxFavoritesPath, 2);
stream.Close;
stream = null;
}
您也可以从视频列表中删除视频。选择我的收藏视频,然后您会在小工具中看到每个视频后面的“删除图标”。
删除的后台代码
function removefromFavorites(sGuid)
{
var variableName = "userprofile";
var mytext ="Testing";
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.load(System.Environment.getEnvironmentVariable
(variableName) + "\\Videos\\SoapBoxFavorites.xml");
xmlObj=xmlDoc.documentElement;
rssRemoveItems = xmlObj.getElementsByTagName("item");
if (rssRemoveItems[i].getElementsByTagName("guid")
[0].firstChild.nodeValue==sGuid)
{
var lastNode=rssRemoveItems[i];
var delNode=xmlObj.firstChild.removeChild(lastNode);
xmlDoc.save(System.Environment.getEnvironmentVariable
(variableName) + "\\Videos\\SoapBoxFavorites.xml");
mytext = "Deleted and Saved";
break;
}
}
这样我们就完成了!
通用技巧
- 要将 Windows Media Player 调整为自定义宽度,请设置
‹param name="AutoSize" value="1"›
- 边栏小工具主窗口中的任何异常都应通过“服务不可用”屏幕和如图所示的信息图标进行处理
- 每当您使用 JavaScript 函数时,请将其封装在
try catch
语句中,以避免意外 - Escape(^)和 unescape(^)是 URL 编码和解码的有用 JavaScript 函数,当您需要将 URL 等作为参数传递给弹出窗口时
<
的 HTML 代码是“«
”,<<
是“‹
”,>>
是“›
”,而>
是“»
”- 要检查文件是否存在于本地文件夹中,请在
try catch
中使用System.Shell.itemFromPath(Path)
- 要实现计时器功能,请使用
setinterval
4 方法 - 要支持多语言,请为该语言创建一个文件夹(例如,'IT-CH',如果语言是
it-ch 意大利语-瑞士
),并将 'EN-US' 文件夹中的所有文件复制到新创建的文件夹中(语言代码 ^) - 查看设计概念和使用模式5
实际应用
Soapbox 小工具实况:尺寸:400 X 360(Flash 播放器)
参考文献
文章历史
- 2007 年 3 月 7 日:首次发布
- 2007 年 3 月 8 日:增加了对 Flash 播放器的支持
- 2007 年 3 月 9 日:“检查更新的源”时间间隔更改为 30 分钟
- 2007 年 3 月 11 日:添加了架构图
- 2007 年 3 月 20 日:创建“我的收藏视频”
- 2007 年 3 月 23 日:保存您的收藏视频列表以供分享
- 2007 年 3 月 23 日:打开共享的收藏视频列表(已添加示例)
- 2007 年 4 月 2 日:更新了搜索字符串
- 2007 年 4 月 11 日:更新并添加了一些默认值
感谢
感谢您一路阅读!希望您觉得这篇文章有用,如果您觉得有用,请给我投票/评论,并请多保重。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。