1. 程式人生 > >網頁內嵌多媒體內容的完美實現

網頁內嵌多媒體內容的完美實現

如果你不總是用 Windows 上的 Internet Explorer 來上網的話,你可能會注意到,許多網站上的視訊點播之類的多媒體內容,你無法直接在 Internet Explorer 以外的其它瀏覽器中觀看,比如明明已經安裝了外掛卻提示缺少外掛,或者什麼都不提示出現空的框框,或者顯示了播放器外掛卻始終連不上打不開之類的問題,而在 Internet Explorer 上卻能夠正確的開啟並播放。顯然這不是由於網路不通或者媒體不存在造成的,而是由於網頁內的程式碼有問題。你可能覺得這無關緊要,因為你已經習慣用 Internet Explorer 來瀏覽它們了;也可能你曾為此而頭疼,如果你是一個 Linux 使用者。可是不管怎麼樣,如果能在所有作業系統平臺的所有瀏覽器上都能正常播放這些多媒體內容,總是一件好的事情。本文就是來解決這些問題的。

本文將介紹如何在網頁中內嵌 Windows Media、RealPlayer、Quicktime 和 Flash 的完美方法。這些方法適用於 Windows、Linux、Mac OS X 等作業系統平臺上的 Internet Explorer、Mozilla、Firefox、NetScape、Opera 等多種瀏覽器。

完美內嵌 Windows Media

客戶端要求:

對於 Windows 使用者,需要安裝 Windows Media Player 7 以上的版本,Windows Media Player 6 不支援 WMV/WMA,推薦安裝 Windows Media Player 10

。對於非 Internet Explorer 使用者,還需要安裝Windows Media Player Plug-in for Netscape Navigator

對於 Linux 以及 FreeBSD、Solaris 等 Unix 系統使用者,需要 VLC media player及其瀏覽器外掛或者 MPlayer 及其瀏覽器外掛。VLC media player 0.80 及其以上的版本支援 WMV/WMA。

實現程式碼:

<objectwidth="420"height="360"classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
><paramname="filename"value="http://vod.ujn.edu.cn/movies%2Fasf%2F%B6%AC%CC%EC%C1%B5%B8%E8%2Easf"/><embedwidth="420"height="360"type="application/x-mplayer2"src="http://vod.ujn.edu.cn/movies%2Fasf%2F%B6%AC%CC%EC%C1%B5%B8%E8%2Easf"></embed></object>

也可以用下面這段程式碼:

<objectwidth="420"height="360"classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"><paramname="url"value="http://vod.ujn.edu.cn/movies%2Fasf%2F%B6%AC%CC%EC%C1%B5%B8%E8%2Easf"/><embedwidth="420"height="360"type="application/x-mplayer2"src="http://vod.ujn.edu.cn/movies%2Fasf%2F%B6%AC%CC%EC%C1%B5%B8%E8%2Easf"></embed></object>

要點分析:

這兩段程式碼的區別主要是針對 Internet Explorer 的。這兩段程式碼使用了兩個不同的 Media Player 物件,第一個是 MediaPlayer.MediaPlayer,第二個是 WMPlayer.OCX。這兩個 ActiveX 物件都是針對 Internet Explorer 的,因此它們不影響 Firefox、Opera 等瀏覽器。這兩個物件在 Internet Explorer 上的顯示效果是不一樣的,第一個物件的顯示效果跟在 Windows 上的 Firefox、Opera 內的顯示效果是一樣的,而第二個物件在 Internet Explorer 上的顯示效果是採用 Windows Media Player 本身的面板效果,如果你安裝了 Windows Media Player 10,採用第二種寫法,你在 Internet Explorer 上將會看到 Windows Media Player 10 那種晶瑩剔透的面板效果。

Firefox 不支援 object 中 classid 屬性,只支援 type 屬性,而如果發現 object 有 classid 屬性以後,它將不理會 object,而只執行 embed。而對於 Opera 則很有趣,它既支援 object,又支援 embed,但是因為 embed 是嵌入到 object 中的,如果它能正確識別 object,它就不再理會 embed,如果它不能識別 object,則執行 embed。因此它不會顯示兩個播放器。至少我是用的 8.5 版的 Opera 是這樣的。而 Internet Explorer 則只識別 object 中的 classid 屬性。因此在 object 中,我們不需要指定 type 屬性。

