2010-10-28 71 views
13

我正在研究使用JMF捕獲視頻和音頻並將其傳輸到另一個端點的視頻會議項目。一個問題是我的團隊不希望產品的用戶必須安裝JMF。如何使用JMF捕獲視頻但未安裝JMF

我認爲可能值得分享我們的解決方案來解決這個問題。有用。它運作良好。我對你的問題是:有沒有人有更好的方法來做到這一點?

環境:Windows,XP及以上

  1. 下載JMF的Windows
  2. 你的機器上安裝它

  3. 在system32文件夾中找到以下dll小號JMF安裝後:

    jmacm.dll
    jmam.dll
    jmcvid.dll
    jmdaud.dll
    jmdaudc.dll
    jmddraw.dll
    jmfjawt.dll
    jmg723.dll
    jmgdi.dll
    jmgsm.dll
    jmh261.dll
    jmh263enc.dll
    jmjpeg.dll
    jmmci.dll
    jmmpa.dll
    jmmpegv.dll
    jmutil.dll
    jmvcm.dll
    jmvfw.dll
    jmvh263.dll
    jsound.dll

  4. 複製dll s轉換爲臨時文件夾

  5. 找到jmf.properties文件(在執行搜索您爲它的電腦)
  6. 下載JMF的源代碼
    在源代碼中,找到以下文件:

JMFinit.java
JMRPropertiesGen.java
Registry.java
RegistryGen。java

  1. 創建一個包;我稱之爲JMFNoInstall
  2. 添加步驟中列出的文件6
  3. 添加一個名爲Main這個包這樣的類:

 

package JMFNoInstall; 
// add your imports and whatnot here 
public class Main() 
{ 
    public Main() 
    { 
     JMFinit.main(null); 
     JMFPropertiesGen.main(null); 
     Registry.main(null); 
     RegistryGen.main(new String[] { 
      new File(".").getAbsolutePath(), 
      "registrylib" 
     }); 
    } 
} 

jmf.properties文件需要去與包含main方法的類相同的文件夾或與包含main方法的JAR存檔相同的文件夾。
dll需要進入win32文件夾。您可以檢查程序是否在win32文件夾中。如果他們不是,你可以讓它從某個位置複製它們。上面列出的Main類運行時,jmf.properties文件會更新。您只需運行一次,程序第一次運行,或者用戶想要添加新的捕獲設備。最後,請確保類路徑中包含隨Windows JMF下載一起提供的jmf.jar文件和jmfcom.jar。在這一點上你很好。 JMF的所有功能都不需要實際安裝。

確實沒有太多的工作涉及到這一點,您可以很容易地將它合併到您的自定義安裝程序中。

有沒有人找到更好的方法來做到這一點,但?這樣做有幾個缺陷。

編輯:我認爲這可能是值得分享一些我創建的代碼。當然你需要修改它來處理你的事情。它很可能不會編譯,但缺少的東西應該很容易重新創建。但認爲這可能是幫助人們的一個很好的起點。 detectCaptureDevices函數可能會幫助大多數人。我隨時更新這門課。

 

import GUI.Window; 
import GlobalUtilities.OS; 
import GlobalUtilities.ProgressBar; 
import GlobalUtilities.FileUtilities; 
import java.io.File; 
import java.util.ArrayList; 
import java.util.Vector; 
import javax.swing.text.Utilities; 


/** 
* This class providex easy access to the most needed info about JMF. You can test 
* a JMF install (Windows only currently) and also get info about the captrue 
* devices hooked up to JMF. 
* @author dvargo 
*/ 
public class JMFRunner 
{ 
    /** 
    * Show the status of operations 
    */ 
    final ProgressBar theBar = new ProgressBar(); 
    /** 
    * Location where the dll's JMF relies on need to be placed 
    */ 
    final String windowsDllFolder = "C:\\WINDOWS\\system32\\"; 

    final String linuxDllFolder = "/usr/lib/"; 

    /** 
    * Dll's that JMF uses 
    */ 
    final String[] windowsDllList = new String[]{ 
     "jmacm.dll", 
     "jmam.dll", 
     "jmcvid.dll", 
     "jmdaud.dll", 
     "jmdaudc.dll", 
     "jmddraw.dll", 
     "jmfjawt.dll", 
     "jmg723.dll", 
     "jmgdi.dll", 
     "jmgsm.dll", 
     "jmh261.dll", 
     "jmh263enc.dll", 
     "jmjpeg.dll", 
     "jmmci.dll", 
     "jmmpa.dll", 
     "jmmpegv.dll", 
     "jmutil.dll", 
     "jmvcm.dll", 
     "jmvfw.dll", 
     "jmvh263.dll", 
     "jsound.dll"}; 

