Java:CaptureDeviceManager#getDeviceList() 为空?
我试图打印出使用 CaptureDeviceManager 类中的 #getDeviceList() 方法支持的所有捕获设备,并且返回的 Vector 的大小为 0。
这是为什么?我有一个可以使用的网络摄像头 - 所以应该至少有一个。我正在运行 Mac OS X Lion - 使用 JMF 2.1.1e。
谢谢!
I am trying to print out all of the capture devices that are supported using the #getDeviceList() method in the CaptureDeviceManager class and the returned Vector has a size of 0.
Why is that? I have a webcam that works - so there should be at least one. I am running Mac OS X Lion - using JMF 2.1.1e.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
CaptureDeviceManager.getDeviceList(Format format) 未检测到设备。相反,它从 JMF 注册表中读取,即 jmf.properties 文件。它在类路径中搜索jmf.properties文件。
如果您的 JMF 安装成功,那么类路径将被配置为包含所有相关的 JMF jar 和目录。 JMF 安装附带一个 jmf.properties 文件,该文件包含在 JMF 安装目录下的“lib”文件夹中。这意味着 jmf.properties 将由 JMStudio 定位,并且您通常会看到 JMStudio 应用程序正确执行。 (如果您的 JMF 安装在“C:\Program Files”下,则以管理员身份运行以绕过 UAC)
当您创建自己的应用程序来检测设备时,可能会出现上述问题。我看到了一些与同一问题相关的问题。这是因为您的应用程序的类路径可能不同,并且可能不包含环境类路径。在此处查看您的 IDE 的属性。问题是 CaptureDeviceManager 无法找到 jmf.properties 文件,因为它不存在。
正如您所发现的,您可以从 JMF 安装文件夹复制 jmf.properties 文件。它将包含正确的设备列表,因为 JMF 在安装过程中检测到它(无论如何都要检查一下以确保)。
如果您想自己进行设备检测,则创建一个空的 jmf.properties 文件并将其放在类路径中的某个位置(最初在执行过程中可能会抛出 java.io.EOFException,但这由 JMF 类正确处理)。然后使用以下代码来检测网络摄像头...
VFWAuto 类的代码如下所示。这是 JMStudio 源代码的一部分。您可以很好地了解如何检测设备并将其记录在注册表中。测试时将这两个类放在同一个包中。忽略 VFWAuto 类中的 main 方法。
假设您使用的是 Windows 平台并且有一个可用的网络摄像头,那么此代码应该检测设备并填充 jmf.properties 文件。在下次运行时,您还可以注释掉 VFWAuto 部分及其对象引用,并且您可以看到 CaptureDeviceManager 从 jmf.properties 文件中读取。
VFWAuto 类是 jmf.jar 的一部分。您还可以在 JMStudio 示例源代码中查看用于检测音频设备的 DirectSoundAuto 和 JavaSoundAuto 类。按照与 VFWAuto 相同的方式进行尝试。
我的配置是 Windows 7 64 位 + JMF 2.1.1e Windows 性能包 + 网络摄像头。
CaptureDeviceManager.getDeviceList(Format format) does not detect devices. Instead it reads from the JMF registry which is the jmf.properties file. It searches for the jmf.properties file in the classpath.
If your JMF install has succeeded, then the classpath would have been configured to include all the relevant JMF jars and directories. The JMF install comes with a jmf.properties file included in the 'lib' folder under the JMF installation directory. This means the jmf.properties would be located by JMStudio and you would usually see the JMStudio application executing correctly. (If your JMF install is under 'C:\Program Files', then run as administrator to get around UAC)
When you create your own application to detect the devices, the problem you described above might occur. I have seen a few questions related to the same problem. This is because your application's classpath might be different and might not include the environment classpath. Check out your IDE's properties here. The problem is that CaptureDeviceManager cannot find the jmf.properties file because it is not there.
As you have found out correctly, you can copy the jmf.properties file from the JMF installation folder. It would contain the correct device list since JMF detects it during the install (Check it out just to make sure anyway).
If you want do device detection yourself, then create an empty jmf.properties file and put it somewhere in your classpath (it might throw a java.io.EOFException initially during execution but that's properly handled by the JMF classes). Then use the following code for detecting webcams...
The code for the VFWAuto class is given below. This is part of the JMStudio source code. You can get a good idea on how the devices are detected and recorded in the registry. Put both classes in the same package when you test. Disregard the main method in the VFWAuto class.
Assuming you are on a Windows platform and you have a working web-cam, then this code should detect the device and populate the jmf.properties file. On the next run you can also comment out the VFWAuto section and it's object references and you can see that CaptureDeviceManager reads from the jmf.properties file.
The VFWAuto class is part of jmf.jar. You can also see the DirectSoundAuto and JavaSoundAuto classes for detecting audio devices in the JMStudio sample source code. Try it out the same way as you did for VFWAuto.
My configuration was Windows 7 64 bit + JMF 2.1.1e windows performance pack + a web-cam.
我遇到了同样的问题,我通过在
ObjectInputStream
对象上调用flush()
来解决。根据
ObjectInputStream
构造函数的 API 文档:从流中读取包含幻数和版本号的流标头并进行验证。此方法将阻塞,直到相应的 ObjectOutputStream 写入并刷新标头。
当尝试通过套接字双向发送对象时,这是需要注意的非常重要的一点,因为以错误的顺序打开流将导致死锁。
例如,考虑一下如果客户端和服务器在构造相应的
ObjectOutputStream
之前都尝试从套接字的输入流构造ObjectInputStream
会发生什么情况。客户端上的ObjectInputStream
构造函数将阻塞,等待幻数和版本号通过连接到达,而同时服务器端的ObjectInputStream
构造函数将阻塞也因为同样的原因而被阻止。因此,陷入僵局。因此,您应该始终在代码中养成这样的习惯:在打开
ObjectInputStream
之前,首先打开ObjectOutputStream
并刷新它。ObjectOutputStream
构造函数不会阻塞,并且调用flush()
将强制幻数和版本号通过网络传输。如果您在客户端和服务器中都遵循这种做法,则不会出现死锁问题。感谢 Tim Rohaly 和他的解释此处。
I had the same issue and I solved by invoking
flush()
on myObjectInputStream
object.According to the API documentation for
ObjectInputStream
's constructor:The stream header containing the magic number and version number are read from the stream and verified. This method will block until the corresponding
ObjectOutputStream
has written and flushed the header.This is a very important point to be aware of when trying to send objects in both directions over a socket because opening the streams in the wrong order will cause deadlock.
Consider for example what would happen if both client and server tried to construct an
ObjectInputStream
from a socket's input stream, prior to either constructing the correspondingObjectOutputStream
. TheObjectInputStream
constructor on the client would block, waiting for the magic number and version number to arrive over the connection, while at the same time theObjectInputStream
constructor on the server side would also block for the same reason. Hence, deadlock.Because of this, you should always make it a practice in your code to open the
ObjectOutputStream
and flush it first, before you open theObjectInputStream
. TheObjectOutputStream
constructor will not block, and invokingflush()
will force the magic number and version number to travel over the wire. If you follow this practice in both your client and server, you shouldn't have a problem with deadlock.Credit goes to Tim Rohaly and his explanation here.
在调用CaptureDeviceManager.getDeviceList()之前,必须先将可用设备加载到内存中。
您可以在安装 JMF 后通过运行 JMFRegistry 手动执行此操作。
或借助扩展库 FMJ(Java 中的自由媒体)以编程方式执行此操作。这是代码:
这是输出:
Before calling CaptureDeviceManager.getDeviceList(), the available devices must be loaded into the memory first.
You can do it manually by running JMFRegistry after installing JMF.
or do it programmatically with the help of the extension library FMJ (Free Media in Java). Here is the code:
Here is the output: