Capturing Time-Based Media with JMF

 
JMF 拍摄基于时间的媒体
 
你可以使用JMF从一个摄像装置如麦克风或录像机中截取媒体数据。截取的媒体数据能够被加工和播放,或存储以备将来使用。
 
要截取媒体数据:
通过查询CaptureDeviceManager定位你想使用的摄像驱动。
为这个驱动取得一个CaptureDeviceInfo对象。
从CaptureDeviceInfo对象中得到一个MediaLocator,然后使用它创建一个数据源。
使用这个数据源创建一个Player或Processor。
启动Player或Processor开始摄像处理。
 
当你用一个Player拍摄时,你只能舍弃拍摄到的媒体数据。要显示的处理或存储已拍摄的媒体数据,需要使用Processor。
 
访问摄像驱动
 
通过CaptureDeviceManager访问摄像驱动。为使所有的摄像驱动到JMF可用,CaptureDeviceMangager是重要的注册步骤。通过调用CaptureDeviceMangager.getDeviceList方法,你能够得到一个可用摄像驱动的列表。
 
每一个驱动都通过CaptureDeviceInfo对象来处理。要为一个特殊的驱动得到CaptureDeviceInfo对象,调用CaptureDeviceManager.getDevice:
 
CaptureDeviceInfo deviceInfo = CaptureDeviceManager.getDevice("deviceName");
 
拍摄媒体数据
 
从一个特别的驱动中拍摄媒体数据,你需要从它的CaptureDeviceInfo对象中得到驱动的MediaLocator。你可以使用MediaLocator直接创建一个Player或Processor,也可使用MediaLocator创建一个你能够使用像输入到Player或Processor的数据源。发起摄像过程,start这个Player或Processor。
 
允许用户控制拍摄过程
 
摄像驱动一般都有一套详细的执行属性,可用来控制驱动。摄像驱动定义了两类可编程的控制:
PorControl 和MonitorControl。你通过在拍摄源上调用getControl来访问这些控制,然后传递你想控制的名字。
 
PortControl 提供了一条途径来选择想要拍摄数据的端口。一个MonitorControl为显示驱动的摄像监控提供了一种方法,
 
像其他的控制对象,如果有符合PortControl或MonitorControl的可视组件,你可以通过调用getControlComponent来得到它。添加组件到你的applet或application窗口,以使用户能够
互操作拍摄控制。
 
结合你正使用的Player和Processor,你可显示标准控制面板组件和可视组件。
 
Example 5-1: Displaying GUI components for a processor.
  Component controlPanel, visualComponent;
  if ((controlPanel = p.getControlPanelComponent()) != null)
      add(controlPanel); 
  if ((visualComponent = p.getVisualComponent()) != null)
      add(visualComponent); 
 
存储拍摄到的媒体数据
 
如果你想把拍摄到的媒体数据保存到一个文件中,需要使用Processor来替换掉Player。使用一个DataSink从Processor对象的输出数据源中来读媒体数据,然后再返回数据到一个文件。
 
1. 通过调用getDataOutput从Processor中得到输出数据源.
2. 通过调用Manager.createDataSink创建一个文件写入者DataSink。传递输出数据源和一个MediaLocator,这是你指定想要写入的文件的地址。
3. 在DataSink上调用open打开文件。
4. 在DataSink上调用start。
5. 在Processor上调用start开始拍摄数据。
6. 等待一个EndOfMediaEvent,一个特殊的媒体数据,或者一个用户事件。
7. 在Processor 上调用stop结束数据拍摄。
8. 在Processor上调用close。
9. 当Processor被关闭时,DataSink提交一个EndOfStreamEvent事件,在DataSink调用close。
 
Example 5-2: Saving captured media data to a file.
  DataSink sink;
  MediaLocator dest = new MediaLocator("file://newfile.wav");
  try {
          sink = Manager.createDataSink(p.getDataOutput(), dest);
          sink.open();
          sink.start();
  } catch (Exception) {}
 
例子:拍摄和播放生活中的音频数据
 
要从一个麦克风中拍摄生活音频数据并且播放,你需要:
 
1. 从麦克风得到CaptureDeviceInfo对象。
2. 从CaptureDeviceInfo对象中使用重新得到的MediaLocator创建一个Player。(你可以通过调用createDeviceInfo对象来创建Player,或者用MediaLocator创建一个DataSource,然后使用createPlayer(DataSource)去创建Player。
 
Example 5-3: Capturing and playing audio from a microphone.
  // 为音频摄像驱动取得CaptureDeviceInfo
  Vector deviceList = CaptureDeviceManager.getDeviceList(new
                         AudioFormat("linear", 44100, 16, 2));
  if (deviceList.size() > 0)
          di = (CaptureDeviceInfo)deviceList.firstElement();
  else
  // Exit if we can't find a device that does linear, 44100Hz, 16 bit,
// stereo audio.
      System.exit(-1);
 
  // Create a Player for the capture device:
  try{
      Player p = Manager.createPlayer(di.getLocator());
  } catch (IOException e) {
  } catch (NoPlayerException e) {}
 
例子:将已拍摄的音频数据写入文件
 
你可以使用DataSink将拍摄到的媒体数据写入一个文件中。要拍摄并存储文件,你需要:
 
1. 从音频拍摄驱动中得到CaptureDeviceInfo对象。
2. 从CaptureDeviceInfo对象中使用重新得到的MediaLocator创建一个Processor。
3. 从Processor中得到输出数据源。
4. 为文件中你想写入所拍摄到的数据的位置创建一个MediaLocator。
5. 使用输出数据源创建一个文件写入DataSink。
6. 开始写入文件,启动Processor。
 
这个例子使用了一个助手类,StatatHelper.java,去管理Processor的状态。为StateHelper完成的源代码被包含在附录的page 179页。
 
Example 5-4: Writing captured audio to a file with a DataSink. (1 of 2)
          CaptureDeviceInfo di = null;
          Processor p = null;
          StateHelper sh = null;
          Vector deviceList = CaptureDeviceManager.getDeviceList(new
                                  AudioFormat(AudioFormat.LINEAR, 44100, 16, 2));
          if (deviceList.size() > 0)
              di = (CaptureDeviceInfo)deviceList.firstElement();
          else
              // Exit if we can't find a device that does linear,
           // 44100Hz, 16 bit,
              // stereo audio.
              System.exit(-1);
          try {
              p = Manager.createProcessor(di.getLocator());
              sh = new StateHelper(p);
          } catch (IOException e) {
              System.exit(-1);
          } catch (NoProcessorException e) {
              System.exit(-1);
          }
          // Configure the processor
          if (!sh.configure(10000))
              System.exit(-1);
          // Set the output content type and realize the processor
          p.setContentDescriptor(new
                   FileTypeDescriptor(FileTypeDescriptor.WAVE));
          if (!sh.realize(10000))
              System.exit(-1);
          // get the output of the processor
          DataSource source = p.getDataOutput();
          // create a File protocol MediaLocator with the location of the
          // file to which the data is to be written
          MediaLocator dest = new MediaLocator("file://foo.wav");
          // create a datasink to do the file writing & open the sink to
          // make sure we can write to it.
          DataSink filewriter = null;
          try {
             filewriter = Manager.createDataSink(source, dest);
              filewriter.open();
          } catch (NoDataSinkException e) {
              System.exit(-1);
          } catch (IOException e) {
              System.exit(-1);
          } catch (SecurityException e) {
              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) {
              System.exit(-1);
          }
          // Capture for 5 seconds
          sh.playToEndOfMedia(5000);
          sh.close();
          // Wait for an EndOfStream from the DataSink and close it...
          filewriter.close();
 
例子:编码拍摄到的音频数据
 
在播放、传输或存储数据之间,你可以配置一个Processor转换拍摄到的数据。在存储到一个文件以前,要将拍摄到数据编码到IMA4格式。
 
1. 为摄像驱动得到MediaLocator,然后创建一个Processor。
2. 在Processor上调用configure。
3. 一旦Processor处于Configured状态,调用getTrackControls方法。
4. 直到你找出能被转换成IMA4的那个媒体,就在每个轨迹上调用setFormat。(因为setFormat要成功,适当的编解码器插件完成转换时必须是可用的。
5. 实现Processor,然后使用它的输出数据源创建一个DataSink写数据到文件中。
 
Example 5-5: Encoding captured audio data.  
          // Configure the processor
          if (!sh.configure(10000))
              System.exit(-1);
          // Set the output content type
          p.setContentDescriptor(new
                 FileTypeDescriptor(FileTypeDescriptor.WAVE));
 
          // Get the track control objects
          TrackControl track[] = p.getTrackControls();
          boolean encodingPossible = false;
          // Go through the tracks and try to program one of them
          // to output ima4 data.
          for (int i = 0; i < track.length; i++) {
              try {
                  track[i].setFormat(new AudioFormat(AudioFormat.IMA4_MS));
                  encodingPossible = true;
              } catch (Exception e) {
                  // cannot convert to ima4
                  track[i].setEnabled(false);
              }
          }
 
          if (!encodingPossible) {
              sh.close();
              System.exit(-1);
          }
          // Realize the processor
          if (!sh.realize(10000))
              System.exit(-1);
 
例子:拍摄和保存音频视频数据
 
在这个例子中,一个ProcessorModel被用于创建一个Processor来拍摄生活中的视频和音频数据,编码数据像IMA4和Cinepak轨迹,交叉存取轨迹,然后存储交叉存取的媒体数据到一个QuickTime文件。
 
当你通过指定的轨迹格式创建一个ProcessorModel时,输出内容的类型,然后使用模式去创建一个Processor,这个Processor是自动地被连接到合适的格式需要的摄像驱动,如果有一个的话。
 
Example 5-6: Creating a capture Processor with ProcessorModel.  
          Format formats[] = new Format[2];
          formats[0] = new AudioFormat(AudioFormat.IMA4);
          formats[1] = new VideoFormat(VideoFormat.CINEPAK);
          FileTypeDescriptor outputType =
              new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME);
          Processor p = null;
          
          try {
              p = Manager.createRealizedProcessor(new ProcessorModel(formats,
                                                                     outputType));
          } catch (IOException e) {
              System.exit(-1);
          } catch (NoProcessorException e) {
              System.exit(-1);
          } catch (CannotRealizeException e) {
              System.exit(-1);
          }
          // get the output of the processor
          DataSource source = p.getDataOutput();
          // create a File protocol MediaLocator with the location
       // of the file to
          // which bits are to be written
          MediaLocator dest = new MediaLocator("file://foo.mov");
          // create a datasink to do the file writing & open the
       // sink to make sure
          // we can write to it.
          DataSink filewriter = null;
          try {
              filewriter = Manager.createDataSink(source, dest);
              filewriter.open();
          } catch (NoDataSinkException e) {
              System.exit(-1);
          } catch (IOException e) {
              System.exit(-1);
          } catch (SecurityException e) {
              System.exit(-1);
          }
          // now start the filewriter and processor
          try {
              filewriter.start();
          } catch (IOException e) {
              System.exit(-1);
          }
          p.start();
          // stop and close the processor when done capturing...
          // close the datasink when EndOfStream event is received...
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值