對於 embed 標籤,我們指定它的 type 為 application/x-mplayer2,在安裝了 Windows Media Player 的系統上,它對應於所有 Windows Media Player 能識別的型別,因此你可以任意指定 asf,asx,wmv,wma,avi,mp3 等型別的媒體,而在沒有 Windows Media Player,卻安裝了 VLC media player(或 MPlayer)的系統上,它對應於所有 VLC media player(或 MPlayer)能識別的型別,Windows Media Player 支援的媒體型別 VLC media player(或 MPlayer)均能支援,甚至 VLC media player(或 MPlayer)支援的媒體型別比 Windows Media Player 更多,因此上面這種寫法是完全支援多平臺多瀏覽器的。

對於上面兩個不同的 ojbect,指定播放檔案的引數是不一樣,第一個是用 filename 來指定,第二個是用 url 來指定。而 embed 中指定播放檔案的引數是 src,雖然用 filename 也可以,但是 src 更標準一些。

embed 中的檔名必須是完整的 url 路徑,否則 VLC media player 不能正確識別,另外要對檔案路徑進行 url 編碼,否則如果檔案路徑中如果有中文或者其他非英文文字的話,在非 Internet Explorer 瀏覽器中也無法正確識別。不要對 “協議://域名/” 部分進行 url 編碼,否則所有的瀏覽器都不能識別。呵呵。

對檔案路徑進行 url 編碼,在 php 中可以使用 rawurlencode 函式,在 asp 中可以使用 Server.URLencode 函式。

完美內嵌 RealPlayer (RealMedia)

客戶端要求:

對於 Windows,Linux 和 Mac OS X,可以安裝 Realplayer 播放器及其瀏覽器外掛,也可以安裝帶有 RealPlayer 解碼器及其瀏覽器外掛的其他播放器,例如 Windows 上可以安裝暴風影音

實現程式碼:

<objectclassid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"width="420"height="310"><paramname="src"value="link.php?link=rtsp%3A%2F%2Fvod%2Eujn%2Eedu%2Ecn%2F%D0%C2%D4%FA%CA%A6%C3%C3%2F1%2Erm"/><paramname="controls"value="Imagewindow"/><paramname="console"value="clip1"/><paramname="autostart"value="true"/><embedsrc="link.php?link=rtsp%3A%2F%2Fvod%2Eujn%2Eedu%2Ecn%2F%D0%C2%D4%FA%CA%A6%C3%C3%2F1%2Erm"type="audio/x-pn-realaudio-plugin"autostart="true"console="clip1"controls="Imagewindow"width="420"height="310"></embed></object><br/><objectclassid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"width="420"height="44"><paramname="src"value="link.php?link=rtsp%3A%2F%2Fvod%2Eujn%2Eedu%2Ecn%2F%D0%C2%D4%FA%CA%A6%C3%C3%2F1%2Erm"/><paramname="controls"value="ControlPanel"/><paramname="console"value="clip1"/><paramname="autostart"value="true"/><embedsrc="link.php?link=rtsp%3A%2F%2Fvod%2Eujn%2Eedu%2Ecn%2F%D0%C2%D4%FA%CA%A6%C3%C3%2F1%2Erm"type="audio/x-pn-realaudio-plugin"autostart="true"console="clip1"controls="ControlPanel"width="420"height="44"></embed></object>

link.php

<?phpecho(get_magic_quotes_gpc() ? stripslashes($_GET['link']) : $_GET['link']);
?>

要點分析:

上面的程式碼實現了的效果是在任何安裝了 realplayer 外掛的瀏覽器上,都可以看到一個播放視窗和一個播放控制欄,並且媒體被自動載入播放。對於 object 一段,這裡就不做詳細解釋了,因為它是針對 Internet Explorer 的,相信大部分寫過這種程式碼的人都能看得懂。我們重點來說一下 embed 一段,它是針對 Firefox 和 Opera 等瀏覽器的。

大部分人在使用 Firefox 和 Opera 時經常會遇到一個問題,就是安裝了 RealPlayer 及其瀏覽器外掛以後,仍然不能觀看嵌入到網頁中的 rm 或 rmvb 流媒體,提示找不到外掛,或者顯示空白,或者顯示了內嵌的播放器卻不能播放,這是什麼原因造成的呢?

如果你在 Firefox 和 Opera 的位址列中鍵入:about:plugins ,可以看到你所安裝的所有外掛。不管你的系統裡是否安裝的是真的 RealPlayer 播放器,只要你看到下面的內容,

Windows

RealPlayer(tm) G2 LiveConnect-Enabled Plug-In (32-bit)
檔名: nppl3260.dll
RealPlayer(tm) LiveConnect-Enabled Plug-In
MIME 型別 描述 字尾 已啟用
audio/x-pn-realaudio-plugin RealPlayer(tm) as Plug-in rpm