    String[] linuxDllList = new String[]{ 
     "libjmcvid.so", 
     "libjmdaud.so", 
     "libjmfjawt.so", 
     "libjmg723.so", 
     "libjmgsm.so", 
     "libjmh261.so", 
     "libjmh263enc.so", 
     "libjmjpeg.so", 
     "libjmmpa.so", 
     "libjmmpegv.so", 
     "libjmmpx.so", 
     "libjmutil.so", 
     "libjmv4l.so", 
     "libjmxlib.so" 
    }; 

    String [] dlls= null; 
    String dir = null; 

    /** 
    * List of the video capture devices found by JMF 
    */ 
    Vector videoDevices = null; 
    /** 
    * List of the audio capture devices found by JMF 
    */ 
    Vector audioDevices = null; 

    public JMFRunner() 
    { 
     if(OS.isWindows()) 
     { 
      dlls = windowsDllList; 
      dir = windowsDllFolder; 
     } 
     else if(OS.isLinux()) 
     { 
      dlls = linuxDllList; 
      dir = linuxDllFolder; 
     } 
     else 
     { 
      Window.getLogger().severe("Operating system does not support JMF"); 
     } 

    } 

    /** 
    * Adds new capture devices 
    */ 
    public void detectCaptureDecives() 
    { 


     Thread theTread = new Thread(theBar); 
     theTread.start(); 
     theBar.repaint(); 

     JMFInit.main(new String[] {""}); 
     JMFPropertiesGen.main(new String[] {""}); 
     Registry.main(new String[] {""}); 
     RegistryGen.main(new String[] {"-d", 
      new File(".").getAbsolutePath(), 
      "registrylib" 
     }); 

     theBar.setMessage(""); 
     theBar.stop(); 
    } 

    /** 
    * Verifies that all the dll's that JMF needs are in their correct spot 
    * @return True if all dlls are in their correct spot, false otherwise 
    */ 
    public boolean detectDlls() 
    { 
     boolean retVal = true; 
     String currFile; 
     for(String currDll : dlls) 
     { 
      currFile = dir + currDll; 
      if(! new File(currFile).exists()) 
      { 
       Window.getLogger().severe("Can not find dll " + currFile + " for JMF"); 
       retVal = false; 
      } 
     } 
     return retVal; 
    } 

    //Doesnt work quite yet 
    public boolean installLibraryFiles() 
    { 
     boolean retVal = true; 
     String currFile; 
     for(String currDll : dlls) 
     { 
      currFile = dir + currDll; 
      File newDll = new File(currFile); 
      //see if this dll is already there 
      if(!newDll.exists()) 
      { 
       //its not there so lets copy it 
       try 
       { 
        FileUtilities.copy(newDll,FileUtilities.getResourceFile("/JMFManager/Resources/"+currDll,currDll)); 
       } 
       catch(Exception e) 
       { 
        retVal = false; 
       } 
      } 
     } 
     return retVal; 
    } 

    /** 
    * Returns the location of the jmf.properties file that STix is using 
    * @return THe locaiton of the JMF properties 
    */ 
    public String getJMFPropertiesFileLocation() 
    { 
     return Registry.getJMFPropertiesFileLocation(); 
    } 

    /** 
    * Returns a list of the audio devices found by JMF 
    * @return Returns an Arraylist containing info about the audio capture devices 
    */ 
    public ArrayList getAudioDevices() 
    { 
     DeviceFinder df = new DeviceFinder(); 
     audioDevices = df.getSoundCaptureDevices(); 
     return new ArrayList(audioDevices); 
    } 

    /** 
    * Returns a list of the video decives deteced by JMF 
    * @return returns an arraylist with info of the video capture devices 
    */ 
    public ArrayList getVideoDevices() 
    { 
     DeviceFinder df = new DeviceFinder(); 
     videoDevices = df.getVideoCaptureDevices(); 
     return new ArrayList(videoDevices); 
    } 


    public static void main(String [] args) 
    { 
     JMFRunner x = new JMFRunner(); 
     //x.detectCaptureDecives(); 
     x.installLibraryFiles(); 
     System.out.println(x.detectDlls()); 
     System.out.println(x.getJMFPropertiesFileLocation()); 
     System.out.println(x.getAudioDevices()); 
     System.out.println(x.getVideoDevices()); 
    } 
} 
 

DeviceFinder.java

 

import java.util.Vector; 
import javax.media.*; 
import javax.media.format.*; 

