JMF捕获音频和视频(转贴)

1  1、捕获媒体数据的步骤:

l 查询CaptureDeviceManager,来定位你需要使用的媒体采集设备。

l 得到此设备的CaptureDeviceInfo实例。

l  从此CaptureDeviceInfo实例获得一个MediaLocator,并通过它来创建一个DataSource

l 用此DataSource创建一个PlayerProcessor

l 启动此PlayerProcessor开始捕获媒体数据。

 

2CaptureDeviceManagerCaptureDeviceInfoMediaLocator

JMF中,CaptureDeviceManager也是一个manager,它提供给了一个列表,这个列表显示当前系统可以被使用的设备名称。同时CaptureDeviceManager可以通过查询的方法对设备进行定位并返回设备的配置信息对象CaptureDeviceInfo,它也可以通过注册的方法向列表加入一个新的设备信息,以便为JMF使用。

设备可通过CaptureDeviceManagergetDevice()方法直接获得设备控制权,设备的控制权一旦得到,就可以以此设备作为一个MediaLocator,可以通过CaptureDeviceInfogetLocator()方法得到。

 

3  JMF识别的音频采集设备

 

4.一个实例实现音频捕获

实例有两个文件组成。CaptureAudio.java实现

查询、获得音频采集设备。

捕获音频。

将音频保存到本地文件foo.wav

StateHelper实现处理器(processor)的状态控制管理。以下为流程图:

5.音频捕获代码实例:

CaptureAudio.java

import java.io.IOException;

import java.util.Vector;

 

import javax.media.CaptureDeviceInfo;

import javax.media.CaptureDeviceManager;

import javax.media.DataSink;

import javax.media.Manager;

import javax.media.MediaLocator;

import javax.media.NoDataSinkException;

import javax.media.NoProcessorException;

import javax.media.Processor;

import javax.media.control.StreamWriterControl;

import javax.media.format.AudioFormat;

import javax.media.protocol.DataSource;

import javax.media.protocol.FileTypeDescriptor;

 

public class CaptureAudio {

      /**

       * Writing captured audio to a file with a DataSink.

       */

      public static void main(String[] args) {

           CaptureDeviceInfo di = null;

          Processor p = null;

          StateHelper sh = null;

 //查询CaptureDeviceManager,来定位你需要使用的媒体采集设备。

          Vector deviceList = CaptureDeviceManager.getDeviceList(new

                           AudioFormat(AudioFormat.LINEAR, 44100, 16, 2));

            if (deviceList.size() > 0){

//得到此设备的CaptureDeviceInfo实例。

                di = (CaptureDeviceInfo)deviceList.firstElement();

                }

            else

                // 找不到满足(linear, 44100Hz, 16 bit,stereo audio.)音频设备,退出。

                System.exit(-1);

            try {

             //获得MediaLocator,并由此创建一个Processor

                  p = Manager.createProcessor(di.getLocator());

                sh = new StateHelper(p);

             } catch (IOException e) {

                  e.printStackTrace();

                System.exit(-1);

            } catch (NoProcessorException e) {

                  e.printStackTrace();

                System.exit(-1);

            }

            // Configure the processor

            if (!sh.configure(10000)){

                  System.out.println("configure wrong!");

                System.exit(-1);

                }

            //定义待存储该媒体的内容类型(content type)。

            p.setContentDescriptor(new

                        FileTypeDescriptor(FileTypeDescriptor.WAVE));

         // realize the processor.

            if (!sh.realize(10000)){

                  System.out.println("realize wrong!");

                System.exit(-1);

                }

            // get the output of the processor

           DataSource source = p.getDataOutput();

         //定义存储该媒体的文件。

           MediaLocator dest = new MediaLocator(new java.lang.String(

                 "file:///D:/Dvp/workspace/JavaSoundMedia/foo.wav"));

         //创建一个数据池

            DataSink filewriter = null;

            try {

                filewriter = Manager.createDataSink(source, dest);

                filewriter.open();

            } catch (NoDataSinkException e) {

                  e.printStackTrace();

                System.exit(-1);

            } catch (IOException e) {

                  e.printStackTrace();

                System.exit(-1);

            } catch (SecurityException e) {

                  e.printStackTrace();

                System.exit(-1);

            }

            // if the Processor implements StreamWriterControl, we can

            // call setStreamSizeLimit

            // to set a limit on the size of the file that is written.

            StreamWriterControl swc = (StreamWriterControl)

                p.getControl("javax.media.control.StreamWriterControl");

            //set limit to 5MB

            if (swc != null)

                swc.setStreamSizeLimit(5000000);

            // now start the filewriter and processor

            try {

                filewriter.start();

            } catch (IOException e) {

                  e.printStackTrace();

                System.exit(-1);

            }

            // Capture for 5 seconds

            sh.playToEndOfMedia(5000);

            sh.close();

            // Wait for an EndOfStream from the DataSink and close it...

            filewriter.close();

      }

}