Linux

Helix DNA Plugin: RealPlayer G2 Plug-In Compatible
檔名: nphelix.so
Helix DNA Plugin: RealPlayer G2 Plug-In Compatible version 0.4.0.552 built
with gcc 3.2.0 on May 13 2005
MIME 型別 描述 字尾 已啟用
audio/x-pn-realaudio-plugin RealPlayer Plugin Metafile rpm

就說明你已經安裝好了 RealPlayer 的外掛。不能夠播放的原因就是他沒有像我上面那樣寫程式碼。

從上面的外掛資訊裡我們可以看到,RealPlayer 外掛只提供了一種 rpm 格式的媒體型別可以播放,而其他諸如 rm,rmvb 等型別卻好像沒有提供支援。是這樣嗎?可以說是也可以說不是。

比如你如果在 embed 裡指定 type 為 audio/x-pn-realaudio 型別,這個是正確的 mime 型別,但是你會發現你的瀏覽器將不能播放,而會讓你安裝外掛,即使你已經安裝了 RealPlayer 外掛。因為 RealPlayer 外掛不能識別這種正確的 mime 型別。

於是有的人認為只要指定 type 為 audio/x-pn-realaudio-plugin,然後後面直接指定 rm 或者 rmvb 等 RealPlayer 媒體型別的檔案就可以了。是這樣嗎?也不是。這樣做的話,你可以看到內嵌的播放器,但是你會發現播放器始終無法連線到伺服器並播放你所指定的媒體。因為你所指定的型別並不是 audio/x-pn-realaudio-plugin 所對應的型別。

於是有人說 RealNetworks 已經將非 IE 的瀏覽器給放棄了,其實這樣說是不對的。雖然存在上面的種種情況,但那是因為那些編寫網頁程式碼的人沒有理解 RealNetworks 的真正意圖, RealNetworks 不但沒有放棄在非 IE 瀏覽器中嵌入 RealMedia,反而是提供了一種通用的方式,讓你可以所有瀏覽器中都能內嵌播放所有的 RealMedia。因為我的程式碼就能夠如我所說的這樣工作。

首先我們必須要先知道一件事情,那就是 rpm 是一種什麼檔案。從上面 Linux 上的外掛的資訊中我們可以得知,它是 RealPlayer 外掛元檔案(RealPlayer Plugin Metafile)。因此它不是媒體內容檔案,更不是紅帽的安裝包檔案。它裡面的內容是實際媒體的位置資訊(url)。這樣我們就很容易理解 RealNetworks 為什麼要這樣做了,因為這樣只要指定一種 type,就能夠播放所有的 Real 媒體了。這不是很方便嗎?

在這裡需要注意的一點是,embed 的 src 屬性裡指定的路徑不需要是完整的 url,相對路徑就可以了,而且也不一定是 rpm 字尾的檔案,因此上面的程式碼中,src 中指定的是一個程式 link.php,而這個程式的結果就是一個 rpm 格式的檔案,因此它能夠被正確的播放。這個 link 程式很簡單,它只是把傳入的引數 link 以檔案內容的形式返回就行了。

雖然 embed 的 src 屬性不需要完整的 url,但是 link.php 的引數 link 是需要實際媒體的完整 url 的, 並且引數 link 要以 url 編碼形式進行編碼,否則 RealPlayer 外掛不能夠識別帶有非英文的路徑。但是返回的 rpm 檔案內容中的 url 無需編碼了,RealPlayer 能夠識別 rpm 檔案內容中的非英文編碼的路徑,如果你實在不放心,也可以對它進行 url 編碼,但是仍然不要對 “協議://域名/” 部分進行 url 編碼,否則 RealPlayer 外掛就不能識別了。

PHP 程式中的 $_GET 中的變數,如果 php 配置檔案中 magic_quotes_gpc 設為 true 的話(預設配置),它會對某些特殊字元加上反斜槓,這樣做是為了避免資料庫注入漏洞,但這裡我們不寫資料庫,因此這裡我們需要根據 magic_quotes_gpc 的狀態來判斷是否去掉多出來的反斜槓。否則輸出的檔案內容可能是錯誤的。

如果用 ASP,則不需這麼麻煩,只需要一行程式碼就搞定了:

<%=Request("link")%>

完美內嵌 Quicktime

客戶端要求:

