vitamio这个视频框架已经有快两年没有没有使用过了,今天想写个demo再复习下。

  • 首先肯定是下载官方的demo跑一下了,他们的demo放在github上,所以我就直接上github搜索并下载VitamioBundle,我个人比较喜欢用新的api,所以手动将targetSdkVersion改为了27,重新编译运行,app打开了,没问题,点击VideoView条目跳转播放页面播放,居然崩溃了。
07-19 07:44:09.764 5133-5133/io.vov.vitamio.demo E/linker: "/data/data/io.vov.vitamio.demo/libs/libffmpeg.so" has text relocations (https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-Enforced-for-API-level-23)
07-19 07:44:09.765 5133-5133/io.vov.vitamio.demo E/Vitamio[4.2.1][Player]: LOAD FFMPEG ERROR: dlopen failed: "/data/data/io.vov.vitamio.demo/libs/libffmpeg.so" has text relocations (https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-Enforced-for-API-level-23)
07-19 07:44:09.766 5133-5133/io.vov.vitamio.demo E/Vitamio[4.2.1][Player]: FIND_NAME_SYM vvo, render_yuv
07-19 07:44:09.768 5133-5133/io.vov.vitamio.demo A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 5133 (ov.vitamio.demo), pid 5133 (ov.vitamio.demo)
07-19 07:44:09.792 5170-5170/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    Build fingerprint: 'google/sdk_gphone_x86/generic_x86:8.1.0/OSM1.180201.021/4741582:userdebug/dev-keys'
    Revision: '0'
    ABI: 'x86'
    pid: 5133, tid: 5133, name: ov.vitamio.demo  >>> io.vov.vitamio.demo <<<
    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    Cause: null pointer dereference
        eax ca5b5ac0  ebx ca5aded8  ecx e49a91e4  edx e3b10860
07-19 07:44:09.792 5170-5170/? A/DEBUG:     esi e3b10860  edi 00000075
        xcs 00000023  xds 0000002b  xes 0000002b  xfs 0000006b  xss 0000002b
        eip 00000000  ebp ca598f98  esp ff832c2c  flags 00010246
    backtrace:
        #00 pc 00000000  <unknown>
        #01 pc 5b6f696c  <unknown>

说实话这日志看的我一脸懵逼,但还是得找解决方案google一下。

Vitamio Crash In Android 6.0(Marshmallow) Devices when android targetSdkVersion set to 23

在这里我找到了暂时解决得方案,把targetSdkVersion改到22,再次运行,视频正常播放。

  • demo跑起来了,接下来当然是自己写个demo玩玩了。(具体的导入过程我就不多说了,百度一下有很多)编译运行,what?黑屏~。查看日志:

07-19 08:03:08.076 5822-5822/io.vov.vitamio.demo E/Vitamio[Player]: Native libs libffmpeg.so not exists!

打开Vitamio.java,找到输出错误日志的地方:

 /*** Check if Vitamio is initialized at this device** @param ctx Android Context* @return true if the Vitamio has been initialized.*/public static boolean isInitialized(Context ctx) {vitamioPackage = ctx.getPackageName();vitamioLibraryPath = ContextUtils.getDataDir(ctx) + "libs/";File dir = new File(getLibraryPath());if (dir.exists() && dir.isDirectory()) {String[] libs = dir.list();if (libs != null) {Arrays.sort(libs);for (String L : getRequiredLibs()) {if (Arrays.binarySearch(libs, L) < 0) {Log.e("Native libs %s not exists!", L);return false;}}File lock = new File(getLibraryPath() + LIBS_LOCK);BufferedReader buffer = null; try {buffer = new BufferedReader(new FileReader(lock));  int appVersion = ContextUtils.getVersionCode(ctx);int libVersion = Integer.valueOf(buffer.readLine());  Log.i("isNativeLibsInited, APP VERSION: %d, Vitamio Library version: %d", appVersion, libVersion);if (libVersion == appVersion)return true;} catch (IOException e) {Log.e("isNativeLibsInited", e);} catch (NumberFormatException e) {Log.e("isNativeLibsInited", e);} finally {IOUtils.closeSilently(buffer);}}}return false;}

原来是没有初始化成功,先看看我们加载布局之前做了什么。

//检查初始化
if (!LibsChecker.checkVitamioLibs(this))return;

那我们再看一下LibsChecker这个类做了什么

