JavaCpp之FFMPEG实战教程

1.文章介绍

最近在业务扩展方面需要接触FFMPEG,借此机会学习点FFMPEG知识,由于大部分工作时间和Android应用层,Framework层和芯片SDK层打交道,自然而然看到JavaCpp这种能提高工作效率的框架,两眼发亮并想可以做些什么,这就是写本篇文章的缘由。
另外,了解JavaCpp的同学应该也有不少,但我自己搜在Android上使用的相关教程却很少很少,于是就自己从零开始记录下实战作为参考。
如网上说的做FFMPEG的人分为两种:一种是懂些皮毛,指令,却没有很好的入门学习方法的开发者;一种是熟悉FFMPEG各个模块,并且可以按照业务需求优化和扩展的大神。我只是第一种,甚至还算不上第一种。

2.干货

1.编译准备过程

1.环境搭建

Ubuntu16.04
Ubuntu的搭建这里就不作介绍了,主要是需要配置好网络环境,Maven编译过程中会根据pom.xml中的依赖去中央仓库下载对应的依赖库,本文使用的是ubuntu-16.04-desktop-amd64.iso

JDK环境配置
下载如 jdk-7u45-linux-x64.tar.gz
解压后jdk库文件后,配置jdk环境:

vim /etc/environment 

添加以下代码:

  update-alternatives --install /usr/bin/java java /usr/lib/jvm/java/jdk1.7.0_45/bin/java 300      
  update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java/jdk1.7.0_45/bin/javac 300   
  update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/java/jdk1.7.0_45/bin/jar 300    
  update-alternatives --config java
  update-alternatives --config javac
  update-alternatives --config jar

或通过配置环境变量命令:

$sudo gedit ~/.bashrc

添加以下代码:

export JAVA_HOME=/usr/lib/jvm/java/jdk1.7.0_45   
export JRE_HOME=${JAVA_HOME}/jre  
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib  
export PATH=${JAVA_HOME}/bin:$PATH

通过以下指令校验jdk信息:

  java -version

maven 3.0 or laster

sudo apt-get install maven

安装完后查看版本是否达到要求,如果版本比较低建议去官网下载对应版本后手动配置安装

mvn -v
maven版本信息

cmake 2.8.8 or laster

sudo apt-get install cmake

安装完后查看版本是否达到要求,如果版本比较低建议去官网下载对应版本后手动配置安装

cmake --version
cmake版本信息

svn安装

sudo apt-get install subversion

2.javacpp的下载和编译:

1.我选择了tag版本,tag版本应该稳定些
在github上找到对应tag版本地址:



复制项目地址,然后下载对应源码:
个人习惯问题,我使用的是svn,先去Repository svn地址:



然后选择tag的svn地址checkout:
svn checkout  https://github.com/bytedeco/javacpp.git/tags/1.3.3 /home/yang/share/javacpp-133

源码下载成功后,就可以通过Maven编译了(前提是安装了Maven,未安装的可以根据提示sudo apt-get install maven安装),在下载代码的根目录下执行编译:

mvn install

编译成功后的target目录:



其中:
javacpp.jar是javacpp核心文件,可以说是java-cpp联系的桥梁,处理jar到so的接口实现
javacpp-javadoc.jar是javacpp api doc文件
javacpp-source.jar是对src目录的编译文件暂时不清楚用途

3.javacpp-ffmpeg的下载和编译:

javacpp-ffmpeg的源码在javacpp-presets下:
https://github.com/bytedeco/javacpp-presets


同样的也是选择了tag版本,使用svn下载代码:

svn checkout  https://github.com/bytedeco/javacpp-presets.git/tags/1.3 /home/yang/share/javacpp-presets-13

如果选择的是Android版本的编译,需要先准备NDK环境,否则编译过程中会因为找不到NDK配置而导致中断:
从javacpp_presets根目录的cppbuild.sh中可以看到以下源码

if [[ -z ${OPERATION:-} ]]; then
    echo "Usage: ANDROID_NDK=/path/to/android-ndk/ bash cppbuild.sh [-platform <name>] <install | clean> [projects]"
    echo "where possible platform names are: android-arm, android-x86, linux-x86, linux-x86_64, macosx-x86_64, windows-x86, windows-x86_64, etc."
    exit 1
