使用J2ME MMAPI開發(fā)移動多媒體應用技術
2007/09/14
一、 引言
在當前世面上存在著大量的不同媒體格式,并且還有許多新的媒體格式即將被建立。為了存儲和傳輸這些不同的媒體格式,存在著了許多不同格式的存儲設備和傳輸協(xié)議,例如大家常使用的媒體存儲設備(如CD、VCD以及DVD),有線傳輸協(xié)議(如UDP、HTTP),無線傳輸協(xié)議(如WAP)。
為了使移動裝置能夠訪問這些不同格式的媒體數(shù)據(jù),必需為其設計一個規(guī)范化的、強大的和可擴充的應用接口。J2ME中就提供了一套為規(guī)范的播放和錄制音頻或視頻接口,即Mobile
Media API (MMAPI)。
二、MMAPI體系結(jié)構(gòu)
一般情況下,可以將媒體處理過程分解為兩個過程:
- 處理媒體數(shù)據(jù)的傳輸協(xié)議的過程。
- 處理媒體數(shù)據(jù)內(nèi)容的過程。
1、 處理媒體數(shù)據(jù)的傳輸協(xié)議的過程
處理傳輸協(xié)議的過程是指從數(shù)據(jù)源(如一個文件、一個捕獲裝置或一個流服務)上讀取媒體數(shù)據(jù)內(nèi)容后,將其傳送到媒體數(shù)據(jù)內(nèi)容處理的過程。
MMAPI使用Data Source來處理媒體數(shù)據(jù)的傳輸協(xié)議的過程。一個Data Source知道如何從它的原始位置讀取媒體數(shù)據(jù)并傳送給媒體數(shù)據(jù)處理(Player)。媒體數(shù)據(jù)可以被保存在不同的位置,從遠程服務器到資源文件或者RMS數(shù)據(jù)庫。媒體數(shù)據(jù)可以從原始位置通過HTTP,像RTP一樣的流式傳輸協(xié)議,或者其他機制傳輸?shù)矫襟w數(shù)據(jù)處理(Player)。圖一展示了Data
Source的工作過程。
圖一:Data Source工作過程
javax.microedition.media.protocol.DataSource提供了MMAPI的Data Source的支持。
2、 處理媒體數(shù)據(jù)內(nèi)容的過程
處理媒體數(shù)據(jù)內(nèi)容的過程通常需要對媒體數(shù)據(jù)進行解釋和解碼,并且還需要認別該媒體的輸出設置的類型,如是音頻設置或者視頻設置。舉個例子,當DataSource從某媒體數(shù)據(jù)源上獲取一MP3媒體數(shù)據(jù),并將其傳送給處理媒體數(shù)據(jù)內(nèi)容過程,此過程首先對這個MP3媒體數(shù)據(jù)進行解析和解碼,同時檢測該MP3媒體為音頻數(shù)據(jù),打開裝置的音頻設備,將解析和解碼后的媒體數(shù)據(jù)直接傳送到裝置的音頻設備緩沖中,由該音頻設備根據(jù)緩沖區(qū)中的數(shù)據(jù)內(nèi)容產(chǎn)生音頻信號。
MMAPI使用Player來處理媒體數(shù)據(jù)內(nèi)容。一個Player是javax.microedition.media.Player接口的一個實現(xiàn)實例,它從Data
Source中讀取媒體數(shù)據(jù)、解析和解碼數(shù)據(jù)以及識別媒體輸出設備和傳送媒體數(shù)據(jù)到輸出設備等。Player提供了一套方法去控制媒體的重放和同步。
MMAPI還提供了一個或多個Controls來調(diào)整player的行為,可以在player從媒體轉(zhuǎn)換數(shù)據(jù)的時候從一個player實例取得并且使用Controls。我們可以通過Player中提供的一些特殊的Controls訪問一些特殊的媒體類型。Controls由javax.microedition.media.Control接口實現(xiàn)。
3、 Manager
J2ME為了實現(xiàn)對DataSource和Player有效管理,使用了工廠機制,由Manager來負責創(chuàng)建Player和DataSource。這樣的機制在JAVA中到處可見,如JDBC中的DriverManager,這里我就不對這種機制進行介紹了。Manager不僅可以從DataSource中創(chuàng)建Player,而且還可以從本地或InputStream中創(chuàng)建Player。圖二展示了MMAPI整體結(jié)構(gòu)圖。
圖二:MMAPI整體結(jié)構(gòu)圖
三、 使用MMAPI
MMAPI提供的類和接口都在javax.microedition.media中,在程序中使用MMAPI時,首先應該引用這些包,否則程序無法編譯。
每個MMAPI程序都需要創(chuàng)建一個Player對象,前面我們已經(jīng)介紹過,MMAPI使用Manager的CreatePlayer函數(shù)來創(chuàng)建Player對象,該函數(shù)有三個版本,其格式如下:
第一個版本實現(xiàn)通過URL字符串指定的協(xié)議和數(shù)據(jù)位置的信息創(chuàng)建一個Player對象,其中l(wèi)ocator的格式如下:
Manager將對createPlayer函數(shù)中提供的URL字符串參數(shù)進行分析,創(chuàng)建一個Data Source對象,由該對象完成對媒體數(shù)據(jù)的傳輸工作,并從數(shù)據(jù)中獲取該媒體的數(shù)據(jù)內(nèi)容類型,Manager將根據(jù)這個媒體數(shù)據(jù)類型創(chuàng)建相應的Player對象,如果Manager無法確定DataSource的內(nèi)容類型,它將拋出一個MediaException異常。
例:創(chuàng)建一個控制某網(wǎng)站MP3音頻的Player對象。
Player pMP3 = Manager.createPlayer( "http://www.XXX.com/111.mp3");
第二版本實現(xiàn)通過已知的DataSource對象創(chuàng)建Player對象。
第三版本實現(xiàn)通過InputStream流創(chuàng)建Player對象。
我們根據(jù)應用實際的情況選擇使用那種版本來創(chuàng)建Player對象。有了一個Player對象以后,接下來要通過這個Player對象提供的方法去控制媒體流。下面我們列出常用的方法:
- Player.start():重放媒體流。
- Player.stop():停止媒體流。
- Player.setMediaTime(long now):設置媒體時間。
- Player.close():關閉媒體流并釋放資源。
- Player.getState():獲取Player的當前狀態(tài)。
每個Player對象中都存在著一個狀態(tài)變量,用于表示該Player對象的生命周期。當Player第一次被建立時處于UNREALIZED狀態(tài);當為該Player設置了媒體數(shù)據(jù)的位置后,它處于REALIZED狀態(tài)(如Player正在從一個服務器的HTTP連接下載并解釋數(shù)據(jù)的時或Player在Http請求已經(jīng)發(fā)送到服務器,收到HTTP響應后,而且DataSource準備好接收媒體數(shù)據(jù)的時);當該Player已經(jīng)讀到足夠的數(shù)據(jù)而開始解釋和運算時,處于PREFETCHED狀態(tài);當數(shù)據(jù)在運算完畢后,該Player的狀態(tài)變成了STARTED。我們在使用Player對象的方法對媒體流進行控制時,應注意它們可能影響到Player狀態(tài)的改變,可以使用getState函數(shù)獲取當前Player的狀態(tài)。圖三展示了Player對象的狀態(tài)轉(zhuǎn)換圖。
圖三:狀態(tài)轉(zhuǎn)換圖
四、 播放常見媒體的方法
1.播放單音與序列音
如果要播放一個單音一次,可使用:
Manager.playTone(note,duration,volume);
如果要播放序列音,則必須使用ToneControl。使用一個特別的定位器來創(chuàng)建一個 Player對象,獲得ToneControl,設置其命令序列,然后啟動播放器,如:
2.播放聲訊和MIDI
聲訊是指如WAV這樣的聲音格式,在這種格式中,數(shù)據(jù)是各種聲訊樣本的一個流,它代表著該聲訊每一秒鐘的片斷。MIDI則是一系列的命令,用作多樂器的某種"虛擬合成器"。
如要播放一段能夠通過HTTP訪問的聲音文件,請使用:
Player p = Manager.createPlayer("http://something.com/somefile.wav");
p.start();
如要播放一段已經(jīng)被置于MIDlet的JAR文件中的聲音文件,需要先了解其MIME類型(如,"audio/x-wav"),然后,使用:
3.播放視頻
播放視頻類似于音頻播放。然而,需要告訴視頻播放器在哪里顯示視頻信號,因此,需要從視頻播放器處得到一個"視頻控件",然后在Form或Canvas中顯示視頻內(nèi)容。下面展示一個從Canvas中顯示視頻的例子:
賽迪網(wǎng)
中國信息化(industry.ccidnet.com)
相關鏈接:
莒南县|
阿拉善左旗|
东兴市|
故城县|
龙州县|
常德市|
东宁县|
常德市|
类乌齐县|
子洲县|
若尔盖县|
敦化市|
托克逊县|
宁安市|
玉山县|
邵阳县|
屏边|
榆林市|
尼木县|
临沧市|
甘肃省|
义马市|
丹江口市|
平安县|
桃园县|
巫山县|
富蕴县|
都匀市|
新民市|
武强县|
平原县|
吴旗县|
辽阳县|
松原市|
会东县|
衡阳县|
周宁县|
周至县|
灵石县|
文安县|
喀喇沁旗|