寬帶、媒體、電影、圖像和聲音等技術的出現推動了 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
飛鳥 閱讀(208)
評論(0) 編輯 收藏 所屬分類:
AJAX