??最新的android studio2.2引入了cmake可以很好地实现ndk的编写。
??进入正题,既然是ffmpeg的移植编译,那么就先下载ffmpeg,https://ffmpeg.org/download.html。这里下载的是3.0.3版本。
??新建ffmpeg文件夹,然后新建脚本用来编译ffmpeg,命名为build.sh,脚本如下:
??主要是实现了四个button,分别是protocol,format,codec和filter。如下图所示:
??
??修改jni部分的代码,也就是native-lib.cpp的代码如下:
#include#include extern "C" { #include #include #include jstring Java_com_jared_helloffmpeg_MainActivity_stringFromJNI( JNIEnv *env, jobject) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } jstring Java_com_jared_helloffmpeg_MainActivity_urlprotocolinfo( JNIEnv *env, jobject) { char info[40000] = {0}; av_register_all(); struct URLProtocol *pup = NULL; struct URLProtocol **p_temp = &pup; avio_enum_protocols((void **) p_temp, 0); while ((*p_temp) != NULL) { sprintf(info, "%sInput: %s\n", info, avio_enum_protocols((void **) p_temp, 0)); } pup = NULL; avio_enum_protocols((void **) p_temp, 1); while ((*p_temp) != NULL) { sprintf(info, "%sInput: %s\n", info, avio_enum_protocols((void **) p_temp, 1)); } return env->NewStringUTF(info); } jstring Java_com_jared_helloffmpeg_MainActivity_avformatinfo( JNIEnv *env, jobject) { char info[40000] = {0}; av_register_all(); AVInputFormat *if_temp = av_iformat_next(NULL); AVOutputFormat *of_temp = av_oformat_next(NULL); while (if_temp != NULL) { sprintf(info, "%sInput: %s\n", info, if_temp->name); if_temp = if_temp->next; } while (of_temp != NULL) { sprintf(info, "%sOutput: %s\n", info, of_temp->name); of_temp = of_temp->next; } return env->NewStringUTF(info); } jstring Java_com_jared_helloffmpeg_MainActivity_avcodecinfo( JNIEnv *env, jobject) { char info[40000] = {0}; av_register_all(); AVCodec *c_temp = av_codec_next(NULL); while (c_temp != NULL) { if (c_temp->decode != NULL) { sprintf(info, "%sdecode:", info); } else { sprintf(info, "%sencode:", info); } switch (c_temp->type) { case AVMEDIA_TYPE_VIDEO: sprintf(info, "%s(video):", info); break; case AVMEDIA_TYPE_AUDIO: sprintf(info, "%s(audio):", info); break; default: sprintf(info, "%s(other):", info); break; } sprintf(info, "%s[%10s]\n", info, c_temp->name); c_temp = c_temp->next; } return env->NewStringUTF(info); } jstring Java_com_jared_helloffmpeg_MainActivity_avfilterinfo( JNIEnv *env, jobject) { char info[40000] = {0}; avfilter_register_all(); AVFilter *f_temp = (AVFilter *)avfilter_next(NULL); while(f_temp != NULL) { sprintf(info, "%s%s\n", info, f_temp->name); f_temp = f_temp->next; } return env->NewStringUTF(info); } }
??这里要特别注意ffmpeg的头文件已经调用的代码要extern “C”里面,要不然会报错误的。
??最后就是java调用代码了。如下所示:
package com.jared.helloffmpeg; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import com.jared.helloffmpeg.databinding.MainBinding; import static java.lang.System.loadLibrary; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private MainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.btnProtocol.setOnClickListener(this); binding.btnCodec.setOnClickListener(this); binding.btnFilter.setOnClickListener(this); binding.btnFormat.setOnClickListener(this); // Example of a call to a native method //TextView tv = (TextView) findViewById(R.id.sample_text); //tv.setText(avformatinfo()); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_protocol: binding.tvInfo.setText(urlprotocolinfo()); break; case R.id.btn_format: binding.tvInfo.setText(avformatinfo()); break; case R.id.btn_codec: binding.tvInfo.setText(avcodecinfo()); break; case R.id.btn_filter: binding.tvInfo.setText(avfilterinfo()); break; default: break; } } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI(); public native String urlprotocolinfo(); public native String avformatinfo(); public native String avcodecinfo(); public native String avfilterinfo(); // Used to load the 'native-lib' library on application startup. static { loadLibrary("native-lib"); } }
??都准备好了,那么就继续运行看看结果了:
??基本上Android Studio下的cmake编译ffmpeg就到此结束了,那么接下去就可以在android手机上使用ffmpeg来做一些音视频相关的东西了。