Напредък в JMF и Java Media API

Първата ми статия за JavaWorld, когато бях в Java Media Framework (JMF). Тъй като различните API на Media са узрели, чувствам, че нещата са завършили пълно. Затова ще посветя последната си колона за медийно програмиране на преразглеждане на JMF и общото състояние на всички Java Media API.

Има някои забележителни промени в JMF и други Java Media технологии, компаниите, разработващи внедряването им, и тяхната наличност за разработчици. Тази статия актуализира материала от предишни статии, както е подходящо.

Важно напомняне: Java Media Framework е специфичен API за синхронизиране на мултимедийни потоци (файлове, мрежови потоци и т.н.). Това е един от няколкото Java Java API, които също включват Java 2D, Java 3D, Java Speech и т.н. Имам предвид Java Media Framework като JMF, запазвайки термина Java Media за цялата колекция от мултимедийни API.

История и основи на JMF

От JMF 1.0, известен още като API на Java Media Player, написах следното през април 1997 г. (вж. Ресурси):

API на Java Media Player, част от Java Media Framework (JMF), позволява на Java програмистите лесно да вграждат аудио и видео в аплети и приложения. Статичните и поточните мултимедия се поддържат от всеки валиден URL адрес. JMF плейърите могат да бъдат контролирани от други плейъри, осигуряващи синхронно възпроизвеждане на множество аудио и видео проби.

Тази информация все още е вярна с актуализациите и допълненията от последните две години. JMF обаче разработи нови възможности и разшири обхвата си, особено с предстоящата версия 2.0 API (очаква се през втората половина на 1999 г.).

JMF играчи в индустрията

Първо, нека да разгледаме играчите в бранша. Sun, Silicon Graphics (SGI) и Intel проектираха и определиха оригиналния JMF 1.0 в средата на 1998 г. Междувременно от първоначалната версия на API, както SGI, така и Intel се оттеглиха от процеса на спецификация на JMF. За известно време в потребителската общност на JMF имаше значителна загриженост, че Sun е единственият доставчик, който поддържа JMF. Тази ситуация беше нежелана.

За щастие, в края на 1998 г. IBM се намеси с интерес към JMF. Малко след като IBM се присъедини към Sun, беше пусната изцяло Java реализация на 1.0 API (декември 1998 г.). Тази реализация, известна като JMF 1.1 за Java платформи, поддържа ограничена, но значителна подгрупа от типове съдържание и протоколи, поддържани от реализациите на Win32 и Solaris-родния JMF 1.1 (известни като пакети за изпълнение). Наличието на изцяло Java JMF 1.1 беше основен етап за JMF, тъй като технологията стана достъпна за всяка съвместима с Java 1.1 или Java 2 среда за изпълнение. Всъщност внедряването на JMF 1.1 Java се предлага дори в уеб-ориентирана версия с инструменти, които позволяват на разработчиците да включват само съответните класове JMF в JAR файл за изтегляне с техните JMF аплети. Това позволява да се разположи базираните на JMF аплети на уеб сървър за използване от всеки браузър, съвместим с Java 1.1. Както Netscape, така и Microsoft поддържат Java 1.1 - и следователно JMF 1.1 за Java - в скорошните им версии на Navigator и Internet Explorer, съответно.

IBM помага на Sun да дефинира JMF 2.0 API, който ще включва спецификация и ще предостави справочна реализация на следващия JMF API: Java Media Capture. Да се ​​надяваме, че IBM ще разбере как впоследствие да внедри JMF функционалността в някои от своите бизнес-ориентирани Java-базирани софтуерни продукти - потенциално добро нещо за дълголетието на JMF технологията.

Какво е новото в JMF 2.0 срещу 1.0?

API на JMF 1.0 определя компонентите, необходими за възпроизвеждане на синхронизирано аудио и видео. Моля, обърнете се към предишната ми статия за JMF (вж. Ресурси) за преглед на възможностите на JMF 1.0.