Windows 使用者也可以安裝暴風影音等帶有 QuickTime 解碼器和瀏覽器外掛的其他播放器,例如暴風影音。

對於 Linux 以及 FreeBSD、Solaris 等 Unix 系統使用者,需要 VLC media player及其瀏覽器外掛或者 MPlayer 及其瀏覽器外掛。

實現程式碼:

<objectclassid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"codebase="http://www.apple.com/qtactivex/qtplugin.cab"width="420"height="360"><paramname="autoplay"value="true"/><paramname="src"value="mov%2F%B2%E2%CA%D4%2Emov"/><embedsrc="mov%2F%B2%E2%CA%D4%2Emov"type="video/quicktime"autoplay="true"width="420"height="360"></embed></object>

要點分析:

QuickTime 格式的內嵌比較簡單,像上面那樣寫就可以了,基本上沒有什麼要注意的地方。媒體路徑 src 的值,可以是完整地址,也可以是相對地址,可以用 url 編碼,也可以不編碼,QuickTime 外掛和 VLC 外掛都能正確的支援,當然為了保險起見,最好還是採用 url 編碼方式裡寫媒體路徑。

雖然 embed 中指定的是 video/quicktime 型別,但是即使連結的媒體是 mp3 仍然能播放。對於 QuickTime 支援的其他型別的沒有進行測試,但我想應該也是可以的。

完美內嵌 Flash

客戶端要求:

安裝你所使用的瀏覽器的 Flash 外掛。

實現程式碼:

<objectclassid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"width="420"height="320"><paramname="movie"value="flash/打電話記.swf"/><paramname="quality"value="high"/><embedsrc="flash/打電話記.swf"quality="high"type="application/x-shockwave-flash"width="420"height="320"></embed></object>

要點分析:

對於 Flash 似乎沒什麼好說的,因為這個用的很普遍。在這裡寫下來只是為了查閱方便,算是湊數吧。呵呵。

讓內嵌多媒體通過 XHTML 驗證

問題:

上面的所有的程式碼,雖然能夠完美的在各個瀏覽器上很好的播放了,但是還有一點美中不足,那就是這樣的頁面無法通過 XHTML 驗證。原因是 embed 標籤從來都不是 HTML 標準中的標籤,因此 XHTML 中也沒有它。

解決:

如果你不在乎你的網頁是否符合標準,那照上面那樣做就可以了。如果你還想追求更加完美,請看下面的解決方案:

下面以 flash 為例來介紹,方法同樣適用於其他型別的多媒體內容。

我們知道 W3C 推薦使用的是 object 標籤,但用法卻不是 Internet Explorer 那種用 classid 來區分控制元件型別,而是採用 type 來指定 MIME 型別。現在的 Mozilla、Firefox 和 Opera 都支援這種用法,雖然 IE 目前的版本也支援這種用法,不過很可惜的是,IE 還是有 bug,那就是隻有全部下載完畢才能播放。而且還不是所有的情況下都能用。在某些 IE 瀏覽器上還顯示空白。所以單純用 W3C 推薦的 object 標籤用法還是不夠的。但是我們可以作一下變通,如果是使用者瀏覽器是 IE 的話,我們就用 IE 的 object 的用法,如果是其他瀏覽器,我們就採用 W3C 的用法。這樣就可以兩全其美了。也許此刻,你覺得我們該用到指令碼了。不,我們不需要指令碼。我們只需要用 IE 所特有的條件註釋和 CSS 就可以做到了。例子如下:

<styletype="text/css">
.mozilla {
  display:block;
}
</style><!--[if IE]>
<style type="text/css">
.mozilla {
  display:none;
}
</style>
<![endif]-->
<objectdata="flashdatei.swf"type="application/x-shockwave-flash"height="275"width="256"class="mozilla"><paramname="autoplay"value="true"></object><!--[if IE]>
<object 
  classid="cclsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
  width="256"
  height="275">
  <param name="src" value=""flashdatei.swf">
</object>
<![endif]-->

你會發現其實就是把 embed 替換成了 object,而且位置也從 IE 的 object 中移出來了。embed 標籤裡的 src 屬性在 object 中變成了 data 屬性。而 firefox 等非 IE 瀏覽器因為不認識 <!–[if IE]> 標籤,所以其中的部分都當作註釋忽略了。而 IE 因為執行了 <!–[if IE]> 中的內容,所以 firefox 中可以識別的那個 object 因為 css 被重新定義而被隱藏了。

好了,現在不但可以完美播放,而且可以通過 XHTML 驗證了!太酷了! 

參考文獻