设为首页 收藏本站
查看: 455|回复: 0

[经验分享] CentOS 下通过 JavaCPP 调用 FFMPEG

[复制链接]

尚未签到

发表于 2016-5-10 09:38:33 | 显示全部楼层 |阅读模式
1. Java 与 FFMPEG
   FFMPEG 是一个广泛用于媒体处理的库,在Java的世界里,处理视频的能力相当弱,于是有很大需求需要Java 调用 FFMPEG。
    Java 调用C 的方式有很多,可以用最原始的JNI方式,也可以JNA方式,还可以是命令行。
   采用命令行的方式比较简单,不过有很大局限性,尤其是涉及到 视频的处理和分析的时候,比如要取出某个packet,然后进行处理。
   
    这里介绍的是用JavaCPP 调用 ffmpeg 库的方式,而不是命令行模式。

     JavaCPP的源码在这里:https://github.com/bytedeco/javacpp 
 
  基于JavaCPP的项目   
1)JavaCV,是做图形图像的,有人脸识别、增强现实AR 等开源算法,非常不错
      项目主页是:https://github.com/bytedeco/javacv 
  
 2)JavaAV 封装了FFMPEG的java 接口
    项目主页:https://github.com/hoary/JavaAV
 
2.  JavaCPP Presets

  为了方便使用,JavaCPP下面有个presets项目,主页是 https://github.com/bytedeco/javacpp-presets,将一些常用的项目都编译好了以方便使用。
    集成的项目包括:
· OpenCV 2.4.9 http://opencv.org/downloads.html
· FFmpeg 2.3.x http://ffmpeg.org/download.html
· FlyCapture 2.6.x http://ww2.ptgrey.com/sdk/flycap
· libdc1394 2.1.x or 2.2.x http://sourceforge.net/projects/libdc1394/files/
· libfreenect 0.5 https://github.com/OpenKinect/libfreenect
· videoInput 0.200 https://github.com/ofTheo/videoInput/tree/update2013
· ARToolKitPlus 2.3.0 https://launchpad.net/artoolkitplus
· flandmark 1.07 http://cmp.felk.cvut.cz/~uricamic/flandmark/#download
· FFTW 3.3.4 http://www.fftw.org/download.html
· GSL 1.16 http://www.gnu.org/software/gsl/#downloading
· LLVM 3.4.2 http://llvm.org/releases/download.html
· Leptonica 1.71 http://www.leptonica.org/download.html
· Tesseract 3.03-rc1 https://code.google.com/p/tesseract-ocr/

    包含的平台有:   android-arm, android-x86, linux-x86, linux-x86_64, macosx-x86_64, windows-x86, windows-x86_64,

  但需要注意:这里的 linux-x86_64 是 基于Fedora 平台的,无法在 CentOS下使用。

 
3. 在CentOS下编译
  1)安装JDK
  2)安装 apache-maven 2/3

  3) 安装 gcc,gcc+,gcc-c++,yasm
     yum -y install yasm gcc+ gcc-c++

  4)  获取源码

     git clone http://github.com/bytedeco/javacpp-presets
  5)  编译 ffmpeg 


     cd javacpp-presets/
    ./cppbuild.sh -platform linux-x86_64 install ffmpeg 


  6) 编译 jni 和 相关jar


      mvn install --projects ffmpeg

 
   7) 编译完成后,会在 ffmpeg 的lib上生成相关 .so ,javacpp-presets/targets 下生成相关的jar

 
4. 测试
   1) 将相关的 .so 复制到 /lib64 目录下,或者通过 -Djava.library.path 指定到.so 所在目录
   2) 拷贝一个实例用来测试,  


