最近项目要求能对视频和语音进行同步合成,以及对视频进行画面与语音的分离功能,由于没有接触过这类东西,所以想从最基础做起,于是在网上找到sun公司开源的jmf架构,看到网上也有不少小例子,就开始对安装jmf并配置了开发环境,将小例子粘到自己的新建工程下,结果发现不好用,没办法自己也顺手写了一个都发生同样的问题,希望有经验的朋友能够帮助解决一下。
我现在干脆就用网上的一个例子来说明问题,实现的功能是,利用点击拍照按钮能,启动摄像头并将捕捉摄像头的画面将生成图片保存到物理硬盘中,代码如下:
package com.creatplay;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.media.Buffer;
import javax.media.CannotRealizeException;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class FirstCapture extends JPanel implements ActionListener{
private CaptureDeviceInfo captureDeviceInfo=null;
private MediaLocator mediaLocator=null;
private static Player player=null;
private ImagePanel imagePanel=null;
private JButton capture;
private Buffer buffer=null;
private VideoFormat videoFormat=null;
private BufferToImage bufferToImage=null;
private Image image=null;
public FirstCapture()
{
setLayout(new BorderLayout());
setSize(320,550);
String str="vfw:Microsoft WDM Image Capture (Win32):0";
captureDeviceInfo=CaptureDeviceManager.getDevice(str);
// MediaLocator mediaLocator=captureDeviceInfo.getLocator();
mediaLocator=new MediaLocator("vfw://0");
imagePanel=new ImagePanel();
capture=new JButton("拍照");
capture.addActionListener(this);
try {
player=Manager.createRealizedPlayer(mediaLocator);
player.start();
Component comp;
Component comp1;
if((comp=player.getVisualComponent())!=null)
add(comp,BorderLayout.NORTH);
// if((comp1=player.getControlPanelComponent())!=null)
// add(comp1,BorderLayout.CENTER);
} 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();
}
add(imagePanel,BorderLayout.SOUTH);
add(capture,BorderLayout.CENTER);
}
@Override
public void print(Graphics g) {
// TODO Auto-generated method stub
super.print(g);
g.setColor(new Color(255,0,0));
g.drawLine(0, 0, 100, 100);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame f = new JFrame("FirstCapture");
FirstCapture cf = new FirstCapture();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
player.close();
System.exit(0);}});
f.add("Center",cf);
f.pack();
f.setSize(new Dimension(320,550));
f.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
FrameGrabbingControl fgc=(FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
buffer=fgc.grabFrame();
bufferToImage=new BufferToImage((VideoFormat)buffer.getFormat());
image=bufferToImage.createImage(buffer);
imagePanel.setImage(image);
saveImage(image,"D:/test.jpg");
}
public static void saveImage(Image image,String path)
{
BufferedImage bi=new BufferedImage(image.getWidth(null),image.getHeight(null),BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.drawImage(image, null, null);
FileOutputStream fos=null;
try {
fos=new FileOutputStream(path);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JPEGImageEncoder je=JPEGCodec.createJPEGEncoder(fos);
JPEGEncodeParam jp=je.getDefaultJPEGEncodeParam(bi);
jp.setQuality(0.5f, false);
je.setJPEGEncodeParam(jp);
try {
je.encode(bi);
fos.close();
} catch (ImageFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ImagePanel extends Panel
{
public Image myimg = null;
public ImagePanel()
{
setLayout(null);
setSize(320,240);
}
public void setImage(Image img)
{
this.myimg = img;
repaint();
}
public void paint(Graphics g)
{
if (myimg != null)
{
g.drawImage(myimg, 0, 0, this);
}
}
}
}
运行以后老出现这个错误:
javax.media.NoPlayerException: Cannot find a Player for :vfw://0
at javax.media.Manager.createPlayerForContent(Manager.java:1412)
at javax.media.Manager.createPlayer(Manager.java:417)
at javax.media.Manager.createRealizedPlayer(Manager.java:553)
at com.creatplay.FirstCapture.<init>(FirstCapture.java:67)
at com.creatplay.FirstCapture.main(FirstCapture.java:100)第一次发帖后没有人关注这个问题,很可能还是分数少我真的是我所有的分数,但是我还是希望哪位朋友能帮助解决一下谢谢了。
我现在干脆就用网上的一个例子来说明问题,实现的功能是,利用点击拍照按钮能,启动摄像头并将捕捉摄像头的画面将生成图片保存到物理硬盘中,代码如下:
package com.creatplay;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.media.Buffer;
import javax.media.CannotRealizeException;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class FirstCapture extends JPanel implements ActionListener{
private CaptureDeviceInfo captureDeviceInfo=null;
private MediaLocator mediaLocator=null;
private static Player player=null;
private ImagePanel imagePanel=null;
private JButton capture;
private Buffer buffer=null;
private VideoFormat videoFormat=null;
private BufferToImage bufferToImage=null;
private Image image=null;
public FirstCapture()
{
setLayout(new BorderLayout());
setSize(320,550);
String str="vfw:Microsoft WDM Image Capture (Win32):0";
captureDeviceInfo=CaptureDeviceManager.getDevice(str);
// MediaLocator mediaLocator=captureDeviceInfo.getLocator();
mediaLocator=new MediaLocator("vfw://0");
imagePanel=new ImagePanel();
capture=new JButton("拍照");
capture.addActionListener(this);
try {
player=Manager.createRealizedPlayer(mediaLocator);
player.start();
Component comp;
Component comp1;
if((comp=player.getVisualComponent())!=null)
add(comp,BorderLayout.NORTH);
// if((comp1=player.getControlPanelComponent())!=null)
// add(comp1,BorderLayout.CENTER);
} 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();
}
add(imagePanel,BorderLayout.SOUTH);
add(capture,BorderLayout.CENTER);
}
@Override
public void print(Graphics g) {
// TODO Auto-generated method stub
super.print(g);
g.setColor(new Color(255,0,0));
g.drawLine(0, 0, 100, 100);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame f = new JFrame("FirstCapture");
FirstCapture cf = new FirstCapture();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
player.close();
System.exit(0);}});
f.add("Center",cf);
f.pack();
f.setSize(new Dimension(320,550));
f.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
FrameGrabbingControl fgc=(FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
buffer=fgc.grabFrame();
bufferToImage=new BufferToImage((VideoFormat)buffer.getFormat());
image=bufferToImage.createImage(buffer);
imagePanel.setImage(image);
saveImage(image,"D:/test.jpg");
}
public static void saveImage(Image image,String path)
{
BufferedImage bi=new BufferedImage(image.getWidth(null),image.getHeight(null),BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.drawImage(image, null, null);
FileOutputStream fos=null;
try {
fos=new FileOutputStream(path);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JPEGImageEncoder je=JPEGCodec.createJPEGEncoder(fos);
JPEGEncodeParam jp=je.getDefaultJPEGEncodeParam(bi);
jp.setQuality(0.5f, false);
je.setJPEGEncodeParam(jp);
try {
je.encode(bi);
fos.close();
} catch (ImageFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ImagePanel extends Panel
{
public Image myimg = null;
public ImagePanel()
{
setLayout(null);
setSize(320,240);
}
public void setImage(Image img)
{
this.myimg = img;
repaint();
}
public void paint(Graphics g)
{
if (myimg != null)
{
g.drawImage(myimg, 0, 0, this);
}
}
}
}
运行以后老出现这个错误:
javax.media.NoPlayerException: Cannot find a Player for :vfw://0
at javax.media.Manager.createPlayerForContent(Manager.java:1412)
at javax.media.Manager.createPlayer(Manager.java:417)
at javax.media.Manager.createRealizedPlayer(Manager.java:553)
at com.creatplay.FirstCapture.<init>(FirstCapture.java:67)
at com.creatplay.FirstCapture.main(FirstCapture.java:100)第一次发帖后没有人关注这个问题,很可能还是分数少我真的是我所有的分数,但是我还是希望哪位朋友能帮助解决一下谢谢了。
而且后面的资源连接怎么试//0 啊?至少也应该是一个规范的资源名称吧
Name = vfw:Microsoft WDM Image Capture (Win32):0Locator = vfw://0Output Formats---->0. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=640,height=480] MaxDataLength = 614400 DataType = class [B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY = 0 OffsetU = 1 OffsetV = 31. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=160,height=120] MaxDataLength = 38400 DataType = class [B yuvType = 32 StrideY = 320 StrideUV = 320 OffsetY = 0 OffsetU = 1 OffsetV = 32. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=176,height=144] MaxDataLength = 50688 DataType = class [B yuvType = 32 StrideY = 352 StrideUV = 352 OffsetY = 0 OffsetU = 1 OffsetV = 33. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=320,height=240] MaxDataLength = 153600 DataType = class [B yuvType = 32 StrideY = 640 StrideUV = 640 OffsetY = 0 OffsetU = 1 OffsetV = 34. javax.media.format.YUVFormat
YUV Video Format: Size = java.awt.Dimension[width=352,height=288] MaxDataLength = 202752 DataType = class [B yuvType = 32 StrideY = 704 StrideUV = 704 OffsetY = 0 OffsetU = 1 OffsetV = 3
所以我就在程序中应用了这个驱动:
vfw:Microsoft WDM Image Capture (Win32):0
根据在网上查的很多例子都是以下方式输入摄像头路径
MediaLocator mediaLocator=new MediaLocator("vfw://0");
当然也有直接获取路径的方式:
MediaLocator mediaLocator=captureDeviceInfo.getLocator();此刻运行程序此行显示的是空指针异常。
所以我不知道这里应该怎么写,还望您能指导一下。
获取摄像头驱动信息和显示路径。
zwen1573谢谢帮忙顶呀!!!
之前remove掉的是sun的jre。 这问题折腾了我两天,希望对你有用。
.getDeviceList(new VideoFormat(null));
Vector<CaptureDeviceInfo> audio = CaptureDeviceManager
.getDeviceList(new AudioFormat(AudioFormat.LINEAR, 44100, 16, 2));
使用的上面试一试把,在xp系统中试过了,可以的
在JMFRegister里面注册摄像头,就OK了