利用JMF進行多媒體編程(4)

作者:馮睿    本文選自:賽迪網  2002年09月29日  
 
2.註冊音頻和視頻截取設備 

在例子中,註冊音頻和視頻截取設備的方法只在程序的內部註冊這些設備,在程序外則不起作用。該方法的作用是當用戶的計算機上存在多和音頻和視頻截取設備時,告訴程序因該使用哪個設備和這些設備支持的音頻和視頻格式。因此在進行截取處理之前需要獲得設備的配置信息。在例子中,當在Configure菜單上按下Capture Device命令後,會彈出CaptureDeviceDialog對話框。如果在截取音頻或視頻前沒有設定設備的配置,也會彈出該對話框。圖三顯示了該對話框。 






圖三 設備註冊對話框


讓我們來看一下CaptureDeviceDialog類中的init()方法:在初始化了界面之後,通過調用CaptureDeviceManager類的getDeviceList()方法: 

devices = CaptureDeviceManager.getDeviceList ( null );
 


CaptureDeviceManager類使用查詢機制和一個註冊表來定位設備,然後將設備的信息放入CaptureDeviceInfo對象中返回。我們還可以利用CaptureDeviceManager類來註冊新的設備。通過調用getDeviceList()方法程序獲取了一個支持指定格式的設備的列表。在例子中,我將格式參數設定爲null,這意味着設備可以使用任何格式。返回值被放入device變量中。如果getDeviceList()方法返回的是一個非空值,程序會將包含在其中的音頻設備名稱和視頻設備名稱分別放入兩個下拉列表中中,但是到目前爲止我們還不知道哪些設備是音頻設備,哪些是視頻設備。 

我們可以通過CaptureDeviceInfo的getFormat()方法獲得Format對象組數,在Format對象中保存了設備支持的媒體格式。Format類間接被AudioFormat和VideoFormat類所繼承。因此我們可以利用設備支持的格式類型來區分設備的類型: 

if (devices!=null && devices.size()>0) {
      int deviceCount = devices.size();
      audioDevices = new Vector();
      videoDevices = new Vector();
      Format[] formats;
      for ( int i = 0;  i < deviceCount;  i++ ) {
        cdi = (CaptureDeviceInfo) devices.elementAt ( i );
        formats = cdi.getFormats();
        for ( int j=0;  j<formats.length; j++ ) {
          if ( formats[j] instanceof AudioFormat ) {
            audioDevices.addElement(cdi);
            break;
          }
          else if (formats[j] instanceof VideoFormat ) {
            videoDevices.addElement(cdi);
            break;
          }
        }
      }
      . . .
    }
 


上面的程序運行後,audioDevices()中將包含所有的音頻設備,videoDevices()中將保存所有的視頻設備。其中cdi是CaptureDeviceInfo對象。然後將設備名稱填入下拉列表中: 

// 將音頻設備顯示在下拉列表中
      for (int i=0; i<audioDevices.size(); i++) {
        cdi  = (CaptureDeviceInfo) audioDevices.elementAt(i);
        audioDeviceCombo.addItem(cdi.getName());
      }
      // 將視頻設備顯示在下拉列表中
      for (int i=0; i<videoDevices.size(); i++) {
        cdi  = (CaptureDeviceInfo) videoDevices.elementAt(i);
        videoDeviceCombo.addItem(cdi.getName());
      }
 


然後程序顯示出當前選中的設備支持的格式: 

displayAudioFormats();
      displayVideoFormats();
 


下一步需要獲取用戶選中的音頻設備和視頻設備以及它們支持的格式,相關的方法是JMF類中的getAudioDevice()、getVideoDevice()、getAudioFormat()和getVideoFormat()方法。然後將獲取的對象分別保存到audioCDI,videoCDI,audioFormat和videoFormat中: 

audioCDI = cdDialog.getAudioDevice();
    if (audioCDI!=null) {
      audioDeviceName = audioCDI.getName();
      System.out.println("Audio Device Name: " + audioDeviceName);
    }
    videoCDI = cdDialog.getVideoDevice();
    if (videoCDI!=null) {
      videoDeviceName = videoCDI.getName();
      System.out.println("Video Device Name: " + videoDeviceName);
    }
    // 獲得選中的多媒體格式
    videoFormat = cdDialog.getVideoFormat();
    audioFormat = cdDialog.getAudioFormat();
 


3.截取視頻和音頻 

使用capture()方法可以截取音頻和視頻數據。但是在使用該方法前需要確定是否已經選中了視頻和音頻截取設備: 

if (audioCDI==null &#38;&#38; videoCDI==null)
        registerDevices();
 


和play()方法類似,可以通過使用Manger類中的靜態方法createPlayer()創建一個Player對象,該對象可以播放一個DataSource對象中的數據流。 

Player createPlayer(MediaLocator sourceLocator)
 


在例子中,我首先通過調用audioCDI和videoCDI的getLocator()方法來獲得MediaLocator對象,然後利用Manager類的createPlayer()方法創建Player對象。最後將一個ControllerListener對象綁定到視頻Player對象上並開始播放。 

videoPlayer = Manager.createPlayer(videoCDI.getLocator());
        audioPlayer = Manager.createPlayer(audioCDI.getLocator());
        videoPlayer.addControllerListener(this);
        videoPlayer.start();
        audioPlayer.start();
 


使用這種方法導致最後獲得了兩個Player對象。我們也可以使用Manager類中的createDataSource()方法從視頻和音頻CaptureDeviceInfo對象(audioCID和videoCDI)中獲得視頻和音頻數據源(DataSource對象),然後調用createMergingDataSource()方法將兩個數據源合併成一個數據源(ds): 

DataSource[] dataSources = new DataSource[2];
        dataSources[0] =
          Manager.createDataSource(audioCDI.getLocator());
        dataSources[1] =
          Manager.createDataSource(videoCDI.getLocator());
        DataSource ds = Manager.createMergingDataSource(dataSources);
 


然後可以使用ds作爲createPlayer()方法的參數來獲得一個Player對象dualPlayer。調用addControllerListener()就可以進行播放了。 

dualPlayer = Manager.createPlayer(ds);
dualPlayer.addControllerListener(this);
dualPlayer.start();
 



小結


Java多媒體框架是一個很好的多媒體編程工具。在這篇文章中我只是簡單介紹了JMF的一些基本功能。如果有興趣的話可以仔細閱讀一下Sun公司的Java網站上提供的JMStudio的例子。在JMStudio中不僅實現了簡單的播放和視頻/音頻截取功能,還實現了從互聯網下載和向互聯網上傳多媒體數據流的功能。而且它還包含了JMFRegistry的源代碼,將相應的代碼移植到你的應用程序中後,你就不需要在運行程序前運行JMFRegistry來向JMF註冊設備了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章