JMF 2.0 прави няколко ключови допълнения към спецификацията:

  • Аудио и видео заснемане
  • Поточно предаване на аудио и видео и по този начин възможността за изграждане на изцяло Java поточни сървъри в допълнение към клиентите
  • Поддръжка на кодек с възможност за включване в играчите

За повече информация относно JMF 2.0 и неговите нови възможности, моля, вижте Ръководството на Java Media Framework Programmer (вж. Ресурси), достъпно в момента във версия 0.5 за ранен достъп.

Инсталиране на инструменти за разработка на JMF и време за изпълнение

Както Silicon Graphics, така и Intel премахнаха предишните версии на JMF от съответните си уеб сайтове. Можете обаче да изтеглите най-новите референтни внедрения (обозначени JMF 1.1, съвместими със спецификациите на 1.0 API) за платформи Win32, Solaris и Java от сайта Sun (вижте Ресурси).

Имайте предвид, че в документацията за изцяло Java версията се споменава специално AIX, което показва, че IBM е тествал този софтуер по време на изпълнението си на AIX Java. Очаквам бъдещите издания на JMF (2.0 и по-нови) да поддържат конкретно операционната среда на IBM, независимо дали чрез чисто Java изпълнение или специфични за операционната система приложения.

Актуализирани примери за JMF

Актуализирах бета-съвместимия JMF 1.0 пример от предишната ми статия за JMF, за да се изпълнява в JMF 1.0 API-съвместими среди. Можете да изтеглите примерния код и да го изпробвате под изпълнение на JMF 1.1, като използвате свои собствени медийни файлове. Аплетът също трябва да се изпълнява по време на изпълнение на JMF 2.0, когато станат налични. (За да изтеглите всички файлове, свързани с тази статия, в zip формат, вижте Ресурси.)

001 // Коментирайте следния израз на пакета, за да го компилирате отделно. 002 // пакет com.javaworld.media.jmf; 003 004 импортиране на java.applet. *; 005 импортиране на java.awt. *; 006 импорт java.net. *; 007 внос java.io. *; 008 импортиране на javax.media. *; 009 010 / ** 011 * JMF11Applet актуализира JMFApplet от април 1997 012 * JavaWorld статия за JMF 1.1 API-съответствие. Моля, 013 * вижте статията на адрес:

014 * //www.javaworld.com/jw-04-1997/jw-04-jmf.html 015 *

016 * В допълнение, JMF11Applet е преработен, за да използва 017 * модел на събитие Java 1.1 (и по-нататък). Тази версия 018 * е разработена и тествана на Java 2 019 * и внедряването на JMF 1.1 изцяло на Java, май 1999 г. 020 *

021 * Този аплет може да бъде разположен на публични уеб сървъри 022 * с помощта на jmf-server.jar, предоставен в JMF 1.1 023 * за изтегляне на уеб сървъри. Този JAR архив съдържа 024 * необходимите класове за изпълнение на JMF за всички Java. JMF11Applet 025 * е разположен по този начин за колоната от юни 1999 026 *:

