JMF 从网络摄像头捕获视频时出现问题



我一直在尝试从我的网络摄像头捕获视频大约 2 个月了,我发现 JMF 可以做到这一点,我得到了很多代码,但没有任何效果。JMF工作室和JMF注册表工作正常,我可以知道设备和格式。下面的代码在返回视频和音频设备时给出了空指针异常,尽管 jmf 注册表检测到了这些设备。谁能帮我?我真的很感激。提前谢谢。

    package JMF;import java.awt.*;import java.awt.event.*;import java.util.Vector;import javax.media.*;import javax.media.format.*;import javax.media.protocol.DataSource;
    public class CaptureDeviceDialog extends Dialog implements ActionListener, ItemListener {
      boolean configurationChanged = false;Vector devices;Vector audioDevices;VectorvideoDevices;Vector audioFormats;Vector videoFormats;Choice audioDeviceCombo;Choice videoDeviceCombo;Choice audioFormatCombo;Choice videoFormatCombo;
      public CaptureDeviceDialog(Frame parent, String title, boolean mode) {
        super(parent, title, mode);
        init();
      }
      private void init() {
        setSize(450, 180);
        Panel p = new Panel();
        p.setLayout(null);
    Label l1 = new Label("Audio Device(s)");
    Label l2 = new Label("Video Device(s)");
    Label l3 = new Label("Audio Format(s)");
    Label l4 = new Label("Video Format(s)");
    audioDeviceCombo = new Choice();
    videoDeviceCombo = new Choice();
    audioFormatCombo = new Choice();
    videoFormatCombo = new Choice();
    Button OKbutton = new Button("OK");
    Button cancelButton = new Button("Cancel");

    p.add(l1);
    l1.setBounds(5, 5, 100, 20);
    p.add(audioDeviceCombo);
    audioDeviceCombo.setBounds(115, 5, 300, 20);
    p.add(l3);
    l3.setBounds(5, 30, 100,20);
    p.add(audioFormatCombo);
    audioFormatCombo.setBounds(115, 30, 300,20);
    p.add(l2);
    l2.setBounds(5, 55, 100, 20);
    p.add(videoDeviceCombo);
    videoDeviceCombo.setBounds(115, 55, 300, 20);
    p.add(l4);
    l4.setBounds(5, 80, 100, 20);
    p.add(videoFormatCombo);
    videoFormatCombo.setBounds(115, 80, 300, 20);
    p.add(OKbutton);
    OKbutton.setBounds(280, 115, 60, 25);
    p.add(cancelButton);
    cancelButton.setBounds(355, 115, 60, 25);
    add(p, "Center");
    audioDeviceCombo.addItemListener(this);
    videoDeviceCombo.addItemListener(this);
    OKbutton.addActionListener(this);
    cancelButton.addActionListener(this);
    //get all the capture devices
    devices = CaptureDeviceManager.getDeviceList ( null );
    CaptureDeviceInfo cdi;
    if (devices!=null && devices.size()>0) {
      int deviceCount = devices.size();
      audioDevices = new Vector();
      videoDevices = new Vector();
      Format[] formats;
      for ( int i = 0;  i < deviceCount;  i++ ) {
        cdi = (CaptureDeviceInfo) devices.elementAt ( i );
        formats = cdi.getFormats();
        for ( int j=0;  j<formats.length; j++ ) {
          if ( formats[j] instanceof AudioFormat ) {
            audioDevices.addElement(cdi);
            break;
          }
          else if (formats[j] instanceof VideoFormat ) {
            videoDevices.addElement(cdi);
            break;
          }
        }
      }
      //populate the choices for audio
      for (int i=0; i<audioDevices.size(); i++) {
        cdi  = (CaptureDeviceInfo) audioDevices.elementAt(i);
        audioDeviceCombo.addItem(cdi.getName());
      }
      //populate the choices for video
      for (int i=0; i<videoDevices.size(); i++) {
        cdi  = (CaptureDeviceInfo) videoDevices.elementAt(i);
        videoDeviceCombo.addItem(cdi.getName());
      }
      displayAudioFormats();
      displayVideoFormats();
    } // end if devices!=null && devices.size>0
    else {
      //no devices found or something bad happened.
    }
  }
  void displayAudioFormats() {
    //get audio formats of the selected audio device and repopulate the audio format combo
    CaptureDeviceInfo cdi;
    audioFormatCombo.removeAll();
    int i = audioDeviceCombo.getSelectedIndex();
    //i = -1 --> no selected index
    if (i!=-1) {
      cdi = (CaptureDeviceInfo) audioDevices.elementAt(i);
      if (cdi!=null) {
        Format[] formats = cdi.getFormats();
        audioFormats = new Vector();
        for (int j=0; j<formats.length; j++) {
          audioFormatCombo.add(formats[j].toString());
          audioFormats.addElement(formats[j]);
        }
      }
    }
  }
  void displayVideoFormats() {
    //get audio formats of the selected audio device and repopulate the audio format combo
    CaptureDeviceInfo cdi;
    videoFormatCombo.removeAll();
    int i = videoDeviceCombo.getSelectedIndex();
    //i = -1 --> no selected index
    if (i!=-1) {
      cdi = (CaptureDeviceInfo) videoDevices.elementAt(i);
      if (cdi!=null) {
        Format[] formats = cdi.getFormats();
        videoFormats = new Vector();
        for (int j=0; j<formats.length; j++) {
          videoFormatCombo.add(formats[j].toString());
          videoFormats.addElement(formats[j]);
        }
      }
    }
  }

  public CaptureDeviceInfo getVideoDevice() {
    CaptureDeviceInfo cdi = null;
    if (videoDeviceCombo!=null) {
      int i = videoDeviceCombo.getSelectedIndex();
      cdi = (CaptureDeviceInfo) videoDevices.elementAt(i);
      System.out.println("videoDeviceCombo!=null");
      if(videoDevices.elementAt(i)!=null)
        System.out.println("element at videoDeviceCombo!=null");
    }
    return cdi;
  }
  public CaptureDeviceInfo getAudioDevice() {
    CaptureDeviceInfo cdi = null;
    //System.out.println("audioDeviceCombo!=null");
    if (audioDeviceCombo!=null) {
      int i = audioDeviceCombo.getSelectedIndex();
      cdi = (CaptureDeviceInfo) audioDevices.elementAt(i);
    if(audioDevices.elementAt(i)!=null)
      System.out.println("eleme");
    }
    return cdi;
  }

  public Format getAudioFormat() {
    Format format = null;
    if (audioFormatCombo!=null) {
      int i = audioFormatCombo.getSelectedIndex();
      format = (Format) audioFormats.elementAt(i);
    }
    return format;
  }
  public Format getVideoFormat() {
    Format format = null;
    if (videoFormatCombo!=null) {
      int i = videoFormatCombo.getSelectedIndex();
      format = (Format) videoFormats.elementAt(i);
    }
    return format;
  }
  public boolean hasConfigurationChanged() {
    return configurationChanged;
  }
  public void actionPerformed(ActionEvent ae) {
    String command = ae.getActionCommand().toString();
    if (command.equals("OK")) {
      configurationChanged = true;
    }
    dispose();
  }public void itemStateChanged(ItemEvent ie) {
    System.out.println(ie.getSource().toString());
    if (ie.getSource().equals(audioDeviceCombo))
      displayAudioFormats();
    else
      displayVideoFormats();
  }
}
`
package JMF;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.media.*;
import javax.media.format.*;
import javax.media.protocol.DataSource;

public class JMF extends Frame implements ActionListener, ItemListener, WindowListener,
  ControllerListener {
  CaptureDeviceInfo audioCDI = null;
  CaptureDeviceInfo videoCDI = null;
  String audioDeviceName = null;
  String videoDeviceName = null;
  Player videoPlayer;
  Player audioPlayer;
  Format videoFormat;
  Format audioFormat;
  Player dualPlayer;  //for merging audio and video data sources
  DataSource dataSource; //of the capture devices
  public JMF(String title) {
    super(title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
        dispose();
      }
    });
    MenuBar mb = new MenuBar();
    setMenuBar(mb);
    Menu menuConfigure = new Menu("Configure");
    mb.add(menuConfigure);
    Menu menuAction = new Menu("Action");
    mb.add(menuAction);
    /* menu items for Configure */
    MenuItem menuItemSetting = new MenuItem("Capture Device");
    menuItemSetting.addActionListener(this);
    menuConfigure.add(menuItemSetting);
    /* menu items for Action */
    MenuItem a1 = new MenuItem("Capture");
    a1.addActionListener(this);
    menuAction.add(a1);
    MenuItem a2 = new MenuItem("Play");
    a2.addActionListener(this);
    menuAction.add(a2);
    MenuItem a3 = new MenuItem("Stop");
    a3.addActionListener(this);
    menuAction.add(a3);
  }
  public void actionPerformed(ActionEvent ae) {
    String command = ae.getActionCommand().toString();
    if (command.equals("Capture Device")) {
      registerDevices();
    }
    else if (command.equals("Play")) {
      play();
    }
    else if (command.equals("Capture")) {
      capture();
    }
    else if (command.equals("Stop")) {
      stop();
    }
  }
  void registerDevices() {
    CaptureDeviceDialog cdDialog = new 
      CaptureDeviceDialog(this, "Capture Device", true);
    cdDialog.show();
    if (!cdDialog.hasConfigurationChanged())
      return;
    //configuration has changed, update variables.
    audioCDI = cdDialog.getAudioDevice();
    if (audioCDI!=null) {
      audioDeviceName = audioCDI.getName();
      System.out.println("Audio Device Name: " + audioDeviceName);
    }
    videoCDI = cdDialog.getVideoDevice();
    if (videoCDI!=null) {
      videoDeviceName = videoCDI.getName();
      System.out.println("Video Device Name: " + videoDeviceName);
    }
    //Get formats selected, to be used for creating DataSource
    videoFormat = cdDialog.getVideoFormat();
    audioFormat = cdDialog.getAudioFormat();
  }
  void capture() {
    if (audioCDI==null && videoCDI==null)
      registerDevices();
    try {
      if (!(audioCDI==null && videoCDI==null)) {
     /* This works, but now we end up having 2 players
        videoPlayer = Manager.createPlayer(videoCDI.getLocator());
        audioPlayer = Manager.createPlayer(audioCDI.getLocator());
        videoPlayer.addControllerListener(this);
        videoPlayer.start();
        audioPlayer.start();
     */
        DataSource[] dataSources = new DataSource[2];
        System.out.println("Creating data sources.");
        dataSources[0] = Manager.createDataSource(new MediaLocator("dsound://"));
        dataSources[1] = Manager.createDataSource(new MediaLocator("vfw://0"));
        DataSource ds = Manager.createMergingDataSource(dataSources);
        dualPlayer = Manager.createPlayer(ds);
        dualPlayer.addControllerListener(this);
        dualPlayer.start();
      }
      else
        System.out.println("CDI not found.");
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
  }
  void play() {
    try {
      FileDialog fd = new FileDialog(this, "Select File", FileDialog.LOAD);
      fd.show();
      String filename = fd.getDirectory() + fd.getFile();
      dualPlayer = Manager.createPlayer(new MediaLocator("file:///" + filename));
      System.out.println("Adding controller listener");
      dualPlayer.addControllerListener(this);
      System.out.println("Starting player ...");
      dualPlayer.start();
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
  }
  void stop() {
    if (dualPlayer!=null) {
      dualPlayer.stop();
      dualPlayer.deallocate();
    }
  }
public synchronized void controllerUpdate(ControllerEvent event) {
    System.out.println(event.toString());
    if (event instanceof RealizeCompleteEvent) {
      Component comp;
      System.out.println("Adding visual component");
      if ((comp = dualPlayer.getVisualComponent()) != null)
        add ("Center", comp);
      System.out.println("Adding control panel");
      if ((comp = dualPlayer.getControlPanelComponent()) != null)
        add("South", comp);
      validate();
    }
  }
  public void itemStateChanged(ItemEvent ie) {}
  public void windowActivated(WindowEvent we) {}
  public void windowClosed(WindowEvent we) {}
  public void windowClosing(WindowEvent we) {}
  public void windowDeactivated(WindowEvent we) {}
  public void windowDeiconified(WindowEvent we) {}
  public void windowIconified(WindowEvent we) {}
  public void windowOpened(WindowEvent we) {}

  public static void main(String[] args) {
    JMF myFrame = new JMF("Java Media Framework Project");
    myFrame.show();
    myFrame.setSize(300, 300);
  }
}

这是因为您的代码未检测到网络摄像头

必须将 JMF.Properties 文件复制到与可执行 JAR 相同的目录

您将在 JMF 安装的 lib 文件夹中找到 jmf.properties 文件。

对我来说,它是C:\Program Files\JMF2.1.1e\lib\jmf.properties

我想我也有类似的问题。JMStudio找到了我的网络摄像头,但我的java代码没有。对我来说,问题在于设备格式。CaptureDeviceManager.getDeviceList( VideoFormat )需要VideoFormat作为参数。我知道的两个是rgbyuv

尝试调用以下电话之一:

  • CaptureDeviceManager.getDeviceList(new VideoFormat("rgb"))
  • CaptureDeviceManager.getDeviceList(new VideoFormat("yuv")) .

您的网络摄像头应显示在一个列表或另一个列表中。

如果您使用的是 64 位处理器,请卸载 jmf。重新安装 jmf,但这次是驱动器C:而不是程序文件:例如。 C:/jmf 2.1.1e .

如果您对视频格式有疑问,我认为您应该提供这样的格式:

CaptureDeviceManager.getDeviceList(new YUVFormat());

它对我有用。

相关内容

  • 没有找到相关文章

最新更新