fi

if [[ -z ${ANDROID_NDK:-} ]]; then
    ANDROID_NDK=~/Android/android-ndk/
fi
export ANDROID_NDK
export ANDROID_CPP="$ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/4.9/"
case $PLATFORM in
    android-x86)
        export ANDROID_BIN="$ANDROID_NDK/toolchains/x86-4.9/prebuilt/$KERNEL-$ARCH/bin/i686-linux-android"
        export ANDROID_ROOT="$ANDROID_NDK/platforms/android-14/arch-x86/"
        ;;
    *)
        export ANDROID_BIN="$ANDROID_NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/$KERNEL-$ARCH/bin/arm-linux-androideabi"
        export ANDROID_ROOT="$ANDROID_NDK/platforms/android-14/arch-arm/"
        ;;
esac

而从javacpp_presets根目录的pom.xml中可以看到这样的源码:

<profile>
      <id>android-arm-default</id>
      <activation>
        <property>
          <name>javacpp.platform</name>
          <value>android-arm</value>
        </property>
      </activation>
      <properties>
        <javacpp.platform>android-arm</javacpp.platform>
        <javacpp.platform.root>${user.home}/Android/android-ndk/</javacpp.platform.root>
        <javacpp.platform.compiler>toolchains/arm-linux-androideabi-4.9/prebuilt/${os.name}-${os.arch}/bin/arm-linux-androideabi-g++</javacpp.platform.compiler>
      </properties>
    </profile>

因此,可以下载android-ndk-r14b-linux-x86_64.zip,并且配置NDK环境为/root/Android/android-ndk:


ndk配置路径

编译环境准备好后,即可在javacpp_presets根目录用以下指令开始编译:

mvn install -Pandroid-arm-default --projects ffmpeg -X

编译过程中某些依赖库找不到的原因可能是SSL或被墙了,需要手动下载对应的库,放置到cppbuild目录:


Maven编译通过后会在ffmpeg目录下生成一个target文件夹:


target目录结构

其中:
ffmpeg.jar是JavaCpp编译出的java api
ffmpeg-android-arm.jar是打包了所有ffmepg so及其jni库的jar包,参考下图:


ffmpeg-android-arm库

ffmpeg-javadoc.jar是JavaCpp根据注解编译的java api doc
ffmpeg-sources.jar是ffmpeg\src目录的编译,具体有什么作用有待查证

编译成功后,必须要做点什么,否则没有任何意义:
1.创建一个Android工程



其中把编译出的ffmpeg.jar和target\classes\lib\armeabi目录下的所有so拷贝到工程的libs目录下(不能直接使用ffmpeg-android-arm.jar是因为Android对so的校验机制,目前没有尝试去解决这种问题,如果有办法解决可以留言告诉我)


直接使用ffmpeg-android-arm.jar

target/classes/lib/armeabi目录下的所有库文件

2.创建测试类
通过一个最简单的测试类,测试JavaCpp FFMPEG的可用性:

package com.example.ffmepgtest;

import org.bytedeco.javacpp.avcodec;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;

public class MainActivity extends Activity {
    public static final String TAG = MainActivity.class.getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        onTest();
    }
    
    public void onTest(){
        Log.d(TAG, " "+avcodec.avcodec_configuration().getString());
    }
}
程序运行最终结果

可以看到,程序运行后可以调用libavcodec打印出FFmpeg的配置信息。说明通过JAVACPP技术在应用层调用FFMPEG(非指令途径调用FFMPEG)省去了JNI代码的编写,这对应用开发者来说是个多么好的消息。

3.结束语

使用JavaCpp FFMPEG这种框架方式,就好像打开了某道门,让应用开发省去了JNI开发成本,比如Tensorflow,Videoinput等开源库,在应用需要使用这些框架时,使用javacpp就能极大的减少应用开发周期。
本文中讲述的JavaCpp例如 OpenCV、FFMpeg 等热门的开源项目是以开源贡献者已经完成JavaCpp代码转换文件的定义为前提的,关于自己的项目代码如何使用JavaCpp实现转换待我分析后再写一篇文章,感谢关注!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容