`
suigara
  • 浏览: 80611 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java 使用JNA连接天敏VC4000采集卡

    博客分类:
  • java
阅读更多

突然发现自己快成了专门调硬件的了

 

 

废话不多说了,正题开始

使用的库

1.官方的两个dll(Mix.dll,Sa7134Capture.dll),可能对应不同版本,我这是6.0的,附件里有

2.jna的jar包,注意是两个

   jna.jar,jna-platform.jar 

以上都在本文后面提供下载

 

关键代码

首先是jna的代理,不明白的看下jna怎么用,这里定义dll存在的且你需要的函数就可以了

package xingyang.meam.video;

import java.io.File;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.win32.StdCallLibrary;

/**
 * 
 * 视频显示设备
 * 
 * @author Administrator
 * 
 */
public interface CaptureDevice extends StdCallLibrary {

	File f = new File("");

	CaptureDevice INSTANCE = (CaptureDevice) Native.loadLibrary(
			f.getAbsolutePath() + "\\Sa7134Capture", CaptureDevice.class);

	/**
	 * 该函数用于初始化开发包。在使用SDK开发包中的函数前,首先需要调用该函数进行初始化。
	 * 
	 * @param hwnd
	 *            表示视频显示多路小窗口的父窗口。
	 * @param eDispTransType
	 *            表示显示类型。
	 * @param bLnitAuDev
	 *            表示是否初始化音频设备。
	 * @return
	 */
	public boolean VCAInitSdk(HWND hwnd);

	/**
	 * 该函数用于释放调用VCAInitSdk函数分配的系统资源,通常在程序结束时调用该函数。
	 */
	public void VCAUnInitSdk();

	/**
	 * 该函数用于获得监控卡中芯片的数量。通常,监控卡支持多少路视频,将会存在多少个芯片。
	 * 
	 * @return 表示系统中安装监控卡上的芯片数量。
	 */
	public int VCAGetDevNum();

	/**
	 * 该函数用于打开指定卡号的设备,并分配相应的系统资源。
	 * 
	 * @param dwCard
	 *            表示视频捕捉的卡号。
	 * @param hPreviewWnd
	 *            表示视频预览窗口句柄。
	 * @return
	 */
	public boolean VCAOpenDevice(int dwCard, HWND hPreviewWnd);

	/**
	 * 该函数用于关闭指定卡号的设备,释放相应系统资源。
	 * 
	 * @param dwCard
	 *            表示视频捕捉的卡号。
	 * @return
	 */
	public boolean VCACloseDevice(int dwCard);

	/**
	 * 该函数用于打开视频预览窗口。
	 * 
	 * @param dwCard
	 *            表示预览的视频卡号。
	 * @return
	 */
	public boolean VCAStartVideoPreview(int dwCard);

	/**
	 * 该函数用于停止视频预览。
	 * 
	 * @param dwCard
	 *            表示预览的视频卡号。
	 * @return
	 */
	public boolean VCAStopVideoPreview(int dwCard);

	/**
	 * 该函数用于更新视频预览窗口。当预览窗口的父窗口大小或位置改变时,需要调用该函数进行调整。
	 * 
	 * @param hOverlayWnd
	 *            表示预览窗口的父窗口。
	 * @return
	 */
	public boolean VCAUpdateOverlayWnd(HWND hOverlayWnd);

	/**
	 * 该函数用于更新视频预览窗口。当预览窗口的大小和位置需要调整时调用该函数。通常,在调用该函数前,需要调用VCAUpdateOverlayWnd函数。
	 * 
	 * @param dwCard
	 *            表示预览的视频卡号。
	 * @param hPreviewWnd
	 *            表示视频预览窗口。
	 * @return
	 */
	public boolean VCAUpdateVideoPreview(int dwCard, HWND hPreviewWnd);
}

 

主类

package xingyang.meam.video;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.io.IOException;
import java.util.Properties;

import javax.swing.JFrame;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;

public class VideoMain {
	public static void main(String[] args) {
		Properties p = new Properties();
		try {
			p.load(VideoMain.class.getResourceAsStream("/config.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		String[] cardNos = p.getProperty("cardNumbers", "0,1,2,3").trim()
				.split(",");
		// int type = Integer.parseInt(p.getProperty("type"));

		JFrame jf = new JFrame();
		Panel parent = new Panel();
		parent.setPreferredSize(new Dimension(660, 500));
		jf.add(parent);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		parent.setLayout(new FlowLayout());
		Panel panels[] = new Panel[cardNos.length];
		for (int i = 0; i < panels.length; i++) {
			Panel cardPanel = new Panel();
			cardPanel.setPreferredSize(new Dimension(320, 240));
			cardPanel.setBackground(new Color(255, 0, 255));
			parent.add(cardPanel);
			panels[i] = cardPanel;
		}
		jf.pack();
		jf.setVisible(true);

		boolean success = CaptureDevice.INSTANCE
				.VCAInitSdk(createHWNDByComponent(parent));
		if (!success) {
			System.out.println("init = " + success);
		}
		for (int i = 0; i < panels.length; i++) {
			Panel cardPanel = panels[i];
			HWND hwnd = createHWNDByComponent(cardPanel);
			int cardNo = Integer.parseInt(cardNos[i]);
			System.out.println("cardNo = " + cardNo);
			boolean isopen = CaptureDevice.INSTANCE.VCAOpenDevice(cardNo, hwnd);
			if (!isopen) {
				System.out.println("isopen = " + isopen);
			}
			boolean isstart = CaptureDevice.INSTANCE
					.VCAStartVideoPreview(cardNo);
			if (!isstart) {
				System.out.println("isstart = " + isstart);
			}
			// CaptureDevice.INSTANCE
			// .VCAUpdateOverlayWnd(createHWNDByComponent(parent));
			// CaptureDevice.INSTANCE.VCAUpdateVideoPreview(cardNo, hwnd);
		}
		// CaptureDevice.INSTANCE
		// .VCAUpdateOverlayWnd(createHWNDByComponent(parent));

	}

	private static HWND createHWNDByComponent(Component parent) {
		return new HWND(Native.getComponentPointer(parent));
	}
}

 这里有个变态的是,就是小panel(显示视频的panel)的背景色不能随便设,得设成粉色(255,0,255)才行,否则。。明明返回的都是true,就是不显示画面。。

 

还有个注意的地方,Native.getComponentPointer的参数得是重量级的不能用轻量级的

也就是awt的,别用swing的

其他就没啥了

 

发现jna果然是个神器。。。。,否则写JNI。。。想想都头疼

 

附件是java工程,导入eclipse,直接运行

 

分享到:
评论
3 楼 flyong86 2014-09-16  
哎~~终于搞对了,原来有个程序占用了视频采集卡

但是调用VCAStartVideoPreview后还是没有图像
2 楼 flyong86 2014-09-16  
在Win7 64位看了这些dll都有,而且运行的时候init正常调用只是没得采集卡等,返回false

在Win XP上在system32里面的确没有发现这些dll
1 楼 flyong86 2014-09-16  
有些郁闷,在Win7 64位系统运行没问题,但是这个机器没安装视频采集卡等
另外一台机器Win XP 32位系统一直提示java.lang.UnsatisfiedLinkError: Unable to load library,一直不识别动态库,看了路径对的,用Dependency Walker看dll依赖,发现缺少IESHIMS.DLL与WER.DLL,下载了这两个dll,又缺少其它的,又下载提示缺少的dll,感觉就是无底洞一样,又提示缺少某某dll

相关推荐

Global site tag (gtag.js) - Google Analytics