JMF捕获音频和视频一

简介:
本文主要阐述JMF捕获音频和视频技术。并给出源代码实例。
author: ZJ    06-11-16
 
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();
    }
}


本文转自zhangjunhd51CTO博客,原文链接:http://blog.51cto.com/zhangjunhd/25475,如需转载请自行联系原作者

相关文章
|
编解码 Android开发 C语言
【Android 高性能音频】AAudio 音频库 简介 ( AAudio 音频库简介 | 音频流 | 音频设备 | 共享模式 | 数据模式 )
【Android 高性能音频】AAudio 音频库 简介 ( AAudio 音频库简介 | 音频流 | 音频设备 | 共享模式 | 数据模式 )
757 0
|
编解码 网络安全 Windows
eyeBeam音频出现问题要如何处理
eyeBeam音频出现问题要如何处理
|
测试技术 API Android开发
【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )(一)
【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )(一)
334 0
【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )(一)
|
测试技术 API Android开发
【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )(二)
【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )(二)
294 0
【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )(二)
|
数据采集 传感器 编解码
【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )
【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )
287 0
|
设计模式 Android开发 数据格式
【Android 高性能音频】AAudio 音频流 构建器 ( AAudio.h | 流构造器 | 音频设备配置 | 音频采样配置 | 构建器销毁 )
【Android 高性能音频】AAudio 音频流 构建器 ( AAudio.h | 流构造器 | 音频设备配置 | 音频采样配置 | 构建器销毁 )
164 0
|
存储 自然语言处理 监控
音频开发中常见的四个错误
以下内容主要为音频开发人员所编写,但同样也能为其他领域并与此相关的开发者带来帮助。在下文当中我将介绍针对开发人员的诊断工具,并分享常见的四个错误以及如何检测问题是否存在并做得更好。
352 0
音频开发中常见的四个错误