利用JNI实现JAVA插件开发

来源:互联网 发布:乐股软件 编辑:程序博客网 时间:2024/06/05 09:19

本文主要工作在于利用JNI实现对已经完成的视频镜头提取C++程序的调用。

整个过程如下所示:

1)将视频特征提取算法建立相应的windows下的Dll和Linux下的So(这个两个文件大家都知是什么了吧)

2)利用jni调用这些dll。但是有一个问题,就是这里的所有库文件需要打到jar包中,因此需要将这些文件先解压到一个临时文件夹中,然后通过Syste.load加载这些库文件。

如何利用JNI调用C、C++可以看我另一篇文章:http://blog.csdn.net/ididcan/article/details/6828982

下面贴上程序:

VideoUtil.java

package udms.video;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;public class VideoUtil {public static String path = "";static {try{// copy the so file to native temp dirString path = LoadVideoLib.loadLib();// according to different operating system to load the libraryString systemType=System.getProperty("os.name");systemType = systemType.toLowerCase();if(systemType.contains("win")){// windows dynamic link library. (dll)System.load(path+"cv210.dll");System.load(path+"cxcore210.dll");System.load(path+"cxts210.dll");System.load(path+"highgui210.dll");System.load(path+"VideoUtily.dll");}else{// linux share object. (so)System.load(path+"libavutil.so.51");System.load(path+"libswscale.so.2");System.load(path+"libavcodec.so.53");System.load(path+"libavformat.so.53");System.load(path+"libtiff.so");System.load(path+"libcxcore.so.2.1");System.load(path+"libcv.so.2.1");System.load(path+"libml.so.2.1");System.load(path+"libhighgui.so.2.1");System.load(path+"libcvaux.so.2.1");System.load(path+"libcxts.so.2.1");System.load(path+"libVideoUtily.so");}}catch(UnsatisfiedLinkError e){System.err.println("Cannot load VideoUtil.so\n"+e.toString());}}/** * extract the abstract frame from the video return the frame director path * @param fileName * @param abFrameNum * @param timeDisFlag * @return */private native static String getAbstractFrameFromVideo(String fileName,int abFrameNum,int timeDisFlag);/** * extract the abstract frame from the video * @param videoPath the video file path * @param abFrameNum the number of abstract frame * @param timeDisFlag time flag * @return */public static List<String> extractAbstractFrameFromVideo(String videoPath,int abFrameNum,int timeDisFlag){List<String> reFiles=new ArrayList<String>(abFrameNum+1);String allPaths=getAbstractFrameFromVideo(videoPath,abFrameNum,timeDisFlag);StringTokenizer toker=new StringTokenizer(allPaths,"|");while(toker.hasMoreTokens()){reFiles.add(toker.nextToken());}return reFiles;}}


 

LoadVideoLib.java 该类主要是从jar包中将那些库文件解压到本地临时目录中来。有以下几点要注意

就是我在jar包中的库文件夹下放置了info文件,该文件中包含了该目录下的文件名。那么解压的时候先读取该info利用这些文件名,然后把所有该文件夹下的库文件都解压出来。这是一种折中的方式,应该有更好的方式,直接可以读取jar文件夹下的文件名列表。

另,生成info文件的代码也放到这里,可以直接调用。

package udms.video;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;public class LoadVideoLib {/** * write the file name list of the directory to an info file. * @param path directory path */public static void readFileList(String path){try{BufferedWriter bw = new BufferedWriter(new FileWriter(new File(path+"/info")));File dir = new File(path);if(dir.isDirectory()){String[] list = dir.list();for(int i= 0 ;i < list.length; i++)bw.append(list[i]+"\r\n");}bw.close();}catch(Exception e){e.printStackTrace();}}/** * read the info from jar file. the info contain the file name of dll or so according to the os system. * @param infoPath info path in the jar * @return the file name list of dll or so. */public static List<String> readInfo(String infoPath){List<String> list = new ArrayList<String>();// get the info input streamInputStream in = LoadVideoLib.class.getResourceAsStream(infoPath);BufferedReader br = new BufferedReader(new InputStreamReader(in));String str = null;try{// read the list of library file name from info while((str = br.readLine())!=null)list.add(str);br.close();}catch(Exception e){e.printStackTrace();}finally{try{if(br!=null)br.close();}catch(Exception e){e.printStackTrace();}}return list;}/** * load the relate library according to the os system. * @return the directory path of library. */public static String loadLib(){// get the os system nameString systemType=System.getProperty("os.name");systemType = systemType.toLowerCase();// here only support windows and linuxif(systemType.contains("win"))systemType="win";elsesystemType="linux";// judge the bit of os system.String bit = System.getProperty("os.arch");String osType = "";// here only support X86 and X64if(bit.contains("64"))osType = systemType+"64";elseosType = systemType+"32";// read the lib name list from infoList<String> list = readInfo(osType+"/info");// the director path which contains the library.String jarLibDir = osType+"/";// get directory path which store the extracted library store in the jar fileString nativeLibDir = System.getProperty("java.io.tmpdir")+"/"+osType;// extract the library file to the native library directoryInputStream in=null;BufferedInputStream bis = null;BufferedOutputStream bos = null;for(String libName : list){// create a native directory to store the libraryFile libDir = new File(nativeLibDir);if(!libDir.exists())libDir.mkdir();// create the extracted library fileFile extractedLibFile=new File(nativeLibDir+"/"+libName);if(!extractedLibFile.exists()){try{in=LoadVideoLib.class.getResourceAsStream(jarLibDir+libName);bis = new BufferedInputStream(in);bos = new BufferedOutputStream(new FileOutputStream(extractedLibFile));byte[] data = new byte[bis.available()];bis.read(data);bos.write(data);bis.close();bos.close();}catch(IOException ioe){ioe.printStackTrace();}finally{try{if(bis!=null)bis.close();if(bos!=null)bos.close();}catch(Exception e){e.printStackTrace();}}}}// return the directory path which contains the library.return nativeLibDir+"/";}}


如有疑问请留言

 

原创粉丝点击