14

私が取り組んでいたビデオ会議プロジェクトでは、JMFを使用してビデオとオーディオをキャプチャし、それを別のエンドポイントに送信しました。問題は、私のチームが製品のユーザーにJMFをインストールさせたくないということでした。

この問題に対する私たちの解決策を共有することは価値があるかもしれないと思いました。できます。それはうまくいきます。あなたへの私の質問は:誰かがそれをするより良い方法を持っていますか?

環境:Windows、XP以降

  1. JMFforWindowsをダウンロードする
  2. マシンにインストールします

  3. dlljmfのインストール後、system32フォルダーで次のを見つけます。

    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を一時フォルダにコピーします

  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同じフォルダー、またはメソッドを含むJARアーカイブと同じフォルダーに配置する必要がありますmain
はフォルダdllに入る必要があります。プログラムに、それらがフォルダ内win32にあるかどうかを確認させることができます。win32そうでない場合は、どこかからコピーしてもらうことができます。上記のクラスが実行jmf.propertiesされるたびに、ファイルが更新されます。Mainこれを実行する必要があるのは、プログラムを初めて実行するとき、またはユーザーが新しいキャプチャデバイスを追加する場合に1回だけです。最後に、jmf.jarファイルとjmfcom.jarこれは、WindowsJMFのダウンロードに付属しています。クラスパスに含まれています。この時点で行ってもいいです。実際にインストールしなくても、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()); } }
4

1 に答える 1

4

より良い方法はないと思います。DLL がパス名で明示的にロードされない限り、DLL がシステム パスにあることを確認するだけでよいので、JVM 実行可能ファイルのすぐ隣にある場合は、DLL も機能するはずです。Windows では、プログラムが開始されたディレクトリが暗黙的にシステム パスに含まれているため、別の潜在的な場所になります。

インストーラーは諸刃の剣です。新しい機能を簡単に追加したり、後で削除したりできますが、製品を使用するソリューションの展開も難しくなります。

Java の一般的な利点の 1 つは、Java をインストールする必要がないことです。基本的に、あるシステムで JRE のインストールを実行すると、それをバンドルして別のシステムで zip ファイルとして使用できます。Java は必要に応じて動的に DLL をロードするため、DLL を明示的に登録する必要はありません。

于 2010-12-10T17:19:11.380 に答える