这几天用了JMF,感觉这个好坑,在win7,jdk1.7版本上支持都不太好,可能是JMF是一个老的东西把,现在apache好像都放弃了,没去了解。。
搞了我3天的时间。主要还是在环境搭建这边花了好多时间,太坑了,最后还弄不到我想要的效果,网上资料也不是很多,不说了,现在把我在网上找的几行代码整理一下,方便日后查看
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,对于这个不了解)
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)