JMF实现视频捕获与录制

Posted on 2007-11-29 09:56 lauber 阅读(2864) 评论(2)  编辑  收藏

//CamDataSource.java

package ccnu.meng.jxtaApp.localTest;

 

   import java.io.*;
   import java.util.*;
   import java.awt.Component;
   import javax.swing.JOptionPane;
   import javax.media.*;
   import javax.media.protocol.*;
import javax.media.format.VideoFormat;


   public class CamDataSource {
      
       private Component parent;
      
       private DataSource mainCamSource;
       private MediaLocator ml;
       private Processor processor;
       private boolean processing;
      
       public CamDataSource(Component parent) {
           this.parent = parent;
           setProcessing(false);
       }
      
       public void setMainSource(){
           setProcessing(false);
           VideoFormat vidformat = new VideoFormat(VideoFormat.RGB);
           Vector devices = CaptureDeviceManager.getDeviceList(vidformat);
           CaptureDeviceInfo di = null;
          
           if (devices.size() > 0)
           di = (CaptureDeviceInfo) devices.elementAt(0);
           else {
               JOptionPane.showMessageDialog(parent,
                  "Your camera is not connected", "No webcam found", JOptionPane.WARNING_MESSAGE);
               return;
           }
         
           try {
               ml = di.getLocator();
               setMainCamSource(Manager.createDataSource(ml));
           } catch (Exception e) {
               JOptionPane.showMessageDialog(parent,
                  "Exception locating media: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
       }
      
       public void makeDataSourceCloneable(){
           // turn our data source to a cloneable data source
           setMainCamSource(Manager.createCloneableDataSource(getMainCamSource()));
          
       }
      
       public void startProcessing(){
          
           try{
               processor = Manager.createProcessor(getMainCamSource());
           }catch (IOException e) {
               JOptionPane.showMessageDialog(parent,
                  "IO Exception creating processor: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }catch (NoProcessorException e) {
               JOptionPane.showMessageDialog(parent,
                  "Exception creating processor: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
          
           CamStateHelper playhelper = new CamStateHelper(processor);
           if(!playhelper.configure(10000)){
               JOptionPane.showMessageDialog(parent,
                  "cannot configure processor", "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
           processor.setContentDescriptor(null);
           if(!playhelper.realize(10000)){
               JOptionPane.showMessageDialog(parent,
                  "cannot realize processor", "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
          // In order for or your clones to start, you must start the original source
           processor.start();
           setProcessing(true);
       }
      
   
       public DataSource cloneCamSource(){
           if(!getProcessing()) setMainSource();
           return ((SourceCloneable)getMainCamSource()).createClone();
       }
      
       public DataSource getMainCamSource(){
           return mainCamSource;
       }

       public void setMainCamSource(DataSource mainCamSource){
           this.mainCamSource = mainCamSource;
       }
      
       public void setMl(MediaLocator ml){
           this.ml = ml;
       }
       
       public MediaLocator getMl(){
           return ml;
       }
      
       public boolean getProcessing(){
           return processing;
       }
      
       public void setProcessing(boolean processing){
           this.processing = processing;
          
       }
      
       public void setParent(Component parent){
           this.parent = parent;
       }
      
       public Component getParent(){
           return parent;
       }

}

/**********************************************************************************************/

 

//CamStateHelper.java

package ccnu.meng.jxtaApp.localTest;

 

import javax.media.*;

 

public class CamStateHelper implements javax.media.ControllerListener {
      
       Player player = null;
       boolean configured = false;
       boolean realized = false;
       boolean prefetched = false;
       boolean eom = false;
       boolean failed = false;
       boolean closed = false;
      
       public CamStateHelper(Player p) {
           player = p;
           p.addControllerListener(this);
       }
      
       public boolean configure(int timeOutMillis) {
          
           long startTime = System.currentTimeMillis();
           synchronized (this) {
               if (player instanceof Processor)
                   ((Processor)player).configure();
               else
                   return false;
               while (!configured && !failed) {
                   try {
                       wait(timeOutMillis);
                   } catch (InterruptedException ie) {
                   }
                   if (System.currentTimeMillis() - startTime > timeOutMillis)
                       break;
               }
           }
           return configured;
       }
      
       public boolean realize(int timeOutMillis) {
           long startTime = System.currentTimeMillis();
           synchronized (this) {
               player.realize();
               while (!realized && !failed) {
                   try {
                       wait(timeOutMillis);
                   }catch (InterruptedException ie) {
                   }
                   if (System.currentTimeMillis() - startTime > timeOutMillis)
                       break;
               }
           }
           return realized;
       }
      
       public boolean prefetch(int timeOutMillis) {
           long startTime = System.currentTimeMillis();
           synchronized (this) {
               player.prefetch();
               while (!prefetched && !failed) {
                   try {
                       wait(timeOutMillis);
                   }catch (InterruptedException ie) {
                   }
                   if (System.currentTimeMillis() - startTime > timeOutMillis)
                       break;
               }
           }
           return prefetched && !failed;
       }
       public boolean playToEndOfMedia(int timeOutMillis) {
           long startTime = System.currentTimeMillis();
           eom = false;
           synchronized (this) {
               player.start();
               while (!eom && !failed) {
                   try {
                       wait(timeOutMillis);
                   }catch (InterruptedException ie) {
                   }
                   if (System.currentTimeMillis() - startTime > timeOutMillis)
                       break;
               }
           }
           return eom && !failed;
       }
      
       public void close() {
           synchronized (this) {
               player.close();
               while (!closed) {
                   try {
                       wait(100);
                   } catch (InterruptedException ie) {
                   }
               }
           }
           player.removeControllerListener(this);
       }
      
       public synchronized void controllerUpdate(ControllerEvent ce) {
           if (ce instanceof RealizeCompleteEvent) {
               realized = true;
           }else if (ce instanceof ConfigureCompleteEvent) {
               configured = true;
           } else if (ce instanceof PrefetchCompleteEvent) {
               prefetched = true;
           } else if (ce instanceof EndOfMediaEvent) {
               eom = true;
           } else if (ce instanceof ControllerErrorEvent) {
               failed = true;
           } else if (ce instanceof ControllerClosedEvent) {
               closed = true;
           } else {
               return;
           }
           notifyAll();
       }
   }

/******************************************************************************************/

//LocalVideoTest.java

package ccnu.meng.jxtaApp.localTest;


public class LocalVideoTest {
 
  public LocalVideoTest() {
        
         CamDataSource dataSource = new CamDataSource(null);
         dataSource.setMainSource();
         dataSource.makeDataSourceCloneable();
         dataSource.startProcessing();
        
         MainFrame frame = new MainFrame(dataSource);
         frame.setSize(400, 400);
         frame.setLocationRelativeTo(null);
         frame.setVisible(true);

         }
 
  public static void main(String[] args) {
        
   LocalVideoTest Lvt = new LocalVideoTest();
        
     }
}

 

/*********************************************************************************************/

//MainFrame.java

package ccnu.meng.jxtaApp.localTest;

   import java.io.*;
   import java.net.URL;
   import java.net.MalformedURLException;
   import java.awt.*;
   import javax.swing.JFileChooser;
   import javax.media.*;
   import javax.media.control.*;
   import javax.media.protocol.*;
   import javax.media.format.VideoFormat;
   import javax.swing.JPanel;
   import javax.swing.JLabel;
   import javax.swing.JToolBar;
   import javax.swing.JButton;
   import javax.swing.JFrame;
   import javax.swing.JOptionPane;
   import javax.swing.WindowConstants;
   import java.awt.BorderLayout;
   import java.awt.event.*;

   public class MainFrame extends JFrame {
    private JPanel centerPanel;
       private JLabel fileLabel;
       private JToolBar mainToolBar;
       private JLabel messageLabel;
       private JPanel northPanel;
       private JButton recordButton;
       private JPanel southPanel;
      
       private CamDataSource dataSource;
       private DataSource camSource;
       private DataSource recordCamSource;
       private DataSink dataSink;
       private Processor processor;
       private Processor recordProcessor;
       private CamStateHelper playhelper;
      
       private JFileChooser movieChooser;
      
       public MainFrame(CamDataSource dataSource) {
       
           this.dataSource = dataSource;
           this.dataSource.setParent(this);
           camSource = dataSource.cloneCamSource();
          
           initComponents();
           try{
               processor = Manager.createProcessor(camSource);
           }catch (IOException e) {
               JOptionPane.showMessageDialog(this,
                 "Exception creating processor: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }catch (NoProcessorException e) {
               JOptionPane.showMessageDialog(this,
                  "Exception creating processor: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
          
           playhelper = new CamStateHelper(processor);
           if(!playhelper.configure(10000)){
               JOptionPane.showMessageDialog(this,
                  "cannot configure processor", "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
           checkIncoding(processor.getTrackControls());
           processor.setContentDescriptor(null);
           if(!playhelper.realize(10000)){
               JOptionPane.showMessageDialog(this,
                  "cannot realize processor", "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
          
           setJPEGQuality(processor, 1.0f);
           processor.start();
          
           processor.getVisualComponent().setBackground(Color.gray);
           centerPanel.add(processor.getVisualComponent(), BorderLayout.CENTER);//视频面板
           centerPanel.add(processor.getControlPanelComponent(), BorderLayout.SOUTH);//视频控制面板
       }
      
       //界面初始化
       private void initComponents() {
           northPanel = new JPanel();
           messageLabel = new JLabel();
           southPanel = new JPanel();
           mainToolBar = new JToolBar();
           recordButton = new JButton();
           fileLabel = new JLabel();
           centerPanel = new JPanel();

           setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
           setTitle("本地视频");
           addWindowListener(new java.awt.event.WindowAdapter() {
               public void windowClosing(WindowEvent evt) {
                   formWindowClosing(evt);
               }
           });

           northPanel.setLayout(new BorderLayout());

           messageLabel.setText("状态:");
           northPanel.add(messageLabel, BorderLayout.SOUTH);
           getContentPane().add(northPanel, BorderLayout.NORTH);

           southPanel.setLayout(new BorderLayout());
           recordButton.setText("录制");
           recordButton.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent evt) {
                   recordButtonActionPerformed(evt);
               }
           });

           mainToolBar.add(recordButton);

           fileLabel.setText("文件:");
           mainToolBar.add(fileLabel);
           southPanel.add(mainToolBar, BorderLayout.CENTER);
           getContentPane().add(southPanel, BorderLayout.SOUTH);
           centerPanel.setLayout(new BorderLayout());
           getContentPane().add(centerPanel, BorderLayout.CENTER);

           pack();
       }
      
       private void formWindowClosing(java.awt.event.WindowEvent evt) {
        processor.close();
       }
      
       //录制当前视频
       private void recordButtonActionPerformed(java.awt.event.ActionEvent evt) {
        
           if(recordButton.getText().equals("录制")){
               fileLabel.setText("文件:");
               if (movieChooser == null) movieChooser = new JFileChooser();
               movieChooser.setDialogType(JFileChooser.SAVE_DIALOG);
               //Add a custom file filter and disable the default
               //(Accept All) file filter.
               movieChooser.addChoosableFileFilter(new MOVFilter());
               movieChooser.setAcceptAllFileFilterUsed(false);
               movieChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
               int returnVal = movieChooser.showDialog(this, "录制");
               if (returnVal == JFileChooser.APPROVE_OPTION) {
                   File file = movieChooser.getSelectedFile();
                   if(!file.getName().endsWith(".mov")
                      &&!file.getName().endsWith(".MOV")) file = new File(file.toString() + ".mov");
                   recordToFile(file);
                   fileLabel.setText("文件:" + file.toString());
                   recordButton.setText("停止");
               }
           }else{
               stopRecording();
               recordButton.setText("录制");
           }
       }
      
       void setJPEGQuality(Player p, float val) {
           Control cs[] = p.getControls();
           QualityControl qc = null;
           VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);
          
           // Loop through the controls to find the Quality control for
           // the JPEG encoder.
           for (int i = 0; i < cs.length; i++) {
               if (cs[i] instanceof QualityControl && cs[i] instanceof Owned) {
                   Object owner = ((Owned)cs[i]).getOwner();
                   // Check to see if the owner is a Codec.
                   // Then check for the output format.
                   if (owner instanceof Codec) {
                       Format fmts[] = ((Codec)owner).getSupportedOutputFormats(null);
                       for (int j = 0; j < fmts.length; j++) {
                           if (fmts[j].matches(jpegFmt)) {
                               qc = (QualityControl)cs[i];
                               qc.setQuality(val);
                               break;
                           }
                       }
                   }
                   if (qc != null) break;
               }
           }
       }
      
       public void checkIncoding(TrackControl track[]){
           for (int i = 0; i < track.length; i++) {
               Format format = track[i].getFormat();
               if (track[i].isEnabled() && format instanceof VideoFormat) {
                   Dimension size = ((VideoFormat)format).getSize();
                   float frameRate = ((VideoFormat)format).getFrameRate();
                   int w = (size.width % 8 == 0 ? size.width :(int)(size.width / 8) * 8);
                   int h = (size.height % 8 == 0 ? size.height :(int)(size.height / 8) * 8);
                   VideoFormat jpegFormat = new VideoFormat(
                      VideoFormat.JPEG_RTP, new Dimension(w, h), Format.NOT_SPECIFIED, Format.byteArray, frameRate);
                   messageLabel.setText("状态: 视频将以" + jpegFormat.toString()+"播放");
               }
           }
       }
      
       public void recordToFile(File file){
           URL movieUrl = null;
           MediaLocator dest = null;
           try{
               movieUrl = file.toURL();
               dest = new MediaLocator(movieUrl);
           }catch(MalformedURLException e){
              
           }
          
           recordCamSource = dataSource.cloneCamSource();
           try{
               recordProcessor = Manager.createProcessor(recordCamSource);
           }catch (IOException e) {
               JOptionPane.showMessageDialog(this,
                  "Exception creating record processor: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }catch (NoProcessorException e) {
               JOptionPane.showMessageDialog(this,
                  "Exception creating record processor: " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
           playhelper = new CamStateHelper(recordProcessor);
           if(!playhelper.configure(10000)){
               JOptionPane.showMessageDialog(this,
                  "cannot configure record processor", "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
          
           VideoFormat vfmt = new VideoFormat(VideoFormat.CINEPAK);
           (recordProcessor.getTrackControls())[0].setFormat(vfmt);
           (recordProcessor.getTrackControls())[0].setEnabled(true);
           recordProcessor.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME));
           Control control = recordProcessor.getControl("javax.media.control.FrameRateControl");
           if ( control != null && control instanceof javax.media.control.FrameRateControl )
              ((javax.media.control.FrameRateControl)control).setFrameRate(15.0f);
           if(!playhelper.realize(10000)){
               JOptionPane.showMessageDialog(this,
                  "cannot realize processor", "Error", JOptionPane.WARNING_MESSAGE);
               return;
           }
          
           try {
               if(recordProcessor.getDataOutput()==null){
                   JOptionPane.showMessageDialog(this,
                      "No Data Output", "Error", JOptionPane.WARNING_MESSAGE);
                   return;
               }
               dataSink = Manager.createDataSink(recordProcessor.getDataOutput(), dest);
               recordProcessor.start();
               dataSink.open();
               dataSink.start();
           } catch (NoDataSinkException ex) {
               JOptionPane.showMessageDialog(this,
                  "No DataSink " + ex.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
           } catch (IOException ex) {
               JOptionPane.showMessageDialog(this,
                  "IOException " + ex.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
           }
       }
      
       public void stopRecording(){
           try {
               recordProcessor.close();
               dataSink.stop();
               dataSink.close();
           } catch (IOException e) {
               JOptionPane.showMessageDialog(this,
                  "cannot stop recording " + e.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
           }
       }
 
     
 
   }
/***********************************************************************************************/

//MOVFilter.java

package ccnu.meng.jxtaApp.localTest;

import java.io.File;
import javax.swing.*;
import javax.swing.filechooser.*;

/* ImageFilter.java is a 1.4 example used by FileChooserDemo2.java. */
public class MOVFilter extends FileFilter {
    public boolean accept(File f) {
        if (f.isDirectory()) {
            return true;
        }

        String extension = MOVFilter.getExtension(f);
        if (extension != null) {
            if (extension.equalsIgnoreCase("MOV")) {
                    return true;
            } else {
                return false;
            }
        }

        return false;
    }

    //The description of this filter
    public String getDescription() {
        return "QuickTime Movies";
    }
   
    public static String getExtension(File f) {
        String ext = null;
        String s = f.getName();
        int i = s.lastIndexOf('.');

        if (i > 0 &&  i < s.length() - 1) {
            ext = s.substring(i+1).toLowerCase();
        }
        return ext;
    }
}
//本文转载自 http://mengmailu.bokee.com/viewdiary.15643624.html,嘿嘿

Feedback

# re: JMF实现视频捕获与录制  回复  更多评论   

2010-06-11 10:22 by cuiran
你好,看了你这篇文章,我也试着做了一下,但是视频画面没有出来,可以录制.想知道为什么?我是刚接触这,正好要用到视频录制功能.

# re: JMF实现视频捕获与录制  回复  更多评论   

2010-06-11 10:23 by cuiran
我的邮箱是cuiran2001@163.com.期待你的回复.谢谢!

只有注册用户登录后才能发表评论。


网站导航:
 

posts - 9, comments - 5, trackbacks - 0, articles - 0

Copyright © lauber