这几天用了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)