ijkplayer库官方教程已经给出明确的编译过程以及编译脚本
https://github.com/Bilibili/ijkplayer
但是因为我是从window中直接下载的整个工程的zip包 拷贝到Linux下进行库的编译 出现一些教程中未提及的问题
主要是软链接的问题和ndk库新版本与github中发布的ijkplayer库更新时使用的ndk版本的部分兼容问题
当前github中ijkplayer最新版本是 wk2.2 使用的ndk版本 android-ndk-r14b
eclipse导入工程
Import >> Android/Existing Android Code Into Workspace
导入完成后,需要重命名对应的java/为src/ 因为eclipse默认的java代码是从src/目录开始。
ijkplayer库还需要otto库的支持(otto库 : Android中的事件总线框架,它是square的一个开源框架)
点击github下载otto库
这里还需要一个支持库,我使用的是 android-support-v7-appcompat 可以直接下载
点击下载android-support-v7-appcompat支持包
把support.zip解压到对应的android sdk目录下
D:\Program Files (x86)\android\sdk\extras\android\
解压后
D:\Program Files (x86)\android\sdk\extras\android\support\
support\目录
| - - - annotations
| - - - design
| - - - multidex
| - - - percent
| - - - samples
| - - - v4
| - - - v7
| - - - v13
| - - - v17
| - - - NOTICE.txt
| - - - README.txt
| - - - source.properties
如果android sdk环境中已经更新了 v4和v7的支持包,就不需要下载了
在eclipse中导入 sdk\extras\android\support\v7\appcompat
这里ijkplayer-sample是工程的主程序 就是生成的apk的工程 其余的全部为库
使用下面的步骤生成3个库拷贝到主工程的libs下面
点击下载 android-support-v7-preference.jar
开始使用官方提供的脚本进行编译
ijkplayer-master/config$ ln -s module-default.sh module.sh |
主要是这个软链接不能忘记设置
并且设置module.sh链接到不同情况 这里链接到 module-default.sh 文件
编译出来的 libijkffmpeg.so 7,705KB 为普遍使用的库
这里试过链接到 module-lite.sh 文件,但是播放.mpg .mov格式的文件直接报错
且编译出来的库支持格式单一 大小为 2,175KB
ijkplayer-master/android/contrib$ ./compile-ffmpeg.sh |
这是git同步ffmpeg代码 ,并且编译libijkffmpeg.so 库
只要上面的module.sh软链接设置正确即可
ijkplayer-master/android/ijkplayer/ijkplayer-armv7a/src/main/jni$ ln -s ../../../../../../ijkmedia ijkmedia |
这个软链接在编译的时候出现一些问题
如果没有手动设置这个软链接,compile-ijk.sh脚本就只生成一个库 libijkffmpeg.so
compile-ijk.sh 脚本中主要逻辑是
cd "ijkplayer/ijkplayer-$PARAM_TARGET/src/main/jni"
do_sub_cmd $PARAM_SUB_CMD
do_sub_cmd () {
$ANDROID_NDK/ndk-build $FF_MAKEFLAGS
}
进入ijkplayer-master\android\ijkplayer\ijkplayer-armv7a\src\main\jni中执行ndk-build命令
ijkmedia 则是软链接到目录 ijkplayer-master\ijkmedia , 目录如下
| - - - ijkj4a/
| - - - ijkplayer/
| - - - ijksdl/
| - - - ijksoundtouch/
| - - - ijkyuv/
| - - - Android.mk
主要是用于编译生成 libijkplayer.so 和 libijksdl.so 库,compile-ijk.sh脚本执行完成后一共就生成3个库
找不到 monstartup 和 moncleanup 函数 |
ijkplayer-master/android/ijkplayer/ijkplayer-armv7a/src/main/jni/ijkmedia/ijkplayer/android/ijkplayer_jni.c
修改为添加实现 否则会在ndk-build阶段报错找不到实现 这个函数的作用不影响demo的功能 后面涉及到再进一步分析
//void monstartup(const char *libname);
//void moncleanup(void);
void moncleanup(void){}
void monstartup(const char *libname){}
ndk兼容问题 |
ijkmedia\Android.mk 添加 APP_ALLOW_MISSING_DEPS :=true
编译 运行程序
编译过程:
$ ./compile-ijk.sh
[armeabi-v7a] Prebuilt : libijkffmpeg.so <= /home/admin/src/ijkplayer-master/android/contrib/build/ffmpeg-armv7a/output/
[armeabi-v7a] Compile thumb : ijkplayer <= ff_cmdutils.c
[armeabi-v7a] Compile thumb : ijkplayer <= ff_ffplay.c
[armeabi-v7a] Compile thumb : ijkplayer <= ff_ffpipeline.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkmeta.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkplayer.c
[armeabi-v7a] Compile thumb : ijkplayer <= ffpipeline_ffplay.c
[armeabi-v7a] Compile thumb : ijkplayer <= ffpipenode_ffplay_vdec.c
[armeabi-v7a] Compile thumb : ijkplayer <= ffmpeg_api_jni.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkplayer_android.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkplayer_jni.c
[armeabi-v7a] Compile thumb : ijkplayer <= ffpipeline_android.c
[armeabi-v7a] Compile thumb : ijkplayer <= ffpipenode_android_mediacodec_vdec.c
[armeabi-v7a] Compile thumb : ijkplayer <= allformats.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijklivehook.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkmediadatasource.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkio.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkiomanager.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkiocache.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkioffio.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkioandroidio.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkiourlhook.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkasync.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkurlhook.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijklongurl.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijksegment.c
[armeabi-v7a] Compile thumb : ijkplayer <= ijkthreadpool.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_aout.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_egl.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_vout.c
[armeabi-v7a] Compile thumb : ijksdl <= color.c
[armeabi-v7a] Compile thumb : ijksdl <= common.c
[armeabi-v7a] Compile thumb : ijksdl <= renderer.c
[armeabi-v7a] Compile thumb : ijksdl <= renderer_rgb.c
[armeabi-v7a] Compile thumb : ijksdl <= renderer_yuv420p.c
[armeabi-v7a] Compile thumb : ijksdl <= renderer_yuv444p10le.c
[armeabi-v7a] Compile thumb : ijksdl <= shader.c
[armeabi-v7a] Compile thumb : ijksdl <= rgb.fsh.c
[armeabi-v7a] Compile thumb : ijksdl <= yuv420p.fsh.c
[armeabi-v7a] Compile thumb : ijksdl <= yuv444p10le.fsh.c
[armeabi-v7a] Compile thumb : ijksdl <= mvp.vsh.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_vout_dummy.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_vout_overlay_ffmpeg.c
[armeabi-v7a] Compile thumb : ijksdl <= image_convert.c
[armeabi-v7a] Compile thumb : ijksdl <= android_nativewindow.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_vout_android_nativewindow.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_vout_android_surface.c
[armeabi-v7a] Compile thumb : ijksdl <= ijksdl_vout_overlay_android_mediacodec.c
[armeabi-v7a] Install : libijkffmpeg.so => libs/armeabi-v7a/libijkffmpeg.so
[armeabi-v7a] SharedLibrary : libijksdl.so
[armeabi-v7a] SharedLibrary : libijkplayer.so
[armeabi-v7a] Install : libijksdl.so => libs/armeabi-v7a/libijksdl.so
[armeabi-v7a] Install : libijkplayer.so => libs/armeabi-v7a/libijkplayer.so
这里用了歌词的形式顺便测试音视频同步的精准度
对应右侧的信息 可以设置不显示
IjkVideoView.java/setHudView(TableLayout tableLayout)/tableLayout.setVisibility(View.INVISIBLE);
上面是播放了本地视频, 测试下sdk中的网络视频播放
把AppActivity.java中上面菜单的settings键修改为进入播放视频界面 传入网络视频源文件地址
@Override
public boolean onOptionsItemSelected(MenuItem item) {
String netpath = "http://v.cctv.com/flash//jingjibanxiaoshi/2008/09/jingjibanxiaoshi_300_20080919_1.flv";
if (id == R.id.action_settings) {
//SettingsActivity.intentTo(this);
VideoActivity.intentTo(this,netpath "online.demo");
return true;
} else if (id == R.id.action_recent) {
RecentMediaActivity.intentTo(this);
} else if (id == R.id.action_sample) {
SampleMediaActivity.intentTo(this);
}
return super.onOptionsItemSelected(item);
}