Wie man Videos mit JMF aufnimmt, ohne JMF zu installieren

Ein Videokonferenzprojekt, an dem ich gearbeitet habe, verwendete JMF, um Video und Audio aufzunehmen und an einen anderen Endpunkt zu übertragen. Ein Problem war, dass mein Team nicht wollte, dass der Benutzer des Produkts JMF installieren muss.

Ich dachte, es könnte sich lohnen, unsere Lösung für dieses Problem mitzuteilen. Es klappt. Es funktioniert gut. Meine Frage an Sie lautet: Hat jemand eine bessere Möglichkeit, dies zu tun?

Umwelt: Windows, XP und höher

JMF für Windows herunterladen

Installieren Sie es auf Ihrem Computer

Lokalisieren Sie die folgendendlls im Ordner system32 nach der Installation von 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

Kopiere dasdlls in einen temporären Ordner

Lokalisieren Sie dasjmf.properties Datei (Suchen Sie auf Ihrem Computer danach) Laden Sie den JMF-Quellcode herunter
inden Sie im Quellcode die folgenden Dateie

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

Erstelle ein Paket; Ich werde es @ nennJMFNoInstallFügen Sie die in Schritt 6 aufgelisteten Dateien hinzuügen Sie diesem Paket eine Klasse namens Main als solche hinzu:

 

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"
        });
    }
}

Dasjmf.propertiesie @ -Datei muss sich in demselben Ordner wie die Klasse befinden, in der sich Ihr @ befindemain -Methode oder derselbe Ordner wie das JAR-Archiv, das das @ enthämain Methode
Dasdlls müssen in das @ gehwin32 Mappe. Sie können Ihr Programm überprüfen lassen, um festzustellen, ob es sich im @ befindewin32 Mappe. Wenn dies nicht der Fall ist, können Sie sie von einem beliebigen Ort kopieren lassen. Dasjmf.properties -Datei wird aktualisiert, wenn dasMain Klasse oben aufgeführt läuft. Sie müssen dies nur einmal ausführen, wenn das Programm zum ersten Mal ausgeführt wird oder wenn der Benutzer neue Aufnahmegeräte hinzufügen möchte. Stellen Sie zum Schluss sicher, dass dasjmf.jar file undjmfcom.jar, das mit dem Windows JMF-Download einhergeht, ist im Klassenpfad enthalten. Du bist gut, an diesem Punkt zu gehen. Die gesamte Funktionalität von JMF, ohne sie tatsächlich installieren zu müssen.

Damit ist wirklich nicht viel Arbeit verbunden, und Sie können es ganz einfach in Ihr benutzerdefiniertes Installationsprogramm integrieren.

Hat jemand einen besseren Weg gefunden, dies zu tun? Es gibt ein paar Fallstricke, wenn Sie dies auf diese Weise tun.

EDIT: Ich dachte, es könnte sich lohnen, einen Teil des Codes, den ich erstellt habe, mit anderen zu teilen. Natürlich müssen Sie es ändern, um mit dem fertig zu werden, was Sie möchten. Es wird wahrscheinlich nicht kompiliert, aber das fehlende Zeug sollte einfach genug sein, um es neu zu erstellen. Aber dachte, es könnte ein guter Ausgangspunkt sein, um Menschen zu helfen. Die Funktion detectCaptureDevices wird wahrscheinlich den meisten Menschen helfen. Ich werde diese Klasse aktualisieren, wenn ich gehe.


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 <br> a vector of attributes
   */
   public Vector getVideoCaptureDevices()
   {
      return  videoDevices;
   }


   /**
   * purpose:  Get information on all audio capture devices on the system
   * @return java.util.Vector <br> 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 <br> the name of the video device
   */
   public String getVideoCaptureDeviceName()
   {
      return ((CaptureDeviceInfo)videoDevices.get(0)).getName();
   }


   /**
   * get the first audio device name
   * @return String <br> 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
   * <br>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());
   }
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage