鷹翔宇空

          學(xué)習(xí)和生活

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
          原文引自:http://www-128.ibm.com/developerworks/cn/java/wi-mvideo/

          最新一代的 iPod 媒體播放器在移動(dòng)視頻編程領(lǐng)域開(kāi)辟了一個(gè)新機(jī)會(huì) —— 但是如何入門(mén)呢?本文介紹將 QuickTime for Java? 庫(kù),以編程方式為 iPod 媒體播放器創(chuàng)建視頻內(nèi)容時(shí)需要這個(gè)庫(kù)。

          Apple iPod 是當(dāng)今市場(chǎng)上的幾個(gè)媒體播放器之一,它能播放多種媒體,其中包括音頻、視頻和圖片。在美國(guó)和其他地方,iPod 引領(lǐng)著便攜媒體播放器市場(chǎng),從誕生至今,已經(jīng)售出 3千萬(wàn)套 iPod ,這占據(jù)了整個(gè)媒體播放器市場(chǎng) 78% 以上的份額。雖然 iPod 的成功顯然是受 MP3 流行的推動(dòng),而且手機(jī)用戶拍攝和交易數(shù)字圖片到現(xiàn)在也有了一段時(shí)間,但移動(dòng)視頻的市場(chǎng)仍然在形成中。早期進(jìn)入移動(dòng)視頻市場(chǎng)的潛在收益是顯而易見(jiàn)的,但對(duì)許多開(kāi)發(fā)人員來(lái)說(shuō),他們要解決的問(wèn)題是最好地應(yīng)用這項(xiàng)新技術(shù)的方式和地方。

          在這篇文章中,我首先將推薦一些移動(dòng)視頻的實(shí)際(可能也是非常流行的)應(yīng)用,然后演示兩個(gè)程序,讓您開(kāi)始使用 QuickTime for Java API 為 iPod 創(chuàng)建視頻內(nèi)容。這兩個(gè)程序可以讓您很容易地給現(xiàn)有的視頻文件添加標(biāo)題,并將傳統(tǒng)的視頻文件轉(zhuǎn)換成與 iPod 兼容的格式。在文章末尾,將留給您一些示例代碼,可以用它們學(xué)習(xí)使用 QuickTime for Java API 進(jìn)行視頻操作的更多內(nèi)容。

          為什么要用移動(dòng)視頻?


          圖 1. iPod 視頻播放器
          iPod 視頻播放器

          便攜媒體播放器在特定人群(即年齡在 18 到 38 歲之間,具有一定的可支配收入的消費(fèi)者)中特別流行。因?yàn)橐苿?dòng)視頻對(duì)于便攜媒體播放器來(lái)是相對(duì)較新的東西,所以對(duì)大多數(shù)開(kāi)發(fā)者來(lái)說(shuō),遇到的第一個(gè)問(wèn)題就是: 為什么要?jiǎng)?chuàng)建移動(dòng)視頻內(nèi)容?除了移動(dòng)媒體最明顯的娛樂(lè)要求之外,還有許多實(shí)際的使用情況:移動(dòng)媒體既可以促進(jìn)銷售,也可以給便攜媒體播放器和內(nèi)容帶來(lái)一類新用戶。請(qǐng)想想以下這些情況:

          • 房地產(chǎn)經(jīng)紀(jì)人可以創(chuàng)建一段視頻,將視頻做成房產(chǎn)可用屬性和用錄制好的配音說(shuō)明的一些功能的虛擬漫步。然后,潛在的住房買(mǎi)主可能會(huì)用便攜媒體播放器查看中意的屬性。在沒(méi)有時(shí)間尋找所有符合自己需求的房產(chǎn)的住宅搜索客戶中,這種極為節(jié)約時(shí)間的方式會(huì)變得非常流行。
          • 汽車廠商和經(jīng)銷商可以使用移動(dòng)視頻發(fā)布所銷售的最新車型的視頻目錄。潛在客戶就會(huì)更熟悉中意的車型的特性和好處,而不必親自去經(jīng)銷商那里。
          • 學(xué)院和大學(xué)的官員可以用移動(dòng)視頻格式向?qū)W生提供提供演講,輔助學(xué)生學(xué)習(xí)。
          • 生產(chǎn)商可以為汽車、書(shū)架、玩具(等等)提供移動(dòng)視頻格式的安裝說(shuō)明。

          顯然,這只是創(chuàng)建移動(dòng)視頻內(nèi)容的商業(yè)驅(qū)動(dòng)力的幾個(gè)示例。這些示例中的共同之處就是向新市場(chǎng)介紹便攜媒體的潛力。現(xiàn)在,我們來(lái)看看允許用編程方式創(chuàng)建和編輯視頻文件的 Java API。





          回頁(yè)首


          QuickTime for Java API

          對(duì)于 Java 開(kāi)發(fā)人員來(lái)說(shuō),支持?jǐn)?shù)字媒體的創(chuàng)建、修改和回放的能力最強(qiáng)、功能最豐富的 API 就是 QuickTime for Java API。QuickTime for Java 最初是為 Macintosh 平臺(tái)創(chuàng)建的,但過(guò)去這幾年時(shí)間里,Windows 和 Mac 用戶也可以隨意使用它。當(dāng)然,如果曾經(jīng)用 Java 語(yǔ)言做過(guò)一些編程,那么您可能會(huì)問(wèn):為什么不可以只使用 Java 媒體框架 (JMF) API。

          最初創(chuàng)建 JMF 是為了給 Java V1.0.2 的開(kāi)發(fā)人員提供處理各種媒體的能力。但是,它的應(yīng)用并不廣,它支持一些過(guò)時(shí)的媒體格式和編碼方式,例如 MPEG-2、AU、HotMedia 和 Flash 2。另一方面,QuickTime for Java 支持 QuickTime 可以播放的所有媒體格式和編碼方式。使用 QuickTime for Java API 可以訪問(wèn)更新的媒體格式,其中包括 MPEG-4、MP3 音頻、H.264 和 Flash 5。實(shí)際上,下面就是 QuickTime 支持的視頻編碼方式的完整列表:

          • 動(dòng)畫(huà)
          • Apple BMP
          • Apple Pixlet
          • Apple Video
          • Cinepak
          • Component video
          • DV and DVC Pro NTSC
          • DV PAL
          • DVC Pro PAL
          • Graphics
          • H.261
          • H.263
          • H.264
          • JPEG 2000
          • Microsoft? OLE
          • Microsoft Video 1
          • Motion JPEG A
          • Motion JPEG B
          • MPEG-4 (Part 2)
          • Photo JPEG
          • Planar RGB
          • PNG
          • Sorenson Video 2
          • Sorenson Video 3
          • TGA
          • TIFF




          回頁(yè)首


          向視頻添加標(biāo)題

          如果是初次接觸 QuickTime for Java API 或者是初次處理數(shù)字媒體,那么向視頻片斷添加標(biāo)題是一個(gè)好的起點(diǎn)。清單 1 顯示的 CaptionAdder.java 是一個(gè)簡(jiǎn)單的程序,它接受視頻文件,然后向視頻添加一個(gè)文本字符串作為標(biāo)題。


          清單 1. CaptionAdder.java
          import quicktime.*;
          import quicktime.io.*;
          import quicktime.std.image.*;
          import quicktime.std.movies.media.*;
          import quicktime.std.movies.*;
          import quicktime.std.*;
          import quicktime.qd.*;
          import quicktime.util.QTPointer;
          
          
          import java.io.*;
          
          public class CaptionAdder {
          
           public static void main (String args[]) {
          
            if (args.length != 1){
          
              System.out.println("Usage: java CaptionAdder [input_filename]");
          
            } else {
                
              try {
               QTSession.open();     
          
               System.out.println ("QuickTime version: " + QTSession.getMajorVersion() + "." + 
                  QTSession.getMinorVersion());
          
               QTFile qtfile = new QTFile(new File(args[0]));
               DataRef urlMovie = new DataRef ("file://" + qtfile.getPath());
               Movie movie = Movie.fromDataRef (urlMovie,StdQTConstants.newMovieActive);
              
               float  textTrackHeight = 32;
          
               QDRect movieBounds = movie.getNaturalBoundsRect();
               float  movieWidth  = movieBounds.getWidthF();
               float  movieHeight = movieBounds.getHeightF();
          
               Track  textTrack = movie.addTrack(movieWidth, textTrackHeight, 0);
          
               Matrix textTrackMatrix = textTrack.getMatrix();
               textTrackMatrix.translate (0, movieHeight - textTrackHeight);
               textTrack.setMatrix (textTrackMatrix);
          
               textTrack.setEnabled (true);
          
               int movieTimeScale = movie.getTimeScale();
               TextMedia textMedia = new TextMedia (textTrack, movieTimeScale);
          
                 QDRect textBounds = new QDRect (movieWidth, movieHeight);
          
               textMedia.beginEdits();
          
                TimeInfo sampleTime = new TimeInfo (0, movie.getDuration()/2);
              
                String text = new String ("1234 Main St. - Listing price: $164,000");
                TextMediaHandler textMediaHandler = textMedia.getTextHandler();
                QTPointer textPointer = new QTPointer ( text.length() + 1, true );
                textPointer.copyFromArray ( 0, text.getBytes(), 0, text.length() );
                textMediaHandler.addTextSample (
                  textPointer,
                  QDFont.getFNum("Times"), 
                  16, 
                  0,
                  QDColor.white,
                  QDColor.black,
                  QDConstants.teCenter,
                  textBounds,
                  StdQTConstants.dfClipToTextBox | StdQTConstants.dfKeyedText,
                  0,0,0,
                  null,
                  sampleTime.duration );
                
               textMedia.endEdits();
          
               textTrack.insertMedia (sampleTime.time, 0, sampleTime.duration, 1 );
               OpenMovieFile outStream = OpenMovieFile.asWrite (qtfile); 
          
               movie.updateResource (outStream, StdQTConstants.movieInDataForkResID, 
                  qtfile.getName());
              } catch (Exception e) {
                   e.printStackTrace();
                       QTSession.close();
                       System.exit(0);
              }
                  
                         QTSession.close();
          
            // end else
            }
          
            System.out.println ("complete.");
          
           //end method
           }
            
          
          }
          

          關(guān)于代碼

          幾乎每個(gè) QuickTime for Java 應(yīng)用程序都一樣,所有的實(shí)際動(dòng)作都發(fā)生在 QTSession.open()QTSession.close() 語(yǔ)句之間。在調(diào)用 QTSession.open() 時(shí),QuickTime 引擎可以初始化其自身。如果沒(méi)有先調(diào)用 QTSession.open(),就想調(diào)用其他 QuickTime for Java 類,那么您會(huì)獲得拋出到命令行中的非常難看的堆棧跟蹤。

          QuickTime for Java API 中使用的核心對(duì)象之一是 quicktime.std.movies.Movie 對(duì)象。如果初次使用 QuickTime for Java,那么需要認(rèn)識(shí)到,在 quicktime.std.movies.Movie 對(duì)象和硬盤(pán)上可能存在的 file_name.mov 之間有一點(diǎn)細(xì)微的區(qū)別。重要的是,可以創(chuàng)建 quicktime.std.movies.Movie 對(duì)象,并且無(wú)需要在硬盤(pán)上創(chuàng)建 file_name.mov 文件該對(duì)象就可以存在。

          quicktime.std.movies.Movie 對(duì)象可由多個(gè)軌道 組成,這些軌道是獨(dú)立的媒體源(例如音頻、視頻、靜態(tài)圖片或文本)。在 CaptionAdder.java() 中,在創(chuàng)建了 quicktime.std.movies.Track 對(duì)象后,我在 textMedia.beginEdits() 語(yǔ)句和 textMedia.endEdits() 語(yǔ)句之間添加了文本標(biāo)題。在這個(gè)示例中,我用 quicktime.std.movies.TimeInfo 對(duì)象設(shè)置標(biāo)題在視頻中顯示的時(shí)間長(zhǎng)度,以及什么時(shí)候開(kāi)始顯示標(biāo)題。我想讓文本標(biāo)題在視頻的前半段顯示,所以我把 TimeInfo 設(shè)為從 0 開(kāi)始,并通過(guò) movie 的持續(xù)時(shí)間將它設(shè)置為運(yùn)行到一半時(shí)結(jié)束。





          回頁(yè)首


          使用 CaptionAdder.java

          那么該如何使用 CaptionAdder.java 呢?首先,調(diào)用 CaptionAdder.java 非常簡(jiǎn)單直接。在向類路徑中添加了 QuickTime for Java 庫(kù)之后,需要做的就是提供想要編輯的文件的名稱。例如,假設(shè)想向 圖 2 所示的房地產(chǎn)清單視頻添加標(biāo)題。


          圖 2. 沒(méi)有標(biāo)題的房地產(chǎn)視頻示例截圖
          沒(méi)有標(biāo)題的房地產(chǎn)視頻示例截圖

          要向這個(gè)文件添加標(biāo)題,只需如 清單 2 中所示那樣運(yùn)行 CaptionAdder.java 程序即可。


          清單 2. 使用 CaptionAdder.java
          java CaptionAdder listing22345.mov 
          

          結(jié)果顯示在 圖 3 中。


          圖 3. 添加了標(biāo)題的房地產(chǎn)視頻示例
          虛擬的房地產(chǎn)清單視頻在運(yùn)行了 CaptionAdder.java 之后的截圖




          回頁(yè)首


          轉(zhuǎn)換成 iPod 格式

          在有了使用 QuickTime for Java API 創(chuàng)建和操作視頻內(nèi)容的基礎(chǔ)之后,下一個(gè)主要障礙就是把內(nèi)容轉(zhuǎn)換成與 iPod 兼容的格式。不論使用攝像機(jī)、從活動(dòng)視頻源錄制,還是創(chuàng)建動(dòng)畫(huà)序列,視頻內(nèi)容都不會(huì)立即與 iPod 視頻播放器兼容。iPod 對(duì)于它播放的媒體的類型有點(diǎn)挑剔。表 1 顯示了 iPod 環(huán)境支持的視頻格式和設(shè)置。


          表 1. iPod 兼容內(nèi)容的視頻設(shè)置


          視頻格式

          數(shù)據(jù)率

          尺寸

          幀率
          H.264 視頻最高 768 Kbps320 x 240 像素30 fps
          MPEG-4 視頻最高 2.5 Mbps480 x 480 像素30 fps

          讓問(wèn)題更復(fù)雜的是,對(duì)于視頻中的音軌,它只支持高級(jí)音頻編碼 (AAC),所以如果想在 iPod 上播放視頻,不僅僅要轉(zhuǎn)換傳統(tǒng)視頻內(nèi)容。幸運(yùn)的是,可以求助于 MovieConverter.java,它是轉(zhuǎn)換傳統(tǒng)視頻內(nèi)容到 iPod 兼容格式的一個(gè)方便工具。MovieConverter.java清單 3 中所示。


          清單 3. MovieConverter.java
          import java.awt.*;
          import java.awt.event.*;
          import javax.swing.*;
          
          import java.io.IOException;
          
          import quicktime.*;
          import quicktime.io.*;
          import quicktime.qd.*;
          import quicktime.std.*;
          import quicktime.std.clocks.*;
          import quicktime.std.StdQTConstants;
          import quicktime.std.image.*;
          import quicktime.std.movies.*;
          import quicktime.std.movies.media.*;
          import quicktime.std.qtcomponents.*;
          import quicktime.util.*;
          
          import quicktime.app.view.*;
          
          public class MovieConverter extends JFrame implements Errors, ActionListener{
          	
            QTComponent component = null;  
            JPanel jpanel = null;
            Button selectButton = null;
          
            public static void main (String args[]) {
              try{
                new MovieConverter();
              } catch(Exception e){
                System.out.println(e);
              }
            }
          
            public MovieConverter(){
          
              super("Movie Converter");
          
              try { 
                QTSession.open();
              } catch (Exception e) {
                e.printStackTrace();
                QTSession.close();
              }
          
              jpanel = new JPanel();
          
              this.setContentPane(jpanel);
              selectButton = new Button ("Select a File to Convert");
              selectButton.addActionListener(this);
          
              jpanel.add (selectButton);
          
              addWindowListener(new WindowAdapter () {
                public void windowClosing (WindowEvent e) {
                  QTSession.close();
                  dispose();
                }
          
                public void windowClosed (WindowEvent e) { 
                  System.exit(0);
                }
              });     
          
              this.pack();
              this.setVisible(true);
          
            }
          
            public void actionPerformed (ActionEvent event) {
              exportMovie();    
            }
          
          
            void displayMovie (Movie m) throws QTException {
              component = QTFactory.makeQTComponent (new MovieController (m));
              jpanel.add ((Component)component);
              jpanel.remove(selectButton);
              pack();
            }
              
            void exportMovie () {
              try{
                FileDialog fileDialog = new FileDialog (this, 
                    "Choose Movie to Export...", FileDialog.LOAD);
                fileDialog.show();
                if (fileDialog.getFile() == null)
                  return;
                QTFile movieFile = new QTFile (fileDialog.getDirectory() 
                   + fileDialog.getFile());
                
                Movie movie = Movie.fromFile (OpenMovieFile.asRead(movieFile));
              
                if (component != null) {
                  component.setMovieController(new MovieController(movie));
                } else {
                  displayMovie (movie);
                }
              
                new Thread (new Exporter(movie)).start();
              
              } catch (QTException err) {
                err.printStackTrace();
              }
            }
            
          
          }
          





          回頁(yè)首


          使用 MovieConverter.java

          使用 MovieConverter.java 非常簡(jiǎn)單。在 圖 4 中,可以看到一個(gè)關(guān)于如何使用 Internet 的虛擬學(xué)術(shù)培訓(xùn)視頻的截屏(從 Google 的主頁(yè)開(kāi)始)。實(shí)際的影片文件是 AVI 格式,并且還包括授課錄音的音軌。


          圖 4. 示例學(xué)術(shù)培訓(xùn)視頻的截屏
          示例學(xué)術(shù)培訓(xùn)視頻的截屏

          MovieConverter.java 程序?qū)⑦@個(gè)視頻文件轉(zhuǎn)換成 iPod 兼容的格式很容易。在啟動(dòng) MovieConverter.java 之后,首先選擇要轉(zhuǎn)換的文件。然后指定新創(chuàng)建的文件的名稱,如 圖 5 中所示。


          圖 5. MovieConverter.java 請(qǐng)求新文件的名稱
          MovieConverter.java 請(qǐng)求新文件的名稱

          在指定了新視頻文件的名稱之后,應(yīng)用程序顯示一個(gè)影片設(shè)置總結(jié)屏幕,如 圖 6 中所示。在這個(gè)屏幕上,有修改編碼方式、壓縮算法的選項(xiàng),甚至可以對(duì)媒體應(yīng)用視頻過(guò)濾器。


          圖 6. 影片設(shè)置總結(jié)
          影片設(shè)置總結(jié)

          圖 7 中,可以看到 MovieConverter 的視頻設(shè)置窗口,在這個(gè)窗口中,可以選擇視頻編碼方式,而提供了轉(zhuǎn)換后的視頻預(yù)覽。


          圖 7. 視頻設(shè)置窗口
          MovieConverter.java 的視頻設(shè)置窗口

          設(shè)置好之后,MovieConverter 生成可以在 iPod 視頻播放器上播放的新視頻文件。還要注意的是,MovieConverter.java 是個(gè)功能豐富且強(qiáng)大的應(yīng)用程序。不但可以用它生成能夠在 iPod 媒體播放器上播放的視頻內(nèi)容,還能用它把傳統(tǒng)視頻轉(zhuǎn)換成 QuickTime 支持的其他視頻格式。





          回頁(yè)首


          結(jié)束語(yǔ)

          在數(shù)年之后,iPod 很有可能會(huì)領(lǐng)導(dǎo)便攜媒體播放器市場(chǎng)。目前這代 iPod 媒體播放器中添加了視頻內(nèi)容,這開(kāi)辟了許多令人興奮的營(yíng)銷和商業(yè)機(jī)會(huì)。在這篇文章中,我提供了移動(dòng)視頻內(nèi)容的一些實(shí)際和商業(yè)上的應(yīng)用,介紹了 QuickTime for Java API,并演示了如何用編程方式操縱移動(dòng)視頻文件,并將它轉(zhuǎn)換成與視頻 iPod 兼容的格式。





          回頁(yè)首


          參考資料

          學(xué)習(xí)

          獲得產(chǎn)品和技術(shù)

          討論




          回頁(yè)首


          關(guān)于作者

          Bruce Hopkins 是 Bluetooth for Java (Apress) 一書(shū)的作者,也是 JB-22 開(kāi)發(fā)包的制作者。他畢業(yè)于底特律的 Wayne 州立大學(xué),擁有電子和計(jì)算機(jī)工程的學(xué)士學(xué)位。他目前是 Gestalt LLC 的技術(shù)架構(gòu)師,專攻分布式計(jì)算、Web 服務(wù)和無(wú)線技術(shù)。您可以通過(guò)他的郵箱 bhopkins@gestalt-llc.com 與他聯(lián)系。

          posted on 2006-05-16 12:41 TrampEagle 閱讀(397) 評(píng)論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 沙雅县| 绿春县| 利辛县| 萝北县| 堆龙德庆县| 虎林市| 龙井市| 安阳市| 湖口县| 卫辉市| 峡江县| 洪泽县| 桃园县| 滦平县| 宜兰县| 阳西县| 茌平县| 城市| 新化县| 肇东市| 新河县| 江门市| 印江| 铅山县| 桑日县| 容城县| 富锦市| 驻马店市| 旅游| 多伦县| 高密市| 贵州省| 易门县| 辽中县| 克东县| 抚顺市| 巴楚县| 浪卡子县| 大关县| 安福县| 阿荣旗|