本篇文章的前一篇是采用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,但可以通过第三方库如JNative来实现这一目标。本文将详细介绍如何在Java中使用JNative库来调用DLL文件。 首先,理解DLL文件:DLL(Dynamic Link Library)是Windows操作系统中...
在Java中调用DLL(Dynamic Link Library)文件,可以使用Java的本地方法接口(JNI,Java Native Interface)来实现。JNI允许Java程序与本地代码进行交互,从而实现跨平台的功能。
Java调用动态链接库(DLL)是Java编程中一个比较特殊的技术,主要涉及到Java与本地代码的交互。在Windows系统中,DLL(Dynamic Link Library)是实现函数复用的一种方式,它包含了一系列可供其他程序调用的函数或数据...
JNA(Java Native Access)是Java平台上的一个库,它允许Java代码直接调用本机库(如DLL文件)的函数,而无需编写JNI(Java Native Interface)代码。在Spring Boot项目中集成JNA,可以方便地实现Java应用程序对DLL...
#### 第一种方法:Java利用JNA进行调用 **背景介绍:** 为了实现Java与C#之间的交互,一种常用的方式是通过调用C#封装的DLL文件来完成特定功能。这种方法涉及到.NET Framework与Java平台之间的互操作性问题。其中一...
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)加密和解密操作。...
在Java程序中调用DLL(动态链接库)文件通常是通过JNI(Java Native Interface)来实现的,而JNative是JNI的一个封装库,它提供了一种更简洁的方式来调用C/C++编写的本地代码。这篇博客文章可能介绍了如何利用...
假设我们需要编写一个Java程序,该程序调用名为`TestAppSvr.dll`的DLL文件中的`TestConnect()`函数来检测某个应用服务器的状态。`TestConnect()`函数接受三个参数:服务器IP地址、端口号以及是否启用数据压缩,并...
下面将详细介绍这一过程,以及涉及到的jar和dll文件。 Jacob是一个开源项目,它为Java提供了与COM接口交互的能力,允许Java代码直接调用Windows API和OCX控件。Jacob的核心在于一个名为`jacob.jar`的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 ...
以上代码会截取视频的第一帧并保存为指定路径的图片。当然,为了更精确地截取特定帧,你需要解析视频的时长信息,并根据需要调整`-vframes`参数。 总结来说,通过Java后台结合`ffmpeg.jar`,我们可以轻松地实现从...
你需要定义一个接口,该接口的每个方法对应DLL中的一个函数,然后使用`NativeLibrary`类加载DLL,并将接口实例化,这样就可以在Java中直接调用DLL函数了。 1. **基本数据类型**:JNA支持Java的基本数据类型如int、...
而调用DLL(Dynamic Link Library)文件是Windows操作系统中常见的一种技术,允许不同程序共享代码和资源。本案例主要介绍了如何在ABAP环境中调用DLL文件以实现特定功能,比如连接外部数据库读取数据。 首先,我们...
因此,在使用Java和OpenCV从视频文件中获取帧时,需要确保视频文件格式正确并且ffmpeg已安装正确。 Java使用OpenCV从视频文件中获取帧是一个非常有用的技术,它可以应用于很多领域,例如视频监控、图像识别、视频...