現在是成為 Java 開發人員的大好時機。根據 JavaOne 2008 大會提供的最新統計數據,全世界部署了超過六十億支持 Java 功能的設備。這些設備涵蓋了從大型企業級服務器到可以放入皮夾中的微型智能卡的各種設備。Java 技術已經被嵌入到數以億計的電話,以及包括傳統台式機在內的無數其他設備中:圖 1 顯示了現有的各種 Java 平台)。
圖 1:當前可用的各種 Java 平台
用於藍光播放器的 Java 平台叫做 BD-J。在本系列的第 1 部分,我們將涵蓋以下主題:
BD-J 開發的基本要求
BD-J 平台的功能
BD-J 規范和 API
理解藍光配置文件
Xlet 和 Xlet 生命周期
創建您的第一個 BD-J 應用程序
我們假設您不具備創建 Java ME 或視頻內容的任何經驗。在這個基礎上,我們就可以開始了。
BD-J 開發的基本要求
盡管 BD-J 標准是 Java ME 平台的一部分,但是您仍然需要一個更加強大的機器,以便在您的 PC 上播放 BD-J 應用程序。下面列出了在您的 PC 上創建、刻錄和播放 BD-J 應用程序的物理要求:
一台運行 Windows Vista 或 XP 的台式機或膝上型電腦。不幸的是,在寫這篇論文的時候,還沒有很多用於在 Mac OS 或 Linux 上進行 BD-J 開發的工具和硬件。如果您是 Mac 用戶,那麼與使用虛擬化軟件相比,您最好還是使用帶 Bootcamp 的 Windows 系統,因為高清視頻對視頻驅動程序和顯示器的要求比較嚴格。
顯存不低於 256MB 的顯卡。這個要求非常重要,因為大部分渲染高清視頻所需的艱苦工作將由顯卡的 GPU 來完成,而不是由主板上的 CPU 完成。
能夠渲染高清視頻的視頻顯示器。高清視頻的分辨率為 1920x1080 像素。
一台藍光刻錄設備。幸運的是,一些驅動器附帶了可擦寫的藍光光盤(也稱之為 BD-RE),這樣您可以重復使用該光盤創建您的應用程序或電影。
換句話說,通常 500 美元的台式機或者 1000 美元的膝上電腦可能 就可以創建 BD-J 應用程序和刻錄藍光光盤,但是二者可能都無法播放藍光光盤,因為高清視頻對系統的要求非常高。幸運的是,CyberLink 公司開發了一款 方便的診斷工具,可用於確認您的機器是否能夠播放藍光視頻。下面的圖 2 顯示了一個在我的膝上電腦上運行的工具的屏幕截圖。
圖 2:該 CyberLink Advisor 工具指出這台膝上電腦不能播放藍光電影
BD-J 平台的功能
那麼,您可以使用 BD-J 平台做什麼呢?我很高興您問了這個問題。但是,在我們討論 BD-J 平台的功能之前,最好先說明一下創建 BD-J 應用程序時經常使用的一些術語:
光盤: 光盤是承載高清視頻內容和 BD-J jar 文件的物理介質。
節目(Title):一張光盤可以有一個或多個節目。在外行的術語中,一個節目就是一部電影。但是,如果您想要創建一張包含分為 10 段的烹饪影片的藍光光盤,您不能把每段都稱為一部電影。因此,光盤上有組織的一個視頻內容單元就叫做一個“節目”。
菜單:菜單是 BD-J 應用程序的交互部分,可響應遙控器的輸入。通過與菜單交互,您可以在光盤上選擇標題、開始播放標題,以及激活或者停用高級選項。
現在我們已經涵蓋了創建 BD-J 應用程序和制作內容時要用的術語,讓我們來研究 BD-J 平台的功能。使用 BD-J API,您可以在顯示器上繪制任何文本、圖像或動畫。這使您可以創建具有以下功能的應用程序:
在屏幕上繪制由當前顯示的幀觸發的簡單文本。可以想象,這對呈現字幕將非常有用。
在顯示器上繪制圖形或圖像,並在當前顯示的視頻內容上面顯示。
在顯示器上為互動游戲繪制圖像,並使圖像運動起來。
創建具有特效(像淡化和過度)的動畫按鈕。
創建高度互動的菜單,允許用戶選擇節目、章節或任何其他高級選項,像獎勵內容 (bonus content)。實際上。圖 3 顯示了 HDcookbook 項目中(對 BD-J 開發人員來說是很好的資源)提供的示例代碼呈現的菜單。
圖 3:使用 BD-J API 呈現的交互菜單
另外,BD-J API 允許您開始播放光盤上的任何視頻內容,這意味著您可以創建具有任何以下功能的應用程序:
根據菜單選擇開始播放節目。這是最普通的視頻播放場景。
啟動“first playback”(首先播放),這使光盤插入播放器時開始播放內容。
使用進行畫中畫 (Picture in Picture, PiP) 呈現的 API 同時開始播放兩個視頻流。
另外,使用 BD-J API,您可以響應來自遙控器的用戶輸入,通過網絡訪問數據,或者在藍光播放器的本地永久存儲器上存儲數據——等等,藍光播放器有本地存儲器?是的,當前市場上的播放器要求有 64 KB 內存用於永久存儲。藍光播放器也可以把數據存儲到一個“虛擬文件系統”,但是稍後我們將在本文中進行討論。那麼,以此為前提,BD-J API 的這些功能也將使您能夠創建具有以下功能的應用程序:
根據遙控器的輸入更改操作。
當光盤在藍光播放器中時,下載獎勵內容並播放特殊功能。
允許光盤所有者安全地從電子商務網站購買衣服、紀念品、書籍等東西。
允許藍光播放器“記住”游戲最高分等內容,或者知道您已經解鎖光盤上的某些特殊功能。
允許藍光播放器在光盤彈出後仍保持應用程序運行。當您有一套盒裝光盤,您希望在播放所有這一套光盤時,應用程序程序可以繼續運行並且保持狀態,那麼這個功能將非常有用——一個非常強大的功能!
現在您已經很好地了解了 BD-J 平台的功能,讓我們更加深入一點,更加仔細看一看 API 的種類。
BD-J 規范 API
可以想象,BD-J 規范不是一下子發明的,它的確利用了很多其他在主頁的平台/消費電子區域運營的 Java 規范。如果您記得圖 1,消費電子的 Java 平台為 CDC (Connected Device Configuration)。在圖 4 中,我們將看一看構成 BD-J 規范的 API 堆棧。
圖 4:包含一些先前存在的 API 的 BD-J API 堆棧
既然您對規范已經比較熟悉了,下面我們逐個包簡要介紹特定的 BD-J 類。
Blu-ray Java (BD-J) API
org.bluray.application 此包包含一個類,該類擴展了一個 GEM/MHP 層的類。它包含多項功能,包括一個光盤插入和彈出的事件通知框架。 org.bluray.media 此包包含符合藍光媒體播放器的特定於媒體的類,並且它們擴展了 GEM/MHP 規范中的功能。這些類包含控制畫中畫 (Picture-in-Picture, PiP)、字幕和音頻的機制。 org.bluray.Net 預先猜測一下,您可能以為此包包含所有從藍光播放器建立 TCP/IP 網絡連接所需的類。實際上,所有那些苦活兒都由 Personal Basis Profile 提供的 Java.Net 包完成。相反,此包包含一個擴展 Java TV API 的功能的類,以便為藍光設備定義一個定位器 (Locator)。什麼是定位器?它只是一個格式類似 URL 的文本字符串。在藍光環境中,定位器用於在光盤上選擇節目。 org.bluray.storage 此包包含 3 個類,允許您確定藍光播放器上的空閒存儲空間總量。請注意:所有藍光播放器上都必須要有永久存儲區域,但不是所有播放器都必須要有虛擬文件系統(允許您存儲大量數據,比如視頻內容)。 org.bluray.system 此包包含一個類,該類允許您訪問藍光播放器上的系統寄存器。 org.bluray.ti 此包包含很多向您提供光盤上的節目信息和節目的元數據的類。 org.bluray.ui 此包包含添加 Personal Basis Profile 中的 Java.awt 包尚未提供的用戶接口功能的類。這些類允許您添加一些花樣,以及做一些與視頻幀同步的動畫。 org.bluray.vfs 此包中的類允許您在虛擬文件系統中存儲數據。虛擬文件系統並不是所有藍光播放器必須要有的,但是在那些支持網絡連接的播放器中存在。
GEM 和 MHP API
BD-J 規范絕對不是第一個對消費電子設備使用 Java 的規范。Multimedia Home Platform (MHP) 和 Globally Executable Multimedia Home Platform (GEM) 的規范定義了最初用於家庭的分線盒和其他多媒體設備的 API。由於 GEM 規范是一個全球標准,它已經得到了其他消費電子設備標准的運用,包括:
Blu-ray Disc Java (BD-J)
OpenCable Applications Platform (OCAP),現在叫做 Tru2way
Advanced Common Application Platform (ACAP)
在這篇文章中,我並不打算深入討論整篇 GEM/MHP 平台。以下列表展示了構成 GEM/MHP API 的 Java 包,它包含在 BD-J 標准中。
org.davic.media dvb.event dvb.test org.davic.Net dvb.io dvb.ui org.davic.resources dvb.lang dvb.user dvb.application dvb.media havi.ui dvb.dsmcc dvb.Net
Java TV 1.1 API
回憶一下圖 4,整個 BD-J 標准也使用來自 Java TV API 的功能。Java TV API 提供關鍵功能或 BD-J 應用程序,比如 Xlet 框架(稍後我將在本文中詳細討論),以及 javax.tv.service.Service 的類定義。對於具有 Java 功能的電視機和機頂盒(包含電纜接收機和 DVR),一項服務就是一個頻道。所以,舉例來說,如果您想要編寫一個簡單的應用程序,該應用程序為您啟用 Java 的 DVR 安排節目,使其每天下午 4:00 調諧到 203 頻道,那麼您需要使用 javax.tv.service 包中的類來完成該任務。現在,對於藍光設備來說,一個 javax.tv.service.Service 就是一個光盤節目。以下是一個 Java TV API 中的包的完整列表:
Javax.tv.graphics Javafx.tv.service Javax.tv.locator Javafx.tv.util Javax.tv.media Javafx.tv.xlet Javax.tv.Net
Personal Basis Profile,Foundation Profile 以及 Connected Device Configuration API
Personal Basis Profile (PBP)、Foundation Profile (FP) 以及 Connected Device configuration (CDC) 一起構成了另一個上一層 API 為嵌入的和消費電子設備利用的基礎。這些類提供了桌面 Java 程序員已經非常熟悉的 Java SE 類。這些類不等同於整個 JDK 1.6 標准 (Java SE 6),但是它們與 Java SE 1.3 標准非常相似,只有少數例外。這些是 JDBC、Swing 和假設用戶輸入包含定點設備(即鼠標)的高級 AWT 小部件的省略。現在,您應該知道由於此平台是 Java ME(而不是 Java SE),那麼您也可以訪問同樣在具有 Java 功能的手機中包含的 Javax.microedition.io 類。以下是 PBP、FP 和 CDC API 中所包含類的列表:
Java.awt Java.math Java.text Java.beans Java.Net Java.util Java.io Java.rmi Javax.microedition.io Java.lang Java.security Javax.microedition.xlet
理解藍光配置文件
讓我們回顧一下在市場上的播放器上實現的不同版本的藍光光盤規范。
發布的第一版藍光光盤規范為 profile 1.0。
下一個版本為 Blu-ray Disc Profile 1.1,也叫做 “Bonus VIEw”。在 Blu-ray Profile 1.1 中,該規范要求支持畫中畫 (Picture-in-Picture, PiP) 並且擁有虛擬文件系統,這至少需要能夠存儲 256 MB 數據。
最新的版本是 profile 2.0,也叫做 “BD-Live”。此配置文件擁有 Profile 1.1 中的所有功能,並且增加了對 Internet 連接的需要。Profile 2.0 還要求虛擬文件系統至少能夠存儲 1 GB 數據。現在,由於單層藍光光盤可容納 25 GB 數據,您可以看到 Profile 2.0 設備中的虛擬文件系統無法容納整部電影。但是,它完全足夠您的應用程序利用 Internet 連接,以及存儲一些高清視頻內容稍後進行回放。
Xlet 和 Xlet 生命周期
如果您曾經用過一段時間 Java,那麼您應該熟悉 *let 命名約定,該約定適用於 Applet、Servlet 和 MIDlet。值得欣慰的是,CDC 平台上的應用程序不叫做 CDClet,而叫做 Xlet,因為沒人能找到一個更好的名字。
要創建一個 BD-J 應用程序,至少需要在一個類中實現 javax.tv.xlet.Xlet 接口,該接口來自 Java TV API。如果您熟悉 Personal Basis Profile 中的類,那麼您應該知道 Xlet 的定義也在 javax.microedition.xlet 包中。因此,要盡量減少構建 BD-J 應用程序時的麻煩,請一定要從 Java TV 包中導入 Xlet 類。
現在,理解 BD-J Xlet 的生命周期就非常簡單了。調用構造函數之後,您的 Xlet 將進入加載狀態。除了構造函數之外,還需要調用 initXlet() 方法,該方法將把您的 Xlet 至於 Paused 狀態,直到 startXlet() 方法被調用。如下面的圖 5 所示,您的應用程序在銷毀前可以多次在 Paused 和 Active 狀態之間轉換。因此,startXlet() 方法是存放允許您在執行實際工作前檢查網絡連接和其他重要資源的代碼的理想場所。
圖 5:Xlet 狀態圖
既然我們已經解決了所有的初步工作,就讓我們開始創建第一個應用程序吧。
創建您的第一個 BD-J 應用程序
在以下示例代碼中,我在一個簡單的應用程序中實現了所有的 Xlet 生命周期方法,並且執行了一個非常簡單的操作:在屏幕上書寫文本。
清單 1:FirstBDJApp.Java
package test;
import Javax.tv.xlet.Xlet;
import Javax.tv.xlet.XletContext;
import Java.awt.BorderLayout;
import Java.awt.Color;
import Java.awt.Container;
import Java.awt.Font;
import Java.awt.Graphics;
import org.havi.ui.HScene;
import org.havi.ui.HSceneFactory;
public class FirstBDJApp implements Xlet {
private static Font font;
private HScene scene;
private Container gui;
private String text = "My first BD-J app running on the PS3!";
//private String text = "My first BD-J app running on " + System.getProperty("os.name");
public FirstBDJApp() {
}
public void initXlet(XletContext context) {
font = new Font(null, Font.PLAIN, 48);
scene = HSceneFactory.getInstance().getDefaultHScene();
gui = new Container() {
public void paint(Graphics g) {
g.setFont(font);
g.setColor(new Color(10, 10, 10));
g.fillRect(20, 20, getWidth() - 40, getHeight() - 40);
g.setColor(new Color(245, 245, 245));
int message_width = g.getFontMetrics().stringWidth(text);
g.drawString(text, (getWidth() - message_width) / 2, 500);
}
};
gui.setSize(1920, 1080);
scene.add(gui, BorderLayout.CENTER);
scene.validate();
}
public void startXlet() {
gui.setVisible(true);
scene.setVisible(true);
}
public void pauseXlet() {
gui.setVisible(false);
}
public void destroyXlet(boolean unconditional) {
scene.remove(gui);
scene = null;
}
}
如您所見,我們並沒有使用任何高級 widget 在屏幕上繪制文本。我們只是計算了該文本應該占據的面積,並使用 Graphics 對象在顯示器上繪制文本。圖 6 顯示了我們的應用程序在 PS3 游戲主機上的運行情況。
圖 6:FirstBDJApp.Java 在 PS3 游戲機上的效果結束語現在,已經了解了如何創建可以在任何藍光播放器上運行的 BD-J 應用程序。從 BD-J API 中可以看到,我們介紹的內容僅僅是冰山一角。在第二部分中,我們將更加詳細地介紹如何獲得創建 BD-J 應用程序的開發環境。我們也將提供有關如何響應遙控器的用戶輸入的示例代碼。