027 * //www.javaworld.com/jw-06-1999/jw-06-media.html 028 * 029 * @author Bill Day 030 * @version 1.1 031 * @see javax.media.ControllerEvent 032 * @see javax .media.ControllerListener 033 * @see javax.media.Manager 034 * @see javax.media.NoPlayerException 035 * @see javax.media.Player 036 * @see javax.media.RealizeCompleteEvent 037 ** / 038 039 публичен клас JMF11Applet се разширява Аплетът реализира ControllerListener {040 private URL myURL = null; 041 частен играч myPlayer = null; 042 private Component myVisual = null; 043 частен компонент myControls = null; 044 частен панел visualPanel = null; 045 046 / ** 047 * Инициализирайте JMF11Applet. Излагаме интерфейса и 048 * създаваме нашия плейър в init (). 049 ** / 050 public void init () {051 super.init (); 052 053 // Посочете AWT Layout Manager. 054 setLayout (нов BorderLayout ());055 056 // Зареждане на URL от уеб страницата JMF11Applet е вграден. 057 String asset = getParameter ("ASSET"); 058 059 // Проверете URL и създайте URL обект, който да го задържи. 060 if (activ.equals ("")) {061 // не сме въвели актив в аплета. 062} else {063 опитайте {064 myURL = нов URL (getDocumentBase (), актив); 065} catch (MalformedURLException e) {066 // Въведохме непълен актив или изградихме грешен URL адрес. 067 // По-здравият аплет трябва да се справи с това елегантно. 068} 069} 070 опитайте {071 // Ето един интересен бит. Мениджърът се използва за 072 // създаване на действителния плейър за този URL адрес. След това 073 // добавяме JMF11Applet като ControllerListener за myPlayer. 074 // Това ни позволява да реагираме на RealizeCompleteEvents. 075 myPlayer = Manager.createPlayer (myURL); 076 myPlayer.addControllerListener (това);077} catch (IOException e) {078 // Възникна проблем с I / O; изход. 079 System.out.println ("Проблем с I / O при опит за създаване на плейър ... излизане"); 080 System.exit (1); 081} catch (NoPlayerException e) {082 // Не може да се върне използваем Player; изход. 083 System.out.println ("Няма върнат играч ... излизане"); 084 System.exit (1); 085} 086} 087 088 / ** 089 * Заменете метода за стартиране на аплета по подразбиране, за да извикате 090 * на Player (). Това първо ще направи реализацията, която от своя страна 091 * задейства финалните битове на изграждането на GUI в метода controllerUpdate () 092 *. Не стартираме автоматично възпроизвеждане: Потребителят се нуждае от 093 *, за да кликне върху бутона „пусни“ в нашия аплет, за да започне възпроизвеждането на образец на медия 094 *. 095 ** / 096 public void start () {097 myPlayer.realize ();098} 099 100 101 / ** 102 * Заменете метода за спиране на аплета по подразбиране, за да извикате myPlayer.stop () 103 * и myPlayer.deallocate (), за да освободим правилно ресурси 104 *, ако някой излезе от тази страница в браузъра си. 105 ** / 106 публично спиране на празнотата () {107 myPlayer.stop (); 108 myPlayer.deallocate (); 109} 110 111 / ** 112 * Тъй като трябва да знаем кога реализацията завършва, използваме 113 * controllerUpdate () за обработка на RealizeCompleteEvents. 114 * Когато получим RealizeCompleteEvent, оформяме 115 * и показваме видео компонента и контролите в нашия графичен интерфейс на аплет 116 *. 117 ** / 118 public void controllerUpdate (ControllerEvent event) {119 if (instance instanceof RealizeCompleteEvent) {120 //System.out.println("Received RCE ... "); 121 // Сега, когато имаме реализиран играч,можем да вземем 122 // VisualComponent и ControlPanelComponent и да ги опаковаме 123 // в нашия аплет. 124 myVisual = myPlayer.getVisualComponent (); 125 if (myVisual! = Null) {126 // За да се гарантира, че VisualComponent 127 // не е преоразмерен от BorderLayout, аз го влагам 128 // в visualPanel, използвайки FlowLayout. 129 visualPanel = нов панел (); 130 visualPanel.setLayout (нов FlowLayout ()); 131 visualPanel.add (myVisual); 132 добавяне (visualPanel, BorderLayout.CENTER); 133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}124 myVisual = myPlayer.getVisualComponent (); 125 if (myVisual! = Null) {126 // За да се гарантира, че VisualComponent 127 // не е преоразмерен от BorderLayout, аз го влагам 128 // в visualPanel, използвайки FlowLayout. 129 visualPanel = нов панел (); 130 visualPanel.setLayout (нов FlowLayout ()); 131 visualPanel.add (myVisual); 132 добавяне (visualPanel, BorderLayout.CENTER); 133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}124 myVisual = myPlayer.getVisualComponent (); 125 if (myVisual! = Null) {126 // За да се гарантира, че VisualComponent 127 // не е преоразмерен от BorderLayout, аз го влагам 128 // в visualPanel, използвайки FlowLayout. 129 visualPanel = нов панел (); 130 visualPanel.setLayout (нов FlowLayout ()); 131 visualPanel.add (myVisual); 132 добавяне (visualPanel, BorderLayout.CENTER); 133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}= null) {126 // За да се гарантира, че VisualComponent 127 // не е преоразмерен от BorderLayout, аз го влагам 128 // в visualPanel, използвайки FlowLayout. 129 visualPanel = нов панел (); 130 visualPanel.setLayout (нов FlowLayout ()); 131 visualPanel.add (myVisual); 132 добавяне (visualPanel, BorderLayout.CENTER); 133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}= null) {126 // За да се гарантира, че VisualComponent 127 // не е преоразмерен от BorderLayout, аз го влагам 128 // в visualPanel, използвайки FlowLayout. 129 visualPanel = нов панел (); 130 visualPanel.setLayout (нов FlowLayout ()); 131 visualPanel.add (myVisual); 132 добавяне (visualPanel, BorderLayout.CENTER); 133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}133 //System.out.println("Added VisualComponent ... "); 134} 135 myControls = myPlayer.getControlPanelComponent (); 136 if (myControls! = Null) {137 add (myControls, BorderLayout.SOUTH); 138 //System.out.println("Added controls ... "); 139} 140 // invalidate (); 141 валидиране (); 142} 143 // В противен случай просто консумираме събитието. 144} 145}

