CentOS 由 JavaCPP 转让 FFMPEG
阅读原文时间:2023年07月16日阅读:3

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

版权声明:本文博主原创文章,博客,未经同意不得转载。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章