public class Tutorial01 {  
static void SaveFrame(AVFrame pFrame, int width, int height, int iFrame)  
throws IOException {  
// Open file  
OutputStream stream = new FileOutputStream("frame" + iFrame + ".ppm");  
// Write header  
stream.write(("P6\n" + width + " " + height + "\n255\n").getBytes());  
// Write pixel data  
BytePointer data = pFrame.data(0);  
byte[] bytes = new byte[width * 3];  
int l = pFrame.linesize(0);  
for (int y = 0; y < height; y++) {  
data.position(y * l).get(bytes);  
stream.write(bytes);  
}  
// Close file  
stream.close();  
}  
public static void main(String[] args) throws IOException {  
AVFormatContext pFormatCtx = new AVFormatContext(null);  
int i, videoStream;  
AVCodecContext pCodecCtx = null;  
AVCodec pCodec = null;  
AVFrame pFrame = null;  
AVFrame pFrameRGB = null;  
AVPacket packet = new AVPacket();  
int[] frameFinished = new int[1];  
int numBytes;  
BytePointer buffer = null;  
AVDictionary optionsDict = null;  
SwsContext sws_ctx = null;  
if (args.length < 1) {  
args = new String[] { "/root/test.ts" };  
// System.out.println("Please provide a movie file");  
// System.exit(-1);  
}  
// Register all formats and codecs  
av_register_all();  
// Open video file  
if (avformat_open_input(pFormatCtx, args[0], null, null) != 0) {  
System.exit(-1); // Couldn't open file  
}  
// Retrieve stream information  
if (avformat_find_stream_info(pFormatCtx, (PointerPointer) null) < 0) {  
System.exit(-1); // Couldn't find stream information  
}  
// Dump information about file onto standard error  
av_dump_format(pFormatCtx, 0, args[0], 0);  
// Find the first video stream  
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) {  
System.exit(-1); // Didn't find a video stream  
}  
// Get a pointer to the codec context for the video stream  
pCodecCtx = pFormatCtx.streams(videoStream).codec();  
// Find the decoder for the video stream  
pCodec = avcodec_find_decoder(pCodecCtx.codec_id());  
if (pCodec == null) {  
System.err.println("Unsupported codec!");  
System.exit(-1); // Codec not found  
}  
// Open codec  
if (avcodec_open2(pCodecCtx, pCodec, optionsDict) < 0) {  
System.exit(-1); // Could not open codec  
}  
// Allocate video frame  
pFrame = av_frame_alloc();  
// Allocate an AVFrame structure  
pFrameRGB = av_frame_alloc();  
if (pFrameRGB == null) {  
System.exit(-1);  
}  
// Determine required buffer size and allocate buffer  
numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx.width(),  
pCodecCtx.height());  
buffer = new BytePointer(av_malloc(numBytes));  
sws_ctx = sws_getContext(pCodecCtx.width(), pCodecCtx.height(),  
pCodecCtx.pix_fmt(), pCodecCtx.width(), pCodecCtx.height(),  
AV_PIX_FMT_RGB24, SWS_BILINEAR, null, null,  
(DoublePointer) null);  
// Assign appropriate parts of buffer to image planes in pFrameRGB  
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset  
// of AVPicture  
avpicture_fill(new AVPicture(pFrameRGB), buffer, AV_PIX_FMT_RGB24,  
pCodecCtx.width(), pCodecCtx.height());  
// Read frames and save first five frames to disk  
i = 0;  
while (av_read_frame(pFormatCtx, packet) >= 0) {  
// Is this a packet from the video stream?  
if (packet.stream_index() == videoStream) {  
// Decode video frame  
avcodec_decode_video2(pCodecCtx, pFrame, frameFinished, packet);  
// Did we get a video frame?  
if (frameFinished[0] != 0) {  
// Convert the image from its native format to RGB  
sws_scale(sws_ctx, pFrame.data(), pFrame.linesize(), 0,  
pCodecCtx.height(), pFrameRGB.data(),  
pFrameRGB.linesize());  
// Save the frame to disk  
if (++i <= 5) {  
SaveFrame(pFrameRGB, pCodecCtx.width(),  
pCodecCtx.height(), i);  
}  
}  
}  
// Free the packet that was allocated by av_read_frame  
av_free_packet(packet);  
}  
// Free the RGB image  
av_free(buffer);  
av_free(pFrameRGB);  
// Free the YUV frame  
av_free(pFrame);  
// Close the codec  
avcodec_close(pCodecCtx);  
// Close the video file  
avformat_close_input(pFormatCtx);  
System.exit(0);  
}  
}  
 4)运行实例,得到输出结果:
     
Input #0, mpegts, from '/root/test.ts':
  Duration: 00:03:20.02, start: 0.056778, bitrate: 1455 kb/s
  Program 1
    Metadata:
      service_name    : jVideo
      service_provider: jTeam
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p, 960x540 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x101]: Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 66 kb/s
  原文:http://blog.csdn.net/maoxiang/article/details/38388387

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-215019-1-1.html 上篇帖子: CentOS 下通过 JavaCPP 调用FFMpeg 下篇帖子: CentOS 5.5 安装记录
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表