如何使用JMF捕获video,但不安装JMF
我正在研究的video会议项目使用JMF来捕获video和音频,并将其传输到另一个端点。 问题是我的团队不希望产品的用户必须安装JMF。
我认为分享我们对这个问题的解决方案可能是值得的。 有用。 它运作良好。 我的问题是:有没有人有更好的方法呢?
环境:Windows,XP及以上版本
- 下载适用于Windows的JMF
-
将其安装在您的机器上
-
在jmf安装后,在system32文件夹中找到以下
dll
: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 -
将
dll
复制到临时文件夹中 - 找到
jmf.properties
文件(在您的计算机上搜索它) - 下载JMF源代码
在源代码中,找到以下文件:
JMFinit.java
JMRPropertiesGen.java
Registry.java
RegistryGen.java
- 创建一个包; 我称之为
JMFNoInstall
- 添加步骤6中列出的文件
- 将一个名为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的所有function,而无需实际安装它。
实际上并没有涉及到很多工作,您可以很容易地将它合并到自定义安装程序中。
有没有人找到更好的方法来做到这一点? 这样做有一些陷阱。
编辑:我认为分享我创建的一些代码可能是值得的。 当然你需要修改它来处理你的事情。 它不会编译,但缺少的东西应该很容易重新创建。 但是认为这可能是一个帮助人们的好起点。 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()); } }
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()); } }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()); } }
我不认为有更好的方法。 除非通过路径名显式加载DLL,否则您只需要确保它们位于系统路径中,因此如果它们位于JVM可执行文件旁边,它也应该可以工作。 Windows隐式包含程序从系统路径启动的目录,因此这是另一个潜在的位置。
安装程序是一把双刃剑,它们可以轻松添加新function并在以后删除它,但它们也使得部署使用该产品的解决方案变得更加困难。
一般来说,Java的一个好处是你不必安装它就可以工作。 基本上,一旦在一个系统上执行JRE的安装,您就可以将其捆绑起来并在另一个系统上以zip文件的forms使用它。 Java不需要显式注册DLL,因为它根据需要动态加载它们。