Capturing Time-Based Media with JMF

来源:互联网 发布:linux heartbeat 下载 编辑:程序博客网 时间:2024/04/28 07:39
 
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...
 
 
 
原创粉丝点击