宽带、媒体、电影、图像和声音等技术的出现推动了 Web 2.0 的发展。了解如何把多媒体与 PHP 和 Asynchronous JavaScript™ + XML(Ajax)结合起来创造令人耳目一新的体验。
如果问哪一个网站最能代表 Web 应用程序的新潮流,多数人会回答 YouTube。这个网站不仅仅积极接纳新技术营造出梦幻效果,而且改变了我们对多媒体的看法,改变了我们和媒体的关系。许多故事在以传统媒体渠道传播之前就已经出现在 YouTube 上了,当它们不再流传时,YouTube 就会像全世界的一个巨大的 Tivo,记录着曾经发生的点点滴滴。
媒体分享正在改变世界,而且从技术的观点来说,这并不难做到。本文介绍如何在 Web 视频托管应用程序上增加一个 Ajax 前端。
简单的视频选择
首先来看网站,网站上有一个电影列表可供选择 — 一个不用改变页面就能选择不同电影的网站。页面代码如 清单 1 所示。
清单 1. index.html
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<div id="movieHost">
</div>
<div id="movieList">
</div>
<script>
function setMovie( url )
{
$('movieHost').innerHTML = '';
var elEmbed = document.createElement( 'embed' );
elEmbed.src = url;
$('movieHost').appendChild( elEmbed );
}
new Ajax.Request( 'movies.xml', {
method: 'get',
onSuccess: function( transport ) {
var movieTags = transport.responseXML.getElementsByTagName( 'movie' );
$('movieList').innerHTML = '';
var bFirst = true;
for( var b = 0; b < movieTags.length; b++ ) {
var url = movieTags[b].getAttribute('url');
var title = movieTags[b].getAttribute('title');
if ( bFirst )
{
setMovie( url );
bFirst = false;
}
var html = '<a href="javascript:void setMovie(\''+url+'\');">';
html += title+'</a><br/>';
$('movieList').innerHTML += html;
}
}
} );
</script>
</body>
</html>
|
该页面使用 Prototype.js 这个很棒的 JavaScript 库向 movies.xml 数据源发送 Ajax 请求。返回数据后通过 getElementsByTagName()
方法查找所有电影标签。对每个电影标签,代码检索 URL 和标题。如果检索的标签是列表中的第一部电影,脚本立即开始放映这部电影。否则添加一个 anchor 标签作为 movieList <div>
的电影选择器。
电影选择器 anchor 调用 setMovie()
函数打开指定的电影。播放电影的方法很简单,首先将 movieHost <div>
标签置空,即删除原来的电影。然后将内容设置为 <embed>
标签,其 URL 由电影列表指定。
<embed>
标签是在页面中播放电影最简单的方法,但是存在跨浏览器的问题。另一种办法是同时使用 <object>
和 <embed>
标签(还有一种办法,即使用 Macromedia Flash Player:本文稍后 再讨论)。
这个简单的例子中,movies.xml 只是一个平面文件,包含一些我自己的家庭短片的引用。该文件如 清单 2 所示。
清单 2. movies.xml
<movies>
<movie url="spider.mov" title="Spider" />
<movie url="swing.mov" title="Swing Set" />
<movie url="water.mov" title="Water Splash" />
</movies>
|
打开该页面时,显示的结果如 图 1 所示。
图 1. 简单的电影列表页面
最上方是一部由 <embed>
标签播放的电影,下面是其他影片列表。点击其中的任何链接,正在播放的电影就变成所选择的电影。
显然,这个系统不适合大型的视频资料库,还需要对影片列表进行某种搜索。
可搜索的电影列表
要添加搜索功能,必须添加一个搜索框,如 清单 3 所示。其中增加了搜索输入字段 q
。
清单 3. 添加搜索功能
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<table><tr><td valign="top">
<input type="text" id="q" onkeyup="search()">
<div id="movieList">
</div>
</td><td valign="top">
<div id="movieHost">
</div>
</td>
</tr></table>
<script>
function setMovie( url )
{
$('movieHost').innerHTML = '';
var elEmbed = document.createElement( 'embed' );
elEmbed.src = url;
$('movieHost').appendChild( elEmbed );
}
function search()
{
new Ajax.Request( 'search.php?q='+escape($('q').value), {
method: 'get',
onSuccess: function( transport ) {
var movieTags = transport.responseXML.getElementsByTagName( 'movie' );
$('movieList').innerHTML = '';
var bFirst = true;
for( var b = 0; b < movieTags.length; b++ ) {
var url = movieTags[b].getAttribute('url');
var title = movieTags[b].getAttribute('title');
if ( bFirst )
{
setMovie( url );
bFirst = false;
}
var html = '<a href="javascript:void setMovie(\''+url+'\');">';
html += title+'</a><br/>';
$('movieList').innerHTML += html;
}
}
} );
}
</script>
</body>
</html>
|
在 key-up 事件中指定 search()
方法将被调用。search()
方法和 Ajax.Request
调用类似,除了向 search.php 页面传递查询字符串。search.php 脚本返回和原来相同的 XML 格式,因此不需要修改 XML 解析的代码。
我承认对于自己的习惯来说,key-up 上的 search()
函数反映有点太快。理想情况下,系统应该在执行搜索之前等待一秒左右以便输入完整的搜索文本,避免列表不停地闪烁。使用 window.setTimeout()
方法很容易实现这种行为。
清单 4 显示了经过修改的 search.php 脚本。
清单 4. search.php
<?php
header( 'content-type: text/xml' );
$movies = array();
$movies['spider.mov'] = 'Spider';
$movies['swing.mov'] = 'Swing Set';
$movies['water.mov'] = 'Water Splash';
?>
<movies>
<?php
foreach( $movies as $k => $v ) {
if ( strlen( $_GET['q'] ) > 0 &&
preg_match( '/'.$_GET['q'].'/i', $v ) ) {
?>
<movie url="<?php echo($k) ?>" title="<?php echo($v) ?>" />
<?php
} }
?>
</movies>
|
脚本一开始建立了一个数组保存全部电影。为了简化起见,这里对电影进行了硬编码。实际应用的时候这些元素很可能取自电影清单的数据库。
接下来的代码遍历列表,把搜索查询的正则表达式应用于每个电影的标题。如果匹配则输出包含 URL 和名称的 <movie>
标签。
打开页面并输入 s
,将看到 图 2 所示的页面。
图 2. 简单的电影查询页面
如果按下 Delete 建并输入 water
,就会看到 图 3 所示的页面。
图 3. 搜索与 “water” 相关的电影的查询页面
虽然本文主要讨论如何使用 Dynamic HTML(DHTML)和 Ajax 建立前端应用程序,但视频共享网站决不是这么简单。
视频分享基础
先暂时离开实践问题讨论一些更具理论性的东西,视频共享中更加复杂的问题。涉及到三个主要问题:
- 如何存储和传输视频
- 如何处理不同的视频格式
- 如何从上传文件中获得缩略图和视频信息
视频存储是一个实实在在的问题 — 特别是对于小应用程序而言视频文件非常大,需要大容量的硬盘空间来存储。将其传递给客户还面临着带宽的挑战。可以自己购买设备安装到托管设施中。或者使用 Amazon S3 这样的服务,只需很低的价格就能上传任何资料(数据库备份、图片、电影等等)到 Amazon 数据中心,以及提供给其他客户。和建立数据中心的大量投资相比可以先考虑一下这些服务。
下一个问题 — 视频格式 — 提出了一个有趣的挑战。存在多种视频格式,没有任何一种播放器能支持所有格式。事实上多数播放器只能处理自己挑选的视频格式。为了方便用户,也许最好以某种格式为标准然后将所有传来的视频都转化成这种格式。有一种非常方便的工具,即命令行应用程序 FFmpeg。它不仅能把一种视频格式转化成另一种,还能拾取画面的快照从而为用户提供视频缩略图。
选择何种视频格式作为标准可能很麻烦。目前 Flash 视频具有明显的优势,但是 Windows Media®,特别是随着 Microsoft Silverlight(原来的 WPF/Everywhere)的发布,正在赢得越来越多的支持。FFmpeg 几乎能将任何影片格式转化成 Flash 视频格式,这一点很吸引人。而且有一些免费和开源的 Flash 播放器很容易嵌入到网站上。将这些播放器和上述代码结合起来就能建立一个完整的、以 Ajax 为前端的端到端视频分享解决方案。
但 Web 上不仅仅有视频,图像共享也很重要。
幻灯片放映
清单 5 显示了一个简单的基于 DHTML 的幻灯片,数据来自 XML 文件。
清单 5. index.html
<html>
<head>
<script src="prototype.js"></script>
</head>
<body bgcolor="black">
<div style="text-align:center;">
<img id="imgItem" src="" style="display:none;"><br>
<div id="imgTitle" style="color:white;font-family:arial;font-size:24pt;">
</div>
</div>
<script>
var g_images = [];
var g_slideIndex = 0;
function showSlide()
{
$('imgTitle').hide();
$('imgItem').hide();
var height = 600;
var width = ( height / g_images[ g_slideIndex ].height ) *
g_images[ g_slideIndex ].width;
$('imgItem').src = g_images[ g_slideIndex ].src;
$('imgItem').width = width;
$('imgItem').height = height;
$('imgTitle').innerHTML = g_images[ g_slideIndex ].title;
$('imgTitle').show();
$('imgItem').show();
g_slideIndex++;
if ( g_slideIndex >= g_images.length )
g_slideIndex = 0;
}
new Ajax.Request( 'images.xml', {
method: 'get',
onSuccess: function( transport ) {
var imageTags = transport.responseXML.getElementsByTagName( 'image' );
for( var b = 0; b < imageTags.length; b++ ) {
g_images.push( {
src: imageTags[b].getAttribute('src'),
title: imageTags[b].getAttribute('title'),
width: imageTags[b].getAttribute('width'),
height: imageTags[b].getAttribute('height')
} );
}
showSlide();
window.setInterval( showSlide, 5000 );
}
} );
</script>
</body>
</html>
|
|
|
上述代码需要用到 Prototype.js JavaScript 库。利用 Ajax.Request
对象获得要显示的图片列表。然后解析返回的 XML 代码,获得图片的 URL、宽、高和标题。然后调用 showSlide()
函数得到幻灯片显示效果。设置的计时器每五秒切换到下一张幻灯片。
幻灯片放映通过包含当前图片的 <image>
标签和标题 <div>
标签实现。所谓放映只不过是隐藏当前的图片和标题,将图片来源和标题文本设置为新幻灯片的内容并显示。如果需要某种淡入淡出效果,建议使用 Scriptaculous 库中的 Effects
类,它是构建在 Prototype.js 上的。
清单 6 显示了数据图像文件。
清单 6. images.xml
<images>
<image src="images/megan1_875_700.jpg" title="Megan" width="875" height="700" />
<image src="images/oso1_875_700.jpg" title="Oso 1" width="875" height="700" />
<image src="images/oso2_873_700.jpg" title="Oso 2" width="873" height="700" />
</images>
|
这里虽然使用了硬编码,但使用 PHP 脚本很容易生成 XML 代码。幻灯片放映如 图 4 所示。
图 4. 简单的幻灯片放映
注意:我以前介绍过一个更加精细的幻灯片放映版本(要获得相关链接,参见参考资料)。现在这个版本的区别在于使用了 Prototype.js 库,各幻灯片之间的切换更简单。
结束语
像 Flikr 和 YouTube 之类的网站仅仅显示了 Web 上的多媒体应用的巨大潜能的冰山一角。本文介绍了一些非常简便的视频和图片浏览的实现,可用于您自己的项目。如果有效,请参加 developerWorks Ajax 论坛(参见 参考资料)告诉我您取得的成功。
posted on 2007-11-25 11:58
飞鸟 阅读(205)
评论(0) 编辑 收藏 所属分类:
AJAX