Включих прост примерен HTML документ, example.html (който можете да опитате в браузъра си сега, като щракнете тук), за да ви покажа как да вградите аплета в собствените си уеб страници. Просто сменете медийния файл в ASSETмаркера и тръгвайте!

За този пример използвах изтеглянето на JMF 1.1 за уеб сървъри (документирано на уеб сайта на JMF), за да разреша JMF11Appletавтоматично изтегляне jmf-server.jar, архив на код, съдържащ необходимите класове за изпълнение на JMF. Това позволява на аплета да се изпълнява във всеки браузър, съвместим с Java 1.1, без софтуер, който крайният потребител да инсталира. (Обърнете внимание, че версията на JMF за уеб сървъри включва и инструмент за персонализиране JMFCustomizer, който потенциално ще ви позволи да премахнете още по-ненужни класове от JMF JAR файла. Този инструмент в момента не работи под Java 2, тъй като използва остарял име на пакета за Swing.)

В конкретния пример, вграден в example.html , зареждаме WAV файл (welcome.wav), установяваме подходящите контролни компоненти, които да направим достъпни (без видео компонент, тъй като това е само звуков медиен файл), и възпроизвеждаме мултимедията файл. Имайте предвид, че WAV файлът (600 KB) и класовете JMF (570 KB) може да изискват няколко минути за изтегляне на вашето устройство в зависимост от скоростта на връзката ви.

След анализиране на примерната страница, браузърите, съвместими с Java 1.1, трябва автоматично да заредят аплета и да поддържат JMF класове от уеб сървъра JavaWorld . След като аплетът се зареди и стартира, можете да натиснете бутона Възпроизвеждане, за да започне възпроизвеждането на WAV звуковия файл. Опитайте да преместите възпроизвеждането с помощта на лентата за превъртане и да направите пауза и рестартиране на възпроизвеждането с помощта на бутона Пауза / Възпроизвеждане.

Внедряването на платформата JMF 1.1 Java използва изцяло Java джаджи за своите контроли, така че контролите имат един и същ външен вид от браузър до браузър и от платформа до платформа. Забележете как изглежда аплетът, работещ в JVM на Netscape Communicator на Solaris 7 и JVM на Microsoft в Internet Explorer на Win32.

Бутонът с етикет i предоставя информация за медийния файл, който се възпроизвежда в JMF аплета. Щракнете върху тази информационна връзка, за да получите подробности за WAV файла, работещ на тази уеб страница.