public final class LibsChecker {public static final String FROM_ME = "fromVitamioInitActivity";public static final boolean checkVitamioLibs(Activity ctx) {if (!Vitamio.isInitialized(ctx) && !ctx.getIntent().getBooleanExtra(FROM_ME, false)) {Intent i = new Intent();i.setClassName(Vitamio.getVitamioPackage(), "io.vov.vitamio.activity.InitActivity");i.putExtras(ctx.getIntent());i.setData(ctx.getIntent().getData());i.putExtra("package", ctx.getPackageName());i.putExtra("className", ctx.getClass().getName());ctx.startActivity(i);ctx.finish();return false;}return true;}
}

由此我们发现,它的作用主要是将当前Activity的信息传递给InitActivity,并把当前页面finish掉。再看一下InitActivity

public class InitActivity extends Activity {public static final String FROM_ME = "fromVitamioInitActivity";private ProgressDialog mPD;private UIHandler uiHandler;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);uiHandler = new UIHandler(this);new AsyncTask<Object, Object, Boolean>() {@Overrideprotected void onPreExecute() {mPD = new ProgressDialog(InitActivity.this);mPD.setCancelable(false);mPD.setMessage(InitActivity.this.getString(getResources().getIdentifier("vitamio_init_decoders", "string", getPackageName())));mPD.show();}@Overrideprotected Boolean doInBackground(Object... params) {//进行初始化操作return Vitamio.initialize(InitActivity.this, getResources().getIdentifier("libarm", "raw", getPackageName()));}@Overrideprotected void onPostExecute(Boolean inited) {if (inited) {uiHandler.sendEmptyMessage(0);}}}.execute();}private static class UIHandler extends Handler {private WeakReference<Context> mContext;public UIHandler(Context c) {mContext = new WeakReference<Context>(c);}public void handleMessage(Message msg) {InitActivity ctx = (InitActivity) mContext.get();switch (msg.what) {case 0:ctx.mPD.dismiss();Intent src = ctx.getIntent();Intent i = new Intent();i.setClassName(src.getStringExtra("package"), src.getStringExtra("className"));i.setData(src.getData());i.putExtras(src);i.putExtra(FROM_ME, true);ctx.startActivity(i);ctx.finish();break;}}}
}

原来初始化的操作放在了这里,开启了一个异步任务进行初始化操作,初始化成功后通过handler发送一个空消息,然后执行操作,跳转到之前的那个页面(信息都传过来了),并关闭InitActivity。这里有两个地方比较疑惑

  • 为什么要加一个handler呢,onPostExecute里面的就是执行在UI线程的吧
  • Vitamio.initialize(Context ctx, int rawId)方法里面,两个条件问什么是或的关系,明明其中一个失败就能导致初始化失败
 /*** Same as {@link #initialize(Context)}** @param ctx   Android Context* @param rawId R.raw.libarm* @return true if the Vitamio initialized successfully.*/public static boolean initialize(Context ctx, int rawId) {return isInitialized(ctx) || extractLibs(ctx, rawId);}
补充:如果不是通过定义静态内部类的方法使用handler,是有可能造成内存泄漏的。

回归正题,通过以上我们发现了一个参数rawId,默认值是R.raw.libarm。但是我创建项目的时候res下并没有创建raw文件夹。对比了一下demo,发现别人的确实有这么个文件夹,里面放了libarm.so文件。(vitamio库里面也有这个,不太清楚为什么自己module里面也要加上) 重新编译运行,可以正常播放视频。

重新回到最初的问题,我总不能为了使用vitamio而放弃使用高版本的api吧。搜寻一番无果后,我打开了vitamio的官网,看到了新版本5.2.3,并且已经说明支持Android6.0。(这时我想拍死自己),既然有新的了,那么重新集成,这次我把targetSdkVersion设为了27,编译运行,成功。

补充:我将两个版本的demo做了下对比。新的demo中不在需要res/raw文件夹了,并且删除了LibsChecker,同时InitActivity里面不再执行初始化操作了。(感觉这个类也失去了存在的意义,不过没删除而已)

我们做初始化操作,由

if (!LibsChecker.checkVitamioLibs(this))return;

变成了

Vitamio.isInitialized(this);

activity由以前的启动2次变成了1次。

4.2.1版本:VideoViewActivity(start)->LibsChecker.checkVitamioLibs(this)->InitActivity(start),VideoViewActivity(finish)->Vitamio.initialize(this)->VideoViewActivity(start),InitActivity(finish)->setContentView()

5.2.3版本:VideoViewActivity(start)->Vitamio.isInitialized(this)->setContentView()

Vitamio的踩坑+填坑相关推荐

  1. Spark踩坑填坑-聚合函数-序列化异常