StateHelper.java

import javax.media.*;

 

public class StateHelper implements javax.media.ControllerListener {

    Player player = null;

    boolean configured = false;

    boolean realized = false;

    boolean prefetched = false;

    boolean eom = false;//End of media.

    boolean failed = false;

    boolean closed = false;

    public StateHelper(Player p) {

       player = p;

       p.addControllerListener(this);

    }

    /**

     * To judge whether the processor is configured.

       * Configure the processor in the given time which is limited

       * by the timeOutMillis.Once a Processor is Configured, you

       * can set its output format and TrackControl options.

       */

    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;

    }

    /**

     * To judge whether the playerr is realized.

     */

    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;

    }

    /**

     * To judge whether the player is prefetched.

     */

    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;

    }

    /**

     * To judge whether the player has finished.

     */

    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();

    }

}

6.关于视频捕获

6.1VFW(Video for Windows)

在阐述如何识别视频采集设备之前,我们先引入VFW概念:

VFW Microsoft公司为开发Windows平台下的视频应用程序提供的软件工具包,提供了一系列应用程序编程接口(API),用户可以通过它们很方便地实现视频捕获、视频编辑及视频播放等通用功能,还可利用回调函数开发更复杂的视频应用程序。它的特点是播放视频时不需要专用的硬件设备,而且应用灵活,可以满足视频应用程序开发的需要。Windows操作系统自身就携带了VFW,系统安装时,会自动安装VFW的相关组件。

下表为VFW的功能模块

 

     

AVICAP.DLL

包含执行视频捕获的函数,它给AVI文件的I/O处理和视频、音频设备驱动程序提供一个高级接口

MSVIDEO.DLL

包含一套特殊的DrawDib函数,用来处理屏幕上的视频操作

MCIAVI.DRV

包括对VFWMCI命令解释器的驱动程序

AVIFILE.DLL

包含由标准多媒体I/Ommio)函数提供的更高的命令,用来访问.AVI文件

ICM

压缩管理器,用于管理的视频压缩/解压缩的编译码器(Codec

ACM

音频压缩管理器,提供与ICM相似的服务,适用于波形音频

 

6.2 JMFVFW的关系:

注意以下代码:

String str1 = "vfw:Logitech USB Video Camera:0";

String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";

device = CaptureDeviceManager.getDevice(str2);

medialocator = device.getLocator();

只要是vfw开头的设备信息,就能为JMF架构识别并加以使用。可以编写代码来识别此设备。

JMF中,当使用了 Detect Capture Devices以后,可以发现在Capture Devices多了一个设备名称:

6.3一个识别类代码及分析

private MediaLocator autoDetect(){//自动识别功能函数

     MediaLocator ml = null; //视频采集设备对应的MediaLocator

     VideoFormat currentFormat  =   null;//用户定制获得视频采集设备支持的格式

     Format setFormat = null;//用户定制视频采集设备输出的格式

     Format[] videoFormats  =   null;//视频采集设备支持的所有格式

     System.out.println(" AutoDetect for VFW");

    //获得当前所有设备列表

     Vector deviceList = CaptureDeviceManager.getDeviceList( null );    

     if( deviceList != null ){

        //根据设备列表,找出可用设备名称

        for( int i=0; i<deviceList.size(); i++ ){

            try{

             CaptureDeviceInfo di=( CaptureDeviceInfo )deviceList.elementAt(i);

             //如果设备名称以vfw开头

             if( di.getName().startsWith("vfw:") ){

               //获得所有支持RGB格式  

               videoFormats = di.getFormats();

               for( int j=0; j<videoFormats.length; j++ ){

                    //我们只需要第一种RGB格式

                    if( videoFormats[j] instanceof RGBFormat ){

                        currentFormat = ( RGBFormat )videoFormats[i];

                        break;

                    }

                }

                if( currentFormat == null ) {

                    System.err.println("Search For RGBFormat Failed");

                    System.exit( -1 );

                }

                //通过设备,获得MediaLocator,这个很重要

                ml  =   di.getLocator();

}

        }

        catch ( Exception npe ) {

            System.err.println( "Unable to get Processor for device");

            System.exit(-1);

        }

      }

    }

    else {

        System.err.println( "No Capture Device OK");

        System.exit(-1);

    }

    return ml;//返回可用的设备medialocator

   }

   

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值