本篇文章的前一篇是采用FFmpeg解帧,并保持到JPG格式文件,其中使用了main函数对视频进行了解帧,本篇将针对Java如何调用来实现解帧并输出到文件。
一、使用VS2010将其改为Dll输出时,需要改变以下项目属性设置:
1、常规设置
2、库目录设置
3、预编译头设置
4、预处理设置
_INTEL WIN32 _DEBUG _CONSOLE _Windows _CRT_SECURE_NO_DEPRECATE
二、基于上篇文章代码我们添加如下函数声明以及实现
_declspec(dllexport) int findFKeyFrame(char *videoFilePath, char *frameFile); int findFKeyFrame(char *videoFilePath, char *frameFile) { AVFormatContext *pFormatCtx = NULL; int i,videoStream; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame; AVFrame *pFrameRGB; int numBytes; uint8_t *buffer; AVPacket packet; int frameFinished; struct SwsContext *img_convert_ctx = NULL; av_register_all(); // 检查参数以及视频能否解码 if(avformat_open_input(&pFormatCtx, videoFilePath, NULL, NULL)!=0) { printf("can not open"); return -1; } if(avformat_find_stream_info(pFormatCtx, NULL) < 0) { printf("can not find"); return -1; } av_dump_format(pFormatCtx, -1, videoFilePath, 0); videoStream = -1; for (i=0;i<pFormatCtx->nb_streams;i++) { if( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoStream = i; break; } } if ( videoStream == -1 ) { printf("not find videoStream"); return -1; } pCodecCtx = pFormatCtx->streams[videoStream]->codec; pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if ( pCodec == NULL ) { return -1; } if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0 ) { return -1; } pFrame = av_frame_alloc(); if( pFrame == NULL ) { return -1; } pFrameRGB = av_frame_alloc(); if( pFrameRGB == NULL ) { return -1; } // 根据视频宽高设置帧大小 numBytes = avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height); buffer = av_malloc(numBytes); avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); img_convert_ctx = sws_getCachedContext(img_convert_ctx, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); i = 0; while( av_read_frame(pFormatCtx, &packet) >= 0 ) { if( packet.stream_index == videoStream ) { avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); if ( frameFinished && pFrame->key_frame) { if (!img_convert_ctx ) { fprintf(stderr, "Cannot initialize sws conversion context\n"); exit(1); } sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); if(i++<1) { saveFrameJpg(pFrameRGB->data[0],frameFile, i, pCodecCtx->width, pCodecCtx->height); } } } if(i > 5) { break; } } av_free_packet(&packet); av_free(buffer); av_free(pFrame); av_free(pFrameRGB); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 1; }
编译项目,生成DLL,并拷贝其到Java调用类目录下。
三、编写Java代码调用DLL
Java调用dll,肯定会用到JNI,但是此处使用比较常用地JNA框架来调用。JNA相关链接
可从test包可以查看怎么使用指针类Pointer等等
JNA代码实现如下:
package com.xiva.test.pic; import java.io.UnsupportedEncodingException; import com.sun.jna.Library; import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; /** * * <调用DLL读取视频的第一关键帧,并以JPG格式输出到文件> * @author xiva * @version [1.0, 2014-5-15] * @see [相关类/方法] * @since [产品、模块版本] */ public class ReadVideoKeyFrame { public interface VideoDecoder extends Library { /** * 当前路径是在项目下,而不是bin输出目录下。 */ VideoDecoder INSTANCE = (VideoDecoder) Native.loadLibrary("VideoDecoder", VideoDecoder.class); public NativeLong findFKeyFrame(Pointer videoFilePath, Pointer frameFile); } public static void main(String[] args) throws UnsupportedEncodingException { final String ENCODING = "utf8"; String fileName = "E:\\frame01.jpg"; String path = "E:\\zookeeper.avi"; Pointer videoFilePath = new Memory(path.getBytes(ENCODING).length+1); Pointer frameFile = new Memory(fileName.getBytes(ENCODING).length+1); videoFilePath.setString(0, path); frameFile.setString(0, fileName); NativeLong ret = VideoDecoder.INSTANCE.findFKeyFrame(videoFilePath, frameFile); System.out.println(ret); } }
运行程序,可以看到解帧成功。
同样此处还是未解决如何集成其他地解码器,毕竟ffmpeg地解码能力有限;需要后续再次扩展。
相关推荐
Java调用动态链接库(DLL)是Java编程中一个比较特殊的技术,主要涉及到Java与本地代码的交互。在Windows系统中,DLL(Dynamic Link Library)是实现函数复用的一种方式,它包含了一系列可供其他程序调用的函数或数据...
Java调用DLL是Java开发中一个重要的技术主题,它允许Java程序与本地操作系统API或者其他C/C++编写的动态链接库进行交互。在Java中,有多种方法可以实现这个功能,其中最常用的是Java Native Interface (JNA) 和 ...
Java调用Qt DLL是一个跨平台的技术实践,涉及到Java与C++之间的互操作性,其中Qt是一个流行的C++库,主要用于图形用户界面开发。这个主题主要包含以下几个知识点: 1. **JNI(Java Native Interface)**:JNI是Java...
`JNative-1.3.2`是一个开源组件,专门设计用于帮助Java应用程序调用Windows平台上的DLL(动态链接库)文件,同时也支持Linux平台下的SO(共享对象)文件。下面我们将详细介绍这个组件的使用方法、工作原理及相关知识...
Java调用C++ DLL文件是跨语言编程中的一个重要应用场景,特别是在既有Java代码库又有C++动态链接库的情况下。本文将详细讲解如何在Java程序中调用C++编写的DLL文件,以及一个可用的示例。 首先,理解Java与C++交互...
在 JAVA 中,我们可以使用 System.LoadLibrary 方法来加载我们的 DLL 文件,并使用 System.Runtime.InteropServices.DllImportAttribute 属性来调用我们的 DLL 文件。 public class Main { public native String ...
在IT行业中,有时我们需要在Java程序中使用非Java编写的库,例如DLL(动态链接库)文件,这在Windows环境中非常常见。本话题主要聚焦于如何在Java中调用DLL来实现DES(Data Encryption Standard)加密和解密操作。...
1、Labview生成Dll文件 2、Java通过Jnative第三方Jar包调用Labview生成的DLL文件 3、Java在Windows系统调用Labview生成的Dll的说明 有JNative的使用说明 直接下载,根据使用说明可以直接使用。
在Java程序中调用DLL(动态链接库)文件通常是通过JNI(Java Native Interface)来实现的,而JNative是JNI的一个封装库,它提供了一种更简洁的方式来调用C/C++编写的本地代码。这篇博客文章可能介绍了如何利用...
假设我们需要编写一个Java程序,该程序调用名为`TestAppSvr.dll`的DLL文件中的`TestConnect()`函数来检测某个应用服务器的状态。`TestConnect()`函数接受三个参数:服务器IP地址、端口号以及是否启用数据压缩,并...
在Java中调用DLL(Dynamic Link Library)文件,可以使用Java的本地方法接口(JNI,Java Native Interface)来实现。JNI允许Java程序与本地代码进行交互,从而实现跨平台的功能。
Java本身并不直接支持DLL调用,但通过一些第三方库,我们可以实现这样的功能。本示例以"Java调用DLL例子"为主题,使用了JNative库作为接口来实现Java调用本地动态链接库。 JNative是一个开源的Java库,它提供了一种...
在IT行业中,有时我们需要在Java程序中调用第三方的DLL(动态链接库)文件,这通常是C或C++编写的库。Java Native Access (JNA) 是一个流行的开源框架,它允许Java代码直接调用本机库函数,而无需编写JNI(Java ...
Java本身不直接支持加载和调用本地库(如DLL),但是可以通过第三方库来实现。 描述中的“导入jna.jar将MaskKey.dll放到主目录下。执行zyl.java就可以了。”说明了实现这一功能的具体步骤: 1. **jna.jar**:Java ...
你需要定义一个接口,该接口的每个方法对应DLL中的一个函数,然后使用`NativeLibrary`类加载DLL,并将接口实例化,这样就可以在Java中直接调用DLL函数了。 1. **基本数据类型**:JNA支持Java的基本数据类型如int、...
因此,在使用Java和OpenCV从视频文件中获取帧时,需要确保视频文件格式正确并且ffmpeg已安装正确。 Java使用OpenCV从视频文件中获取帧是一个非常有用的技术,它可以应用于很多领域,例如视频监控、图像识别、视频...
Java DLL文件调用是将Java程序与本地C/C++库集成的关键步骤,这对于利用Java的跨平台特性同时利用原生库的功能至关重要。在Java中,我们通常使用Java Native Interface (JNI)来实现对DLL文件的调用。下面将详细介绍...
在本文中,我们将深入探讨如何使用Java程序调用FFmpeg执行视频文件格式转换,特别是将非FFmpeg原生支持的格式转换为FLV格式。FFmpeg是一个强大的多媒体处理工具,支持多种视频、音频格式的编码、解码和转换。在这个...
本文将基于提供的“java调用dll实例代码”,深入探讨如何在Java中集成DLL,包括关键步骤、涉及技术以及具体实现细节。 #### 核心概念:JNI与DLL - **JNI(Java Native Interface)**:是Java平台标准的一部分,它...