這幾天用了JMF,感受這個好坑,在win7,jdk1.7版本上支持都不太好,多是JMF是一個老的東西把,如今apache好像都放棄了,沒去了解。。java
搞了我3天的時間。主要仍是在環境搭建這邊花了好多時間,太坑了,最後還弄不到我想要的效果,網上資料也不是不少,不說了,如今把我在網上找的幾行代碼整理一下,方便往後查看apache
package com.rola.luming; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.Vector; import javax.media.CannotRealizeException; import javax.media.CaptureDeviceInfo; import javax.media.CaptureDeviceManager; import javax.media.DataSink; import javax.media.Format; import javax.media.Manager; import javax.media.MediaLocator; import javax.media.NoDataSourceException; import javax.media.NoPlayerException; import javax.media.Player; import javax.media.Processor; import javax.media.ProcessorModel; import javax.media.control.FormatControl; import javax.media.protocol.DataSource; import javax.media.protocol.FileTypeDescriptor; import javax.media.protocol.SourceCloneable; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; public class MainUI extends JFrame{ /** * */ private static final long serialVersionUID = 1L; private JButton startVideo; //開始錄像按鈕 private JButton stopVideo; //中止錄像按鈕 private JPanel videoPanel; //填充視頻的面板 private JPanel buttonPanel; //放置按鈕的面板 private DataSource source; //原始視頻數據 private Player play = null; //視頻播放器 private DataSource cloneableSource; //能夠克隆的視頻數據 private DataSource clonedDataSource; //克隆出來的視頻數據 private Processor processor; //視頻處理器 private DataSink dataSink; //保存錄制數據的數據池(datasink: 數據接收裝置; 數據接收器) private JFileChooser fileChooser = new JFileChooser(); //文件選擇框 public void init() { JFrame frame = new JFrame("視 頻 監 控 窗 口"); frame.setLayout(new BorderLayout()); String url = "vfw:Microsoft WDM Image Capture (Win32):0"; //攝像頭設備的驅動,在JMStudio可查看 CaptureDeviceInfo newCameraDevice = CaptureDeviceManager.getDevice(url); //獲取攝像頭設備 //獲取系統全部的視頻,音頻設備 //Vector<CaptureDeviceInfo> deviceList = CaptureDeviceManager.getDeviceList(null); //for(CaptureDeviceInfo info:deviceList) { //System.out.println(info.getName()); //輸出全部的設備驅動名稱 //} //System.out.println("end---------------"); MediaLocator ml = newCameraDevice.getLocator();//設備定位器 try { //source = Manager.createDataSource(ml); //在調用createCloneableDataSource(source)後source不能再調用了 //原本是要弄能夠錄製的,可是不知道爲何在弄數據流的時候總是出錯,多是視頻源那邊出錯了, //我在網上找了不少都沒找到合適的答案,但願有人能告訴我,不勝感激 cloneableSource = Manager.createCloneableDataSource(source); play = Manager.createRealizedPlayer(ml); //play = Manager.createRealizedPlayer(cloneableSource); } catch (NoPlayerException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CannotRealizeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } videoPanel = new JPanel(); play.start(); Component comp = null; if ((comp = play.getVisualComponent()) != null) videoPanel.add(comp); startVideo = new JButton("開始錄像");//該功能實現不了 stopVideo = new JButton("中止錄像"); //該功能實現不了 videoPanel.setSize(500, 500); buttonPanel = new JPanel(); buttonPanel.add(startVideo); buttonPanel.add(stopVideo); frame.add("South",buttonPanel); frame.add("Center",videoPanel); startVideo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub start(); } }); stopVideo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub stop(); } }); frame.setSize(500,600); frame.setVisible(true); } /** * 開始攝像按鈕方法 * 該功能在win7,jdk1.6環境下實現不了,不知道是什麼緣由了,但願實現的朋友能告訴我一下 * 主要是在獲取可克隆數據流時出錯了,調試的結果是clonedDataSource 未null,這個我就不知道了 * */ private void start() { clonedDataSource = ((SourceCloneable)cloneableSource).createClone(); FormatControl formatControl = (FormatControl) play.getControl("javax.media.control.FormatControl"); Format defaultFormat = formatControl.getFormat(); //第三個參數 FileTypeDescriptor outputFileType = new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME); ProcessorModel processorModel = new ProcessorModel(clonedDataSource, new Format[]{defaultFormat},outputFileType); try{ processor = Manager.createRealizedProcessor(processorModel); }catch (Exception e) { e.printStackTrace(); } String locatorString = this.getLocatorString();//表示存儲的位置 if (locatorString == null) { return ; } MediaLocator dest = new MediaLocator(locatorString); DataSource outputDataSource = processor.getDataOutput(); //本地文件傳輸 try { dataSink = Manager.createDataSink(outputDataSource, dest); dataSink.open(); dataSink.start(); }catch (Exception e) { e.printStackTrace(); } processor.start(); startVideo.setEnabled(false); stopVideo.setEnabled(true); } //中止按鈕方法 public void stop() { processor.close(); processor.deallocate(); dataSink.close(); processor = null; startVideo.setEnabled(true); stopVideo.setEnabled(false); } //得到文件路徑 public String getLocatorString() { if(JFileChooser.APPROVE_OPTION != fileChooser.showSaveDialog(this) ) return null; File file = fileChooser.getSelectedFile(); if(file == null) return null; System.out.println(file); String locatorString = file.getAbsolutePath(); //加文件後綴 if(!locatorString.endsWith(".QUICKTIME")) locatorString += ".QUICKTIME"; locatorString = "file://"+locatorString; System.out.println(locatorString); return locatorString; } public static void main(String[] args) { MainUI main = new MainUI(); //main.initCamera(); main.init(); } }
在開始攝像這裏會報錯:錯誤緣由:(本人調試的結果是clonedDataSource爲null,對於這個不瞭解)ide
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.sise.luming.MainUI.start(MainUI.java:126) at com.sise.luming.MainUI.access$0(MainUI.java:124) at com.sise.luming.MainUI$1.actionPerformed(MainUI.java:103) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.setPressed(Unknown Source) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)