/** 
* this class gets information about capture devices (mics and cameras) 
*/ 
public class DeviceFinder { 

    Vector videoDevices = new Vector(); 
    Vector audioDevices = new Vector(); 

    /** 
    * Constructor 
    * Creates a new DeviceFinder 
    */ 
    public DeviceFinder() 
    { 
     /*retrieve ALL video and audio devices*/ 
     videoDevices = CaptureDeviceManager.getDeviceList(new VideoFormat(null)); 
     audioDevices = CaptureDeviceManager.getDeviceList(new AudioFormat(null)); 
    } 

    /** 
    * purpose: Get information on all Video capture devices on the system 
    * @return java.util.Vector 
a vector of attributes */ public Vector getVideoCaptureDevices() { return videoDevices; } /** * purpose: Get information on all audio capture devices on the system * @return java.util.Vector
a vector of attributes */ public Vector getSoundCaptureDevices() { return audioDevices; } /** * retrieve the first video capture device */ public CaptureDeviceInfo getPrimaryVideoCaptureDevice() { return (CaptureDeviceInfo)videoDevices.get(0); } /*retrieve the first audio capture device*/ public CaptureDeviceInfo getPrimaryAudioCaptureDevice() { return (CaptureDeviceInfo)audioDevices.get(0); } /** * get the first video device name * @return String
the name of the video device */ public String getVideoCaptureDeviceName() { return ((CaptureDeviceInfo)videoDevices.get(0)).getName(); } /** * get the first audio device name * @return String
the name of the audio device */ public String getAudioCaptureDeviceName() { return ((CaptureDeviceInfo)audioDevices.get(0)).getName(); } /** * get the first video device media locator * @return MediaLocator */ public MediaLocator getVideoMediaLocator() { return ((CaptureDeviceInfo)videoDevices.get(0)).getLocator(); } /** * get the first audio device media locator * @return MediaLocator */ public MediaLocator getAudioMediaLocator() { return ((CaptureDeviceInfo)audioDevices.get(0)).getLocator(); } /** * get the video device media locator at index idx * @param idx index of the media locator (0 is the first/default, * as ordered by *
the JMFRegistry) * @return MediaLocator */ public MediaLocator getVideoMediaLocator(int idx) { if(idx >= videoDevices.size()) { return null; } return ((CaptureDeviceInfo)videoDevices.get(idx)).getLocator(); } /** * get the audio device media locator at index idx * @param idx index of the audio device (as ordered by the JMFRegistry) * @return MediaLocator */ public MediaLocator getAudioMediaLocator(int idx) { return ((CaptureDeviceInfo)audioDevices.get(idx)).getLocator(); } /** * * @param args */ public static void main(String[] args) { DeviceFinder df = new DeviceFinder(); //DEBUG: System.out.println(df.getVideoMediaLocator()); System.out.println(df.getAudioMediaLocator()); } }
+0

在這個例子/示例代碼和幾個步驟上分享一些信息會更好,我也嘗試類似。並正在考慮轉移到JMF或本地訪問? – YumYumYum 2010-12-29 11:24:04

+1

@Stackfan我添加了一些我的代碼,如果這有助於任何人 – user489041 2011-01-12 18:00:26

+0

@ user489041你說「該DLL需要進入win32文件夾」,你的意思是'system32'? – MikeNereson 2011-04-28 19:27:27

回答

4

我不認爲這是一個更好的辦法。除非通過路徑名顯式加載DLL,否則只需確保它們在系統路徑中,因此如果它們居住在JVM可執行文件旁邊,它也應該可以工作。 Windows確實隱含地包含程序從系統路徑啓動的目錄,所以這是另一個潛在的位置。

安裝程序是一把雙刃劍,它們使添加新功能和稍後刪除它變得容易,但它們也使部署使用該產品的解決方案變得更加困難。

一般來說,Java的好處之一就是你不必安裝它就可以工作。從本質上講,一旦您在一個系統上執行JRE的安裝,您可以將其捆綁在一起並將其作爲一個zip文件在另一個系統上使用。 Java不需要顯式註冊DLL,因爲它會根據需要動態加載它們。

+1

這一切都是非常真實的。另一方面,JMF需要安裝。這正是你陳述的原因,''一般來說,Java的好處之一就是你不必安裝它就可以工作。「'我們不希望最終用戶必須安裝其他任何東西爲我們的應用程序工作。如果應用程序作爲applet運行,這也是非常正確的。我們希望能夠在幕後複製文件,並讓所有內容都能正常工作。嘲笑JMF的安裝並不容易。幕後設置了很多屬性。 – user489041 2010-12-10 17:26:43