    Spark踩坑填坑-聚合函数-序列化异常 一.Spark聚合函数特殊场景 二.spark sql group by 三.Spark Caused by: java.io.NotSerializable ...

  2. [iOS]贝聊 IAP 实战之见坑填坑

    大家好,我是**贝聊科技** 的 iOS 工程师 @NewPan. 这次为大家带来我司 IAP 的实现过程详解,鉴于支付功能的重要性以及复杂性,文章会很长,而且支付验证的细节也关系重大,所以这个主题会 ...

  3. weex css单位,Weex系列(7) ——踩坑填坑的总总

    目录 使用weex已经一年半了,踩了很多坑,也流了很多泪填上,总结一波,希望对大家有所帮助. LaunchImage 这是今年来的第一个调整,需要把 iOS8.0 and Later勾上,不然iPho ...

  4. Springboot中使用Mybatis框架对数据库进行联表查询,踩坑填坑

    因为mybatis使用的基本是原生sql语句 所以首先从数据库开始说 以mysql数据库为例,对表的连接查询分为四种 内连接,外连接,交叉连接,和联合连接 内连接使用比较运算符根据每个表共有的列的值匹 ...

  5. js promises 踩坑 填坑 We have a problem with promises

    We have a problem with promises promise 填坑 对于 promise return 与否,结果真的不一样哦. By: Nolan Lawson Published ...

  6. Cobalt Strike折腾踩坑填坑记录

    文章目录 0X00 背景 0x01 基础原理 0x02 关于破戒 Exit暗桩 0x03 CDN+反代隐藏Teamserver Domain Fronting Proxy 0x04 DNS上线 一个未 ...

  7. Pyinstaller 详解多种打包过程(去坑,填坑)。

    前言 本篇文章,详细介绍pyinstaller多种打包过程.去坑,填坑. 一.安装Pyinstaller 1)使用下面的命令即可安装(win10) pip install pyinstaller 二. ...

  8. 微信小程序--多视频滑动播放(踩坑,填坑)

    最近在做一个关于短视频的小程序,类似于微视和快手的小程序,但是在做的过程当中碰到了好多坑,于是得一步一步的去填这个坑.先来看看最后的实现效果 在做的过程中,想要实现多个视频无限滑动播放,并且在视频原生 ...

  9. 踩坑-填坑之 : vue打包上线,页面无法显示

    出现了什么问题,什么现象? 根据从网上down下来的iview-admin框架进行后台管理系统开发,开发过程顺利,在部署到测试服务器时,打开页面一片空白;或是打开页面时只显示首页跳转到其他页面时显示空 ...

最新文章

  1. 招聘:兼职ASP 高级工程师
  2. python自动化测试视频百度云-python接口自动化测试视频教程全集
  3. Tutorial on Variational AutoEncoders
  4. 【Unity3D技巧】一个简单的Unity-UI框架的实现
  5. 如何找到SAP ABAP odata服务实现的具体backend 系统
  6. visual c++ build tools的安装与使用
  7. MFC的程序,不想显示窗口,任务栏里也不显示
  8. [ES6] 细化ES6之 -- 变量的解构赋值
  9. mqa插件_为什么专有的MQA音乐编码系统比DRM更好,但仍然不好
  10. STM8单片机通过PWM触发ADC同步采样
  11. Netty工作笔记0035---Reactor模式图剖析
  12. TypeScript与React中如何使用ref
  13. 51Nod-1091 线段的重叠【排序】
  14. 新浪微博从 Kafka 到 Pulsar 的演变
  15. 机会是留给有准备的人的
  16. 联想计算机怎样分区,电脑硬盘怎么分区才合理?看完秒懂
  17. 子豪兄教你在树莓派上安装OpenCV
  18. 网络原理实验4 路由协议的配置
  19. 【LOJ】#3086. 「GXOI / GZOI2019」逼死强迫症
  20. UUUUUUUUUUnity

热门文章

  1. 鸿蒙和ios流畅对比,鸿蒙OS对比iOS,华为再次“超越”,流畅度大幅领先苹果!...
  2. 数据分析案例(口罩亏损)--数据处理
  3. 23种设计模式——建造者模式
  4. LinuX 硬盘分区细节详谈
  5. Nico的刷题日记(一)
  6. 更新文件服务器,文件更新服务器
  7. 1984年高考数学试题。
  8. 出现这个错误的解决方法No enclosing instance of type 类名 is accessible. Must qualify the allocation with
  9. 喊苦喊累的程序员们,看看日本人是怎么加班的。
  10. sja1000 中断_[转载]SJA1000的错误中断处理