JMF實現從攝像頭和麥克截取視頻和音頻流進行播放
利用JMF捕獲媒體數據的過程:
1.定位所需要用的捕獲設備,可以通過查詢CaptureDeviceManager來定位。
2.獲取這個捕獲設備的信息CaptureDeviceInfo對象。
3.從CaptureDeviceInfo對象中獲取捕獲設備的位置Medialocator。
4.利用MediaLocator創建DataSource。5.使用DataSource創建Player或是Processor。6.然后啟動Player就開始了媒體的捕獲。
在從攝像頭和麥克進行截取視頻流和音頻流時,前提是設備已經注冊。可以利用解壓完成的JMF目錄中的jmfregistry.exe進行注冊。同樣在通過設備進行捕獲媒體數據是要通過媒體目錄的位置進行構建MediaLocator對象,從而繼續實現后續的流程。
以下是演示代碼,能夠實現從本地的攝像頭和麥克進行捕獲視頻流和音頻流,并且流暢播放。
package com.lcq.jmf; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Panel; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.media.ControllerEvent; import javax.media.ControllerListener; import javax.media.DataSink; import javax.media.EndOfMediaEvent; import javax.media.Manager; import javax.media.MediaLocator; import javax.media.NoDataSinkException; import javax.media.NoPlayerException; import javax.media.NoProcessorException; import javax.media.NotConfiguredError; import javax.media.NotRealizedError; import javax.media.Player; import javax.media.PrefetchCompleteEvent; import javax.media.Processor; import javax.media.RealizeCompleteEvent; import javax.media.Time; import javax.media.control.StreamWriterControl; import javax.media.protocol.DataSource; import javax.media.protocol.FileTypeDescriptor; import jmapps.util.StateHelper; @SuppressWarnings( { "unused" }) public class MyVideoPlayer2 implements ControllerListener { public static void main(String[] args) throws Exception { MyVideoPlayer2 sp = new MyVideoPlayer2(); sp.play(); // sp.saveVideo(); } private Frame f; // private Player videoplayer; // private Player audioplayer; private Player dualPlayer; private Panel panel; private Component visual; private Component control = null; private MediaLocator mediaLocator; private MediaLocator audioLocator; private DataSource ds = null; private StateHelper sh = null; public void play() { f = new Frame("MyPlayer"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { if (dualPlayer != null) { dualPlayer.close(); } System.exit(0); } }); f.setSize(500, 400); f.setVisible(true); String filename = null; URL url = null; try { // 準備一個要播放的視頻文件的URL // url = new URL("file:/d:/視頻演示/1.mpg"); mediaLocator = new MediaLocator("vfw://0");// 此類描述媒體目錄的地址???? audioLocator = new MediaLocator("javasound://44100"); // saveVideo(); // FileDialog fd = new FileDialog(f, "Select File", // FileDialog.LOAD); // fd.show(); // filename = fd.getDirectory() + fd.getFile(); } catch (Exception e) { System.out.println(e.toString()); } try { // 通過調用Manager的createPlayer方法來創建一個Player的對象 // 這個對象是媒體播放的核心控制對象 // videoplayer = Manager.createPlayer(mediaLocator); // audioplayer = Manager.createPlayer(audioLocator); DataSource[] dataSources = new DataSource[2]; dataSources[0] = Manager.createDataSource(mediaLocator); dataSources[1] = Manager.createDataSource(audioLocator); ds = Manager.createMergingDataSource(dataSources); ds = Manager.createCloneableDataSource(ds); dualPlayer = Manager.createPlayer(ds); } catch (Exception e1) { e1.printStackTrace(); } // 對player對象注冊監聽器,能噶偶在相關事件發生的時候執行相關的動作 // videoplayer.addControllerListener(this); // 讓player對象進行相關的資源分配 // videoplayer.realize(); // audioplayer.realize(); dualPlayer.realize(); dualPlayer.addControllerListener(this); // try { // saveVideo(ds); // } catch (Exception e) { // e.printStackTrace(); // } } private void saveVideo() throws Exception { System.out.println("ppfmjfdsdf"); Processor processor = null; DataSink dataSink = null; try {// player用cloneabledatasource數據源,processor用cloneddatasource的數據源 processor = Manager.createProcessor(ds); sh = new StateHelper(processor); } catch (IOException ez5) { ez5.printStackTrace(); System.exit(-1); } catch (NoProcessorException ez6) { ez6.printStackTrace(); System.exit(-1); } // Configure the processor,讓processor進入configured狀態 if (!sh.configure(10000)) { System.out.println("configure wrong!"); System.exit(-1); } System.out.println("222"); // 設置視頻輸出格式 processor.setContentDescriptor(new FileTypeDescriptor( FileTypeDescriptor.QUICKTIME)); // realize the processor,讓processor進入realized狀態 if (!sh.realize(10000)) { System.out.println("realize wrong!"); System.exit(-1); } // get the output of the processor,并且啟動processor DataSource outsource = processor.getDataOutput(); //File videofile = new File("test.mpeg"); // 創建新文件 // try { // videofile.createNewFile(); // } catch (IOException e2) { // // TODO Auto-generated catch block // e2.printStackTrace(); // } MediaLocator dest = new MediaLocator("file://e:/media.mov"); processor.start(); /* * try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO * Auto-generated catch block e.printStackTrace(); } */ try { dataSink = Manager.createDataSink(outsource, dest); dataSink.open(); } catch (NoDataSinkException ez1) { ez1.printStackTrace(); System.exit(-1); } catch (IOException ez2) { ez2.printStackTrace(); System.exit(-1); } catch (SecurityException ez3) { ez3.printStackTrace(); System.exit(-1); } try { dataSink.start(); } catch (IOException ez4) { ez4.printStackTrace(); System.exit(-1); } if (dataSink != null) { System.out.println("xxx!"); } System.out.println("end"); } private int videoWidth = 0; private int videoHeight = 0; private int controlHeight = 30; private int insetWidth = 10; private int insetHeight = 30; // 監聽player的相關事件 public void controllerUpdate(ControllerEvent ce) { if (ce instanceof RealizeCompleteEvent) { // player實例化完成后進行player播放前預處理 dualPlayer.prefetch(); } else if (ce instanceof PrefetchCompleteEvent) { if (visual != null) return; // 取得player中的播放視頻的組件,并得到視頻窗口的大小 // 然后把視頻窗口的組件添加到Frame窗口中, if ((visual = dualPlayer.getVisualComponent()) != null) { Dimension size = visual.getPreferredSize(); videoWidth = size.width; videoHeight = size.height; f.add(visual); } else { videoWidth = 320; } // 取得player中的視頻播放控制條組件,并把該組件添加到Frame窗口中 if ((control = dualPlayer.getControlPanelComponent()) != null) { controlHeight = control.getPreferredSize().height; f.add(control, BorderLayout.SOUTH); } // 設定Frame窗口的大小,使得滿足視頻文件的默認大小 f.setSize(videoWidth + insetWidth, videoHeight + controlHeight + insetHeight); f.validate(); // 啟動視頻播放組件開始播放 dualPlayer.start(); } else if (ce instanceof EndOfMediaEvent) { // 當播放視頻完成后,把時間進度條恢復到開始,并再次重新開始播放 dualPlayer.setMediaTime(new Time(0)); // videoplayer.start(); // audioplayer.start(); dualPlayer.start(); } } }以上的代碼中也編寫了保存截取的媒體數據的方法,但是還有不少問題,沒能實現。
轉自:http://blog.csdn.net/liuchangqing123/article/details/7331356
本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!