文章詳情頁
基于Java 開發(fā)QuickTime 程序
瀏覽:3日期:2024-06-16 13:09:31
內(nèi)容: 摘要:QuickTime 視頻文件播放程序如今已經(jīng)發(fā)展和成長15年了,在添加新特性的同時也保持了極好的向后兼容性:1990年在系統(tǒng)6或7上制造的QuickTime movie2005年仍然能在Mac 操作系統(tǒng)X 10.3.7上播放。這是因為QuickTime 的共享代碼片段的組件系統(tǒng)可被發(fā)現(xiàn)和被動態(tài)的調(diào)用。QuickTime 所需要用來播放movie的大部分是一個組件:理解文件格式的代碼;使在文件中使用的音頻,視頻,或其他編解碼器減壓的代碼;處理流媒體協(xié)議的代碼;等等。舊的組件簡單的維護,新的組件向QuickTime 添加了更多的功能。當QuickTime 的一個新版本增加了對新的格式或編解碼器的支持,或當用戶自己安裝了新的特性,一個運行良好的應用程序?qū)詣釉黾舆@些新的特性。并且,幸運地,組件為Java 程序員做好了準備,他們可以使用適合于Java 應用編程接口的QuickTime 。在這篇來自《適用于JAVA的QuickTime :開發(fā)者的寶典》,Chris Adamson 指出怎么寫這樣一個性質(zhì)良好的應用程序。第四章:用組件工作介紹了組件的類型和子類型的識別模式并指出如何導出一個QuickTime movie到固定格式,或運行時能找到的任何格式。它說明了如何導入導出圖形,并提供了顯示所有已安裝組件的一個實用程序。版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時請務必保留以下作者信息和鏈接作者:Chris Adamson;Amydeng(作者的blog:http://blog.matrix.org.cn/page/Amydeng)譯文:http://www.matrix.org.cn/resource/article/44/44269_Java+QuickTime.html關(guān)鍵字:Java;QuickTime用組件工作 當QuickTime1990年問世的時候,它能夠播放一張郵票大小的movie——僅僅在價值7000美圓的硬盤上。它使用音頻和視頻的編解碼器,盡管這些編解碼器今天仍然被支持,但已被用戶淘汰很久了。然而,從 Apple 視頻到Cinepak 視頻再到MPEG-4,是一個平滑的變換。這是由于一個特別的標準化設計——QuickTime 里大部分繁重的任務都是由組件或共享的動態(tài)代碼執(zhí)行。組件提供了如下的支持:導入導出圖片和movie格式,執(zhí)行圖片和聲音的壓縮和解壓縮,訪問系統(tǒng)資源及更多其它功能。QuickTime安裝程序提供了很多組件,這些組件具備許多有效的特性,而用戶也可以自己從Apple或者第三方添加其他組件進來,這些組件能夠提供更多的功能,如支持更多的多媒體格式。 API里組件并不處于中心位置——畢竟,在開始的幾章里已經(jīng)設法完全避免提到它們。當我們需要打開文件并將它們轉(zhuǎn)換為movie,解壓縮和解釋數(shù)據(jù),保存它們到硬盤等等時,這個時候我們QuickTime做正確的事情。當需要的時候,QuickTime為了必需的功能瀏覽它的組件目錄并得到它所需要的東西。 但是有些時候開發(fā)者為了指出什么是可用的,或者為了指定特定地行為,或者需要更直接地使用組件。這個時候, 找出運行時可用的工具是一個強有力的方法。指定組件類型 QuickTime里,組件由類型和子類型來識別,類型指定了功能范圍,子類型是該功能的一個特定實現(xiàn)。例如,有一個“movie 導出器類型,代表可以導出一部movie到非QuickTime格式的組件。它用子類型確定適合AVI(Video for windows 的多媒體文件格式),MPEG-4的導出器, 這些標識符是32比特的整型值,但它們不列舉你可能期望來自JAVA的常數(shù)。通常地,32比特被分成是4個8比特的ASCII 字符來讀取,組成一個簡短的,易讀的名字。這些在本地API包里定義為OSTypes類型,但是當與有意義的值組裝到一起時,它們被稱為“四字符代碼,來自本地FOUR_CHAR_CODE函數(shù),該函數(shù)為一個字符串返回一個OSType類型。這經(jīng)常簡稱為 FCC或4CC。 這種模式采納了C程序員的觀點。例如,為一部movie定義4CC需要一個好的,簡單的短語,就像在本地頁眉文件Movies.h 中所見的一樣: MovieResourceType = 'moov' 然而,由于Java的更先進的文本處理方法,在Java中用4CCs 處理要困難的多。因為,Unicode的應用意味著每個 Java字符是2個比特,這說明我們需要額外的幫助來將Java字符轉(zhuǎn)化為4CC。我們?nèi)绾巫瞿兀? 幸運地,QTUtils類提供了2個方法:toOSType()和fromOSType()。例4-1展示了這些方法,將一個Java 字符串轉(zhuǎn)化為一個4CC 表示,并從它的4CC 表示轉(zhuǎn)化回來。Example 4-1. Converting to and from FOUR_CHAR_CODEs package com.oreilly.qtjnotebook.ch04;import quicktime.util.QTUtils;public class FourCharCodeTest extends Object { public static void main (String[] args) { if (args.length < 1) { System.out.println ('Usage: FourCharCodeTest '); return; } System.out.println (args[0])int fcc = QTUtils.toOSType (args[0]); System.out.println (fcc); System.out.println (Integer.toHexString (fcc)); String fccString = QTUtils.fromOSType(fcc); System.out.println (fccString); }}main()函數(shù)從命令行取得一個String ,把它轉(zhuǎn)換成一個4CC,打印出4CC的十進制和十六進制值,然后把它轉(zhuǎn)換回一個String 。用moov 作實驗時,導出如下: 剛剛發(fā)生了什么?這些有用的方法提供了一些好的,老式的bit-munging來做它們的轉(zhuǎn)換。toOSType()以一個String 為依據(jù),取每個字符的低8位并把它們放在所返回整型值的適當位置。換句話說,第一個字符的低8為代替了整數(shù)的開始8位,然后下一個字符作為下一個8位,等等。圖4-1說明了在 'moov'位轉(zhuǎn)移中在哪里位結(jié)束。(圖4-1)fromOSType()做相反的轉(zhuǎn)換,轉(zhuǎn)換整型的比特位為一個四字符的Java 字符串。導出movie 最明顯的有用的組件之一是MovieExporter,你可以用它來將一個QuickTime movie轉(zhuǎn)換為一個非QuickTime 格式的movie,如AVI 或MPEG-4。我們?nèi)绾巫瞿兀款恞uicktime.std.qtcomponents.MovieExporter圍繞movie導出組件提供了方便的Java 封裝。這需要你傳遞給它一個子類型參數(shù),告訴他你想使用哪種導出類——也就是,你想要導出為哪種格式。例4-2展示了從固定的子類型列表中創(chuàng)造和利用MovieExporter。Example 4-2. Simple MovieExporter creation and use package com.oreilly.qtjnotebook.ch04;import quicktime.*;import quicktime.std.*;import quicktime.std.movies.*;import quicktime.io.*;import quicktime.std.qtcomponents.*;import quicktime.utils.QTUtils;import java.awt.*;import javax.swing.*;import com.oreilly.qtjnotebook.ch01.QTSessionCheck;public class SimpleMovieExport extends Object { public static final void main (String[] args) { new SimpleMovieExport(); } public SimpleMovieExport() { // build choices ExportChoice[] choices = new ExportChoice[3]; choices[0] = new ExportChoice ('QuickTime Movie', StdQTConstants.kQTFileTypeMovie); choices[1] = new ExportChoice ('AVI file', StdQTConstants.kQTFileTypeAVI); choices[2] = new ExportChoice ('MPEG-4 file', QTUtils.toOSType('mpg4')); try { // query user for a movie to open QTSessionCheck.check(); QTFile file = QTFile.standardGetFilePreview (QTFile.kStandardQTFileTypes); OpenMovieFile omFile = OpenMovieFile.asRead (file); Movie movie = Movie.fromFile (omFile); // offer a choice of movie exporters JComboBox exportCombo = new JComboBox (choices); JOptionPane.showMessageDialog (null, exportCombo, 'Choose exporter', JOptionPane.PLAIN_MESSAGE); ExportChoice choice = (ExportChoice) exportCombo.getSelectedItem(); // create an exporter MovieExporter exporter = new MovieExporter (choice.subtype); QTFile saveFile =new QTFile (new java.io.File('Untitled')); // do the export movie.setProgressProc(); movie.convertToFile (null, saveFile, StdQTConstants.kQTFileTypeMovie, StdQTConstants.kMoviePlayer, IOConstants.smSystemScript, StdQTConstants.showUserSettingsDialog | StdQTConstants.movieToFileOnlyExport | StdQTConstants.movieFileSpecValid, exporter); // need to explicitly quit (since awt is running) System.exit(0);} catch (QTException qte) { qte.printStackTrace();}} public class ExportChoice {String name; int subtype; public ExportChoice (String n, int st) { name = n; subtype = st; } public String toString() { return name; } }}運行時,程序提示用戶打開一個movie文件。一旦movie裝載了,程序提供一個導出格式選擇對話框。如圖4-2所示。 Figure 4-2. Choice dialog with canned MovieExporter types 然后,顯示一個保存對話框提示導出信息(例如,“轉(zhuǎn)換為MPEG-4格式)和一個選擇按扭。該按扭關(guān)聯(lián)一個明確導出格式的對話框。例如,AVI 導出對話框相當簡單,僅僅提供幾個設置供選擇。相反,MPEG-4導出對話框,圖4-3所示,格外的繁瑣,充斥著多種選擇的描述,幫助用戶理解他們的選擇和并會保證他們的導出文件適應MPEG-4的標準。 在用戶做了選擇并按下OK鍵后,比較長的導出過程便開始了。因為movie導出是潛在的計算密集的,每個視頻畫面和每個音頻示例都必須被重新編碼——這個過程之間會出現(xiàn)一個進度框,這樣用戶可以看到導出過程完成了多少,還要花多長時間。剛剛發(fā)生了什么?這個程序使用了一個內(nèi)部類ExportType 封裝一個子類型,整型和一個字符串。很大程度上是為了簡化在格式選擇對話框中使用的JcomboBox 。這些子類型來自StdQTConstants 中定義的常量。一旦做出了選擇,程序?qū)⒆宇愋蛥?shù)傳遞給它的構(gòu)造器來選擇適當?shù)腗ovieExporter。下一步,調(diào)用setProgressProc()方法請求一個前進對話框。最后,通過調(diào)用convertToFile()方法,程序開始執(zhí)行導出。這個方法需要幾個參數(shù): Track ,指明僅僅導出這個軌跡,null代表需要導出所有軌跡。 QTFile ,導出到的文件。 文件類型,如StdQTConstants.kQTFileTypeMovie。 一個構(gòu)造器,如StdQTConstants.kMoviePlayer。 一個腳本標簽,典型的是IOConstants.smSystemScript。 行為標志。這個例子使用了所有3個有效值:showUserSettingsDialog 讓導出過程調(diào)用包含文件名和選擇按扭的保存對話框;movieToFileOnlyExport 限制導出組件的導出選擇格式子類型;movieFileSpecValid 聲明QTFile 是有效的并且應該作為默認在對話中作為默認值使用。 MovieExporter 用來進行導出。關(guān)于…… 用MovieExporter 本身來導出?那是一個可供選擇的辦法。導出器的toFile()方法導出movie到一個文件,而toHandle()方法導出文件到內(nèi)存。同時也可以僅導出部分movie,比如指定開始時間和持續(xù)時間參數(shù)。注意要這樣做的話需要不同的程序流程,因為首先你需要得到有效的QTFile (可能是用AWT文件對話框),然后你需要調(diào)用導出器的doUserDialog()方法去設定導出。Movie 類的convertToFile()方法能更方便一些,因為,像這兒所看到的,它允許使用默認的前進對話框。當使用MovieExporter 方法時,程序無權(quán)訪問默認對話框。在那種情況下,唯一可選的辦法是提供一個自定義的前進對話框和用setProgressProc()方法處理進程回調(diào)。也有不好的地方:我試著在windows下導出MPEG-4,但得不到任何音頻選項。當我點擊導出對話框里的音軌菜單,我得到如圖4-4所示的無用的面板。 這不是技術(shù)上的問題而是一種合理的情況。Apple 得到了適合它的基于Mac的QuickTime 用戶的MPEG-4的音頻編碼許可,但不適合Windows 用戶。這個編解碼器存在,但顯然你必須就許可條件聯(lián)系Dolby ,讓它們適合Windows操作系統(tǒng)。導出movie到任何已安裝的格式 導出到已知格式的列表會受到一些限制——如果終端用戶已經(jīng)安裝了新的或者來自第三方或者是QuickTime自身更新的movie 導出器,使用固定導出器列表的程序?qū)⒉荒茏R別他們。幸運的是,QuickTime提供了一個詢問方法可以查詢到關(guān)于某個類型目前已經(jīng)安裝的組件。你可以用這個策略找到所有可用的導出器列表。我如何做那個呢? AdvancedMovieExport 排除了SimpleMovieExport 所用的選擇數(shù)組里的3個固定入口改,而通過動態(tài)發(fā)現(xiàn)來構(gòu)造數(shù)組。這段代碼將代替SimpleMovieExport 構(gòu)造器里的“build choices代碼塊但需要添加到try-catch內(nèi)部,因為它可能拋出QTException異常。運行時,支持的導出器列表讓人出乎意料的大,如圖4-5所示。在這種情況下,一個“普通的movie,這將會導出一個video track和一個audio track,這意味著任何只導出audio或audio/video格式都行。 你也應該注意,一些導出器不能導出movie。這些是比較笨的標準: 這些失敗是因為源movie中沒有包含可以導出為這些格式的tracks。源movie有各種不同的tracks時,一些能成功導出,另一些將會失敗。剛剛發(fā)生了什么?由子類型尋找組件的過程是非常奇特的。它重復調(diào)用“find方法,傳入上一個匹配的組件。這樣做需要一個ComponentDescription來作為模板進行下一次匹配,同時需要一個ComponentIdentifier, 代表特定的組件(并不是該特定的組件的實例)。為了找到movie導出器,用常量movieExporterType來初始化ComponentDescription 模板。靜態(tài)ComponentIdentifier.find()方法會尋找匹配的組件,但要求你重復地傳入ComponentDescription 模板以及該方法先前找到的ComponentIdentifier。第一次重復時,將是空值。調(diào)用find()方法返回一個ComponentIdentifier,傳遞給MovieExporter 構(gòu)造器創(chuàng)造一個新的導出。find()返回空時,表明不再有合適的匹配。匹配的ComponentIdentifier 通過getInfo()方法提供了關(guān)于它自身的信息。這將會返回另一個ComponentDescription 對象,不同于之前作為模板使用的ComponentDescription對象。你可以利用這個去得到類型和子類型的信息(FOUR_CHAR_CODE ints),名字,消息字符串,制造商代碼等等。找到一個MovieExporter 并不能夠保證它能真正的工作。你可以調(diào)用validate()方法,像這個例子這樣,來檢查示例的導出器能夠?qū)С鼋o定的movie。在這個例子中,如果validate()方法拋出異常,它就是非標準的并且導出器沒有被添加到JcomboBox。關(guān)于……能否通過程序來設置導出參數(shù),而不是每次都使用導出對話框?這是可能的,盡管需要開發(fā)中至少需要使用一次導出對話框。一個配置好了的MovieExporter 經(jīng)由getExportSettingsFromAtomContainer()方法能夠以AtomContainer對象的形式返回它的配置狀態(tài)。 這個AtomContainer對象可以經(jīng)由setExportSettingsFromAtomContainer()方法傳遞給一個導出器。在單獨的應用程序里,這是非常直接的。為了保證各個sessions之間的持久,你必須在AtomContainer 上調(diào)用getBytes()得到本地結(jié)構(gòu)然后把它保存到硬盤,數(shù)據(jù)庫等。這樣,將來我們能夠重新生成這個配置,將所有字節(jié)讀入一個字節(jié)數(shù)組,從該數(shù)組中創(chuàng)造一個QTHandle ,然后將它傳遞給AtomContainer.fromQTHandle()來創(chuàng)建AtomContainer。QuickTime 6.3版引入了一個新API來設置導出器,但是這樣寫,它沒有通過QTJ方法的調(diào)用顯示出來。而且,如果我指定類型和子類型,我將總是得到一個匹配嗎?不,在一些情況下,你將得到多重匹配組件,并且你可能需要使用其它的標準來選擇用哪一個。在一個相當經(jīng)典的case中我的一位技術(shù)導師指出了:某些時候用同樣的子類型你得到了不止一個導出器,這個時候你需要用“manufacturer代碼去區(qū)分它們。 這特別適用于AIFF導出器——你所找到的第一個導出器類型僅導出MIDI類型。為了導出任意的QT視頻文件到AIFF,你需要明確地迭代并繼續(xù)選擇第二個!導入導出圖形QuickTime提供了許多組件來導入導出不同的圖象格式。正如你所期望的,這些組件被封裝在類GraphicsImporter和GraphicsExporter里。GraphicImportExport例示應用程序使用了這兩個類來說明動態(tài)的查找輸入導出器。Example 4-3. Graphics import and exportpackage com.oreilly.qtjnotebook.ch04;import quicktime.*;import quicktime.io.*;import quicktime.std.*;import quicktime.std.comp.*;import quicktime.std.image.*;import quicktime.app.view.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.Vector;import java.io.*;import com.oreilly.qtjnotebook.ch01.QTSessionCheck;public class GraphicImportExport extends Object { Button exportButton; Frame frame; GraphicsImporter importer; static final int[] imagetypes = { StdQTConstants.kQTFileTypeQuickTimeImage}; /* other interesting values: StdQTConstants.kQTFileTypeGIF, StdQTConstants.kQTFileTypeJPEG, StdQTConstants4.kQTFileTypePNG, StdQTConstants4.kQTFileTypeTIFF StdQTConstants.kQTFileTypeMacPaint, StdQTConstants.kQTFileTypePhotoShop, StdQTConstants.kQTFileTypePICS, StdQTConstants.kQTFileTypePicture, */ public static void main (String[] args) { new GraphicImportExport(); } public GraphicImportExport() { try { QTSessionCheck.check(); QTFile inFile = QTFile.standardGetFilePreview (imagetypes); importer = new GraphicsImporter (inFile); // put image onscreen QTComponent qtc = QTFactory.makeQTComponent (importer); java.awt.Component c = qtc.asComponent(); frame = new Frame ('Imported image'); frame.setLayout (new BorderLayout()); frame.add (c, BorderLayout.CENTER); exportButton = new Button ('Export'); exportButton.addActionListener (new ActionListener() { public void actionPerformed (ActionEvent ae) { try { doExport(); } catch (QTException qte) { qte.printStackTrace(); } } }); frame.add (exportButton, BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } catch (QTException qte) { qte.printStackTrace(); } } public void doExport() throws QTException { // build list of GraphicExporters Vector choices = new Vector(); ComponentDescription cd = new ComponentDescription ( StdQTConstants.graphicsExporterComponentType); ComponentIdentifier ci = null; while ( (ci = ComponentIdentifier.find(ci, cd)) != null) { choices.add (new ExportChoice (ci.getInfo().getName()ci.getInfo().getSubTyp } // offer a choice of movie exporters JComboBox exportCombo = new JComboBox (choices); JOptionPane.showMessageDialog (frame,exportCombo,'Choose exporter',JOptionPane.PLAIN_MESSAGE); ExportChoice choice = (ExportChoice) exportCombo.getSelectedItem(); System.out.println ('chose ' + choice.name); // build a GE, wire up to the GraphicsImporter GraphicsExporter exporter = new GraphicsExporter (choice.subtype); exporter.setInputGraphicsImporter (importer); // ask for destination, settings FileDialog fd = new FileDialog (frame, 'Save As', FileDialog.SAVE); fd.setVisible(true); String filename = fd.getFile(); if (filename.indexOf('.') == -1) filename = filename + '.' + exporter.getDefaultFileNameExtension(); File file = new File (fd.getDirectory(), filename); exporter.setOutputFile (new QTFile(file)); exporter.requestSettings();// export exporter.doExport(); // need to explicitly quit (since awt is running) System.exit(0); } public class ExportChoice { String name; int subtype; public ExportChoice (String n, int st) { name = n; subtype = st; } public String toString() { return name; } }}運行時,程序顯示一個對話框,選擇要導入的圖形。在Windows環(huán)境下,該對話框里的“文件類型是QuickTime圖象。一旦圖象被選定,它和一個“導出按扭一起顯示在窗口中。當用戶點擊該按扭,她會詢問你類型,如圖4-6所示。 之后,程序顯示一個配置對話框指定選定的導出類型——最小值,這個對話框也提供一個顏色深度的選擇(256色,256灰度,百萬像素等等)。下一步,將會出現(xiàn)一個保存對話框, 要求你指定導出文件的位置。一旦通過,程序轉(zhuǎn)換該圖象到指定的格式,并保存在提供的位置。剛剛發(fā)生了什么?注意QTFile.standardGetFilePreview(),它顯示一個文件打開對話框并帶出一串4整型的數(shù)字,代表各種文件格式常數(shù)的FOUR_CHAR_CODEs,作為可選文件類型的過濾器。你可以利用QTFileTypeQuickTimeImage作為方便的通配符來匹配QuickTime能打開的任何種類的圖象,盡管它看起來僅工作在Windows操作系統(tǒng)上(實際上, 在Mac上,任何文件都可被選中)。給定一個文件,你可以創(chuàng)建一個GraphicsImporter對象將它裝載到QuickTime。為了導入圖片到屏幕上,需要將importer傳給 QTFactory.makeQTComponent()方法,該方法返回一個QTComponent,你可以造型(cast)為一個AWT組件, 或者為了類型安全安全,通過asComponent()方法來轉(zhuǎn)換為了將圖片導出到另外一種格式,你可以通過創(chuàng)造一個ComponentDescription模板來匹配graphicsExporterComponentType的組件, 來查找導出器的子類型。在例子中,匹配組件的名字將出現(xiàn)在一個JComboBox里。當一個子類型被選中了,傳遞該子類型到GraphicsExporter的構(gòu)造函數(shù)來創(chuàng)建GraphicsExporter對象。GraphicsExporter需要綁定到某類型的圖片源。有了GraphicsImporter,你可以用setInputGraphicsImporter()方法來實現(xiàn)這點。導出器還需要一個目的文件。如果寫出到一個文件,你可以用setOutputFile()來設置它——僅為了安全起見,檢查用戶提供的文件擴展名和導出器用getDefaultFileNameExtension()方法返回的值是明智的。用戶可能想在導出顏色,圖片質(zhì)量,和其它設置上進行某些改變,這個時候,requestSettings()方法可提供一個對話框。所有這些做完后,你可以用doExport()方法來導出了。關(guān)于…有其它的源適合該導出嗎?GraphicsExporter的Javadoc提供了一系列的setInputXXX()方法。在下一章,我們將探討這些問題,包括Picts, QDGraphics,和PixMaps。那么關(guān)于導出參數(shù)的設置呢?QTJ有一些方法可以代替用戶對話框。像setDepth()和setCompressionMethod()。一個有趣的方法,setTargetDataSize(),讓導出器可以有“quality選擇(像JPEG)找一個值將導致產(chǎn)生一個給定字節(jié)大小的文件。發(fā)現(xiàn)所有已安裝的組件我希望到這里,你至少對適用于QuickTime的其它組件有了些許的興趣。很容易發(fā)現(xiàn)所有的組件,用一個相同的方法我們可以發(fā)現(xiàn)各種MovieExporters和GraphicExporters:提供一個ComponentDescription模板,并利用ComponentIdentifier.find()方法。而使用一個空白模板,將會顯示所有的組件。我怎樣做呢?例子4-4發(fā)現(xiàn)了所有已安裝的組件并記錄了他們的類型,子類型和描述。Example 4-4. Discovering al instaled componentspackage com.oreilly.qtjnotebook.ch04;import quicktime.*;import quicktime.std.*;import quicktime.std.comp.*;import quicktime.util.QTUtils;import com.oreilly.qtjnotebook.ch01.QTSessionCheck;public class ComponentTour { public static void main (String[] args) { try { QTSessionCheck.check(); /* use this wildcard to show all components in QT */ ComponentDescription wildcard = new ComponentDescription(); ComponentIdentifier ci = null; while ( (ci = ComponentIdentifier.find(ci, wildcard)) != null) { ComponentDescription cd = ci.getInfo(); System.out.println (cd.getName() + ' (' + QTUtils.fromOSType (cd.getType()) + '/' + QTUtils.fromOSType (cd.getSubType()) + } catch (QTException qte) { qte.printStackTrace(); } }}導出結(jié)果有幾百行長,像下面這樣:run-ch04-componenttour:[java] Apple MP3 Decoder (adec/.mp3) An AudioCodec that decodes MPEG-1,MPEG-2, MPEG-2.5 Layer III into linear PCM data[java] MPEG-4 AAC Decoder (adec/aac ) An AudioCodec that decodes MPEG-4AAC into linear PCM data [java] Apple Lossless Decoder (adec/alac) An AudioCodec that decodesApple Lossless into linear PCM data [java] Apple IMA4 Decoder (adec/ima4) An AudioCodec that decodes IMA4into linear PCM data[java] MPEG-4 AAC Encoder (aenc/aac ) An AudioCodec that encodes linearPCM data into MPEG-4 AAC [java] Apple Lossless Encoder (aenc/alac) An AudioCodec that encodeslinear PCM data into Apple Lossless[java] Apple IMA4 Encoder (aenc/ima4) An AudioCodec that encodes linearPCM data into IMA4 [java] Applet (aplt/scpt) The component that runs script applications [java] Apple: AUConverter (aufc/conv) AudioConverter unit [java] Apple: AUVarispeed (aufc/vari) Apple's varispeed playback[...]剛剛發(fā)生了什么?關(guān)鍵點是通過沒有參數(shù)的構(gòu)造器得到ComponentDescriptor的那行。這為ComponentIdentifier. find()方法創(chuàng)建了一個完全的空白模板。當然,如果你僅僅想遍歷特定類型的組件,你可以傳遞一個像StdQTConstants,movieImportType的類型值,限制MovieImporters的查找,這樣,指明QuickTime可以導入的格式類型。證明和解釋每種類型的組件超出了本書的范圍——實際上,在舊的Macintosh series中它們占了大量的篇幅。當然,重要的一些在表4-1中列出來了。注意不是所有的組件都在Java封裝類里。 待續(xù)..資源:Matrix Java社區(qū): http://www.matrix.org.cn Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標簽:
Java
相關(guān)文章:
1. Java實現(xiàn)基于http協(xié)議的網(wǎng)絡文件下載2. .NET一行代碼實現(xiàn)GC調(diào)優(yōu),讓程序不再占用內(nèi)存3. 基于Idea+Jconsole實現(xiàn)線程監(jiān)控步驟4. PHP如何開啟Opcache功能提升程序處理效率5. 基于python調(diào)用jenkins-cli實現(xiàn)快速發(fā)布6. 如何基于python3和Vue實現(xiàn)AES數(shù)據(jù)加密7. Java可以寫android的應用程序嗎8. python基于pygame實現(xiàn)飛機大作戰(zhàn)小游戲9. 基于Android FileProvider 屬性配置詳解及FileProvider多節(jié)點問題10. Python基于requests實現(xiàn)模擬上傳文件
排行榜
