Android简单接入Vitamio

Android简单接入Vitamio

说到第三方视频播放控件,真正意义上好用的就那么几家,这里之所以要说真正意义上是因为市面上存在一部分三方视频播放器是基于原生的VideoView封装而来的,并不是说原生的不好,而是原生支持的视频格式实在是很有限,而且在线播放也是一个短板。

写在前面

在很早之前就有接触过Vitamio这款播放器,当时觉得很容易就没有过多的注意,最近又重新开始使用。轻车熟路,按照之前的流程进行集成,最后碰到了一个大坑,经过两天的时间测试,终于找到了解决方法,于是想写一个解决方案给以后遇到同样问题的朋友一个建议,又想到写都写了干脆就写全吧,O(∩_∩)O哈哈~。

市面上的视频播放SDK

目前市面上所有和媒体有关的解码编码,其实都是基于同一个开源项目——Ffmpeg,当然以下几个也不例外。有兴趣的可以自己看看。

  • Vitamio
    • 优点:几年前的项目了,支持格式较多,稳定性高,性能较高,功能强大,开发难度低。
    • 缺点:因为“年代久远”,targetSDK最高支持到22,再往上就无法运行。
  • Ijk
    • 优点:国内大名鼎鼎的Bilibili的开源库,更新给力,相信上过B站的人都知道它的强大。
    • 缺点:没有现成的play控件,需要自己去实现,集成比较麻烦,当然只是相对而言,官方有对应的Demo,总得来说还是很容易。
  • VLC
    • 优点:同Vitamio,并且是完全免费的项目。
    • 缺点:开发难度比较高,没有好用的现成库,需要自己去编译,也没发现有很好的Demo。

集成

这里直接按照最简单的方式进行集成,那些想自己编译ffmpeg库的童鞋可以去参考别的文章。

  • 下载项目

  • 集成项目

    • 将VitamioBundle集成到自己的项目中,集成方法很简单,该项目本身就是通过Gradle构建的,因此使用AS直接将vitamio作为Module导入项目中,并且添加项目的依赖即可。
  • 配置参数

    • 上面介绍到了,Vitamio最高只支持到SDK22,因此需要将项目的targetSDK设置到23以下即可,其余的权限以及用到的Activity清单都已经在官方Module中设置好了,因此导入后并不需要自己手动添加。
  • 简单使用

    • 可以说Vitamio这个库应经封装的很好了,而且设计架构也是按照原生的VideoView为参考设计的,因此学习成本非常的低。
    • 首先在布局文件中添加对应控件
      <io.vov.vitamio.widget.VideoView
          android:id="@+id/videoView"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"/>
    • 接下来初始化,设置播放地址就可以了,地址会自动识别是网络还是本地的。
          videoView = (VideoView) findViewById(R.id.videoView);
          videoView.setOnPreparedListener(this);
          progressBar.setVisibility(View.VISIBLE);
          Log.i("TAG", videoView.getCurrentPosition() + "   " + videoView.getDuration());
          videoView.setHardwareDecoder(true);
          videoView.setVideoPath(videoPath);
          if (videoView.getCurrentPosition() >= videoView.getDuration()) {
              videoView.seekTo(0);
          }
          videoView.start();
    • 方法都很简单,唯一一个有点陌生的setHardwareDecoder(boolean hardware),用来设置是否打开硬解。

    • 大概扒了一下它的源码,主要是根据不同的系统选择不同的so库。

        // this value only use Hardware decoder before Android 2.3
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB && mHardwareDecoder)      {
          getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    if (preferHWDecoder) {
          if (!NATIVE_OMX_LOADED.get()) {
            if (Build.VERSION.SDK_INT > 17)
              loadOMX_native(LIB_ROOT + "libOMX.18.so");
            else if (Build.VERSION.SDK_INT > 13)
              loadOMX_native(LIB_ROOT + "libOMX.14.so");
            else if (Build.VERSION.SDK_INT > 10)
              loadOMX_native(LIB_ROOT + "libOMX.11.so");
            else
              loadOMX_native(LIB_ROOT + "libOMX.9.so");
            NATIVE_OMX_LOADED.set(true);
          }
        } else {
          try {
            unloadOMX_native();
          } catch (UnsatisfiedLinkError e) {
            Log.e("unloadOMX failed %s", e.toString());
          }
          NATIVE_OMX_LOADED.set(false);
        }

特色

  • 支持的视频格式很多,解码方式可软解可硬解。
  • 在线播放解析的速度快了原生不止一个档次,还有多重缓冲等功能。
  • 支持调节视频播放速率,通过public void onPrepared(final MediaPlayer mp)回调拿到MediaPlayer,最后通过mp.setPlaybackSpeed(float speed)设置速率,速率区间是0.5f-2.0f。

遇到的坑

在最近的一次使用中,按照上面的流程集成,使用,播放。没毛病,恩,没有报错,也没有闪退,完美。诶?怎么没有播放?我靠!什么鬼,播放器毫无波澜。我以为是Gradlebuild版本太高,调低,再试,依然毫无波动。之后在项目层又尝试了各种方法,调了版本号,去掉了Kotlin,去掉了新版本的框架。都没有用。

最后的最后,终于让我找到了解决方法,导致视频没有播放的原因应该是没有正确的加载库。至于为什么一模一样的代码在以前的项目里面就没有问题这是个迷。官方提供了这么个方法来手动初始化库。很强!

/**
 * LibsChecker is a wrapper of {@link Vitamio}, it helps to initialize Vitamio
 * easily.
 * <p/>
 * <pre>
 * public void onCreate(Bundle b) {
 *  super.onCreate(b);
 *  if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
 *      return;
 *
 *  // Code using Vitamio should go below {@link LibsChecker#checkVitamioLibs}
 * }
 * </pre>
 */
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;
  }
}
if (!LibsChecker.checkVitamioLibs(this)) {
            toast("libsCheckerFalse")
        } else {
            videoView.setOnPreparedListener(this)
            videoView.setVideoPath(videoAddress)
            videoView.setHardwareDecoder(true)
            videoView.start()
        }

搞定。伤不起,浪费了两天就因为这么一句话。

猜你喜欢

转载自blog.csdn.net/ccw0054/article/details/79045426