Vitamio使用篇,打造强悍的视频播放器

Vitamio是一个优秀的Android视频框架,很多人也在用,所以这篇文章就是带大家接入Vitamio并且使用的

首先我们要明白一个需求就是,我们需要做一个视频播放器,那这样的话,我们首先想到的就是VideView,但是VideoView说实话,不支持很多视频格式,所以我们换成Vitamio,可以明确的说,Vitamio的使用方式基本上和VideoView是一样的,这也便于我们更好的封装

我们先看下他的官网:https://www.vitamio.org/

这些介绍我就不多BB了,直接点击下载中心可以看到,他提供了两个示例代码:

Android Vitamio演示(eclipse)
Android Vitamio演示(Android Studio)

我们首先推荐的也是Android Studio:https://github.com/yixia/VitamioBundleStudio

你只需要把代码下载下来,我们就可以开始集成了

一.集成踩坑

集成的话,还是万般简单的,你只需要解压下载下来的zip,我们是以 model 的方式集成,也就是vitamio这个包

640?wx_fmt=png

然后再我们的Android Studio中,点击File - New - Import Model 即可

导入之后就开始我们得到踩坑之旅了

如果你发现无法集成model,你需要在在项目的settings.gradle里配置一下

include ':app',":vitamio"

然后在 app/build.gradle中配置如下

android{
    defaultConfig{
        ndk{
             abiFilters 'armeabi''x86','armeabi-v7a'
        }
    }
}

以及

//Vitamio
implementation project(':vitamio')

相信这些都不是什么问题吧,紧接着我们要配置一下vitamio的build.gradle里

android {
    compileSdkVersion 28
    //buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 22
    }
}

总的来讲就是需要配置

  • compileSdkVersion

  • minSdkVersion

  • targetSdkVersion

至于这三个的版本号,你只需要和app/build.gradle保持一致就行,这里的一个坑就是targetSdkVersion 了,targetSdkVersion 必须<=22,不然某些机型会报错,至于什么原因,你自己去搜索下。

最后我们就可以配置清单文件了,在主工程的清单文件中添加如下:

<!--Vitamio-->
<activity
      android:name="io.vov.vitamio.activity.InitActivity"
      android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
      android:launchMode="singleTop"
      android:theme="@android:style/Theme.NoTitleBar"
      android:windowSoftInputMode="stateAlwaysHidden" />

对了,记得配置权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

现在我们就可以开始封装了

二.封装Vitamio

使用方法跟VideoView一样,所以很好的封装

import android.net.Uri;
import android.os.Handler;
import android.os.Message;

import com.xt.gtlauncher.utils.L;

import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.widget.VideoView;

public class VideoManager {

    private io.vov.vitamio.widget.VideoView mVideoView;

    private OnVideoProgressListener listener;

    private static final int H_PROGRESS = 1001;

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what) {
                case H_PROGRESS:
                    if (listener != null) {
                        //获取当前时长
                        long currentDuration = getCurrentPosition();
                        listener.onProgress(currentDuration);
                        mHandler.sendEmptyMessageDelayed(H_PROGRESS, 1000);
                    }
                    break;
            }
            return false;
        }
    });

    public VideoManager(VideoView mVideoView) {
        this.mVideoView = mVideoView;
    }

    /**
     * 设置文件路径
     *
     * @param path
     */

    public void setVideoPath(String path) {
        mVideoView.setVideoPath(path);
    }

    /**
     * 设置网络路径
     *
     * @param uri
     */

    public void setVideoURI(Uri uri) {
        mVideoView.setVideoURI(uri);
    }

    /**
     * 设置倍数 [0.5 - 2.0]
     *
     * @param mediaPlayer
     * @param speed
     */

    public void setPlaybackSpeed(MediaPlayer mediaPlayer, float speed) {
        mediaPlayer.setPlaybackSpeed(speed);
    }

    /**
     * 获取当前播放的位置
     *
     * @return
     */

    public long getCurrentPosition() {
        return mVideoView.getCurrentPosition();
    }

    /**
     * 获取当前的视频总长度
     *
     * @return
     */

    public long getDuration() {
        return mVideoView.getDuration();
    }

    /**
     * 是否播放
     *
     * @return
     */

    public boolean isPlaying() {
        return mVideoView.isPlaying();
    }

    /**
     * 播放
     */

    public void start() {
        mVideoView.start();
        //mVideoView.requestFocus();
        mHandler.sendEmptyMessage(H_PROGRESS);
    }

    /**
     * 暂停
     */

    public void pause() {
        mVideoView.pause();
    }

    /**
     * 重新播放
     */

    public void resume() {
        mVideoView.resume();
    }

    /**
     * 停止播放 释放资源
     */

    public void stopPlayback() {
        mVideoView.stopPlayback();
        mHandler.removeMessages(H_PROGRESS);
    }

    /**
     * 从第几毫秒开始播放
     *
     * @param msec
     */

    public void seekTo(int msec) {
        mVideoView.seekTo(msec);
    }

    /**
     * 设置控制器
     *
     * @param controller
     */

    public void setMediaController(io.vov.vitamio.widget.MediaController controller) {
        mVideoView.setMediaController(controller);
    }

    /**
     * 监听播放完毕
     *
     * @param l
     */

    public void setOnCompletionListener(io.vov.vitamio.MediaPlayer.OnCompletionListener l) {
        mVideoView.setOnCompletionListener(l);
    }

    /**
     * 监听发生错误
     *
     * @param l
     */

    public void setOnErrorListener(io.vov.vitamio.MediaPlayer.OnErrorListener l) {
        mVideoView.setOnErrorListener(l);
    }

    /**
     * 监听视频装载完成
     *
     * @param l
     */

    public void setOnPreparedListener(io.vov.vitamio.MediaPlayer.OnPreparedListener l) {
        mVideoView.setOnPreparedListener(l);
    }

    /**
     * 监听进度
     *
     * @param listener
     */

    public void setOnVideoProgress(OnVideoProgressListener listener) {
        this.listener = listener;
    }

    public interface OnVideoProgressListener {
        void onProgress(long progress);
    }
}

这里特别注意一下,我封装的过程中增加了进度的反馈,所以大家可以根据更方便的更新进度条

三.Vitamio的使用

先看下我的界面吧

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <io.vov.vitamio.widget.VideoView
        android:id="@+id/mVideoView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <!--标题-->
    <LinearLayout
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <ImageView
            android:id="@+id/iv_back"
            android:src="@mipmap/ic_launcher"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />


        <TextView
            android:text="--"
            android:id="@+id/tv_video_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />


    </LinearLayout>

    <!--控制-->
    <LinearLayout
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <SeekBar
            android:thumb="@drawable/img_seekbar_tum"
            android:id="@+id/mSeekBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


        <LinearLayout
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">


            <ImageView
                android:id="@+id/iv_control"
                android:src="@mipmap/ic_launcher"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />


            <TextView
                android:text="--"
                android:id="@+id/tv_video_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />


        </LinearLayout>

    </LinearLayout>

</RelativeLayout>


640?wx_fmt=png

这个界面很简单,上面一个返回键和一个标题,下面一个控制键和一个时间显示

再来看下代码是如何实现的

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import io.vov.vitamio.Vitamio;
import io.vov.vitamio.widget.VideoView;

public class VideoActivity extends BaseActivity implements View.OnClickListener {

    private VideoView mVideoView;
    private TextView tv_video_name;
    private SeekBar mSeekBar;
    private TextView tv_video_time;
    private ImageView iv_back;
    private ImageView iv_control;

    private VideoManager mVideoManager;

    private String videoName;
    private String videoPath;
    private String videoAllDuration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);

        initView();
    }

    private void initView() {

        Intent intent = getIntent();
        videoName = intent.getStringExtra("name");
        videoPath = intent.getStringExtra("path");

        //Test
        videoName = "Test";
        videoPath = "/sdcard/Test.mp4";

        mVideoView = (VideoView) findViewById(R.id.mVideoView);
        tv_video_name = (TextView) findViewById(R.id.tv_video_name);
        mSeekBar = (SeekBar) findViewById(R.id.mSeekBar);
        tv_video_time = (TextView) findViewById(R.id.tv_video_time);
        iv_back = (ImageView) findViewById(R.id.iv_back);
        iv_control = (ImageView) findViewById(R.id.iv_control);

        iv_control.setOnClickListener(this);
        iv_back.setOnClickListener(this);

        tv_video_name.setText(videoName);

        initVideo();
    }

    private void initVideo() {

        mVideoManager = new VideoManager(mVideoView);
        mVideoManager.setVideoPath(videoPath);

  mVideoManager.setOnPreparedListener(new   io.vov.vitamio.MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(io.vov.vitamio.MediaPlayer mp) {
                L.i("onPrepared");
                mVideoManager.setPlaybackSpeed(mp, 1.0f);
                long allDuration = mVideoManager.getDuration();
                videoAllDuration = CommonUtils.formatDuring(allDuration);
                mSeekBar.setMax((int) allDuration);
                mVideoManager.start();
            }
        });

        mVideoManager.setOnCompletionListener(new io.vov.vitamio.MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(io.vov.vitamio.MediaPlayer mediaPlayer) {
                L.i("onCompletion");
            }
        });

        mVideoManager.setOnVideoProgress(new VideoManager.OnVideoProgressListener() {
            @Override
            public void onProgress(long progress) {
                mSeekBar.setProgress((int) progress);
                tv_video_time.setText(CommonUtils.formatDuring(progress) + "/" + videoAllDuration);
            }
        });

        mVideoManager.setOnErrorListener(new io.vov.vitamio.MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(io.vov.vitamio.MediaPlayer mediaPlayer, int i, int i1) {
                L.e("i:" + i + "i1" + i1);
                return false;
            }
        });

        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mVideoManager.seekTo(mSeekBar.getProgress());
            }
        });
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_back:
                finish();
                break;
            case R.id.iv_control:
                if(mVideoManager.isPlaying()){
                    mVideoManager.pause();
                }else{
                    mVideoManager.start();
                }
                break;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mVideoManager.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mVideoManager.pause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mVideoManager.stopPlayback();
    }
}

这份代码可谓是很精简了,大概的流程我说下:

首先VideoManager初始化后设置路径,这里不光可以设置本地File路径也可以是网络路径,就需要setVideoURI即可。然后设置各种监听:

setOnPreparedListener设置就是当加载好视频之后的回调,这个时候我可以设置一下播放倍数,以及获取总时长和设置进度的总时长,然后开始播放视频

setOnCompletionListener 监听播放完成

setOnVideoProgress 不断通知刷新进度

setOnErrorListener 播放错误

setOnSeekBarChangeListener 进度条的拖拽 这里我调用了seekTo实现进度拖拽

最后绑定了一下生命周期即可了,这里用到了一个毫秒转换时长的方法

public class CommonUtils {

    /**
     * 毫秒转换成小时
     * @param mss
     * @return
     */

    public static String formatDuring(long mss) {
        long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
        long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
        long seconds = (mss % (1000 * 60)) / 1000;

        String h = "";
        String m = "";
        String s = "";
        if(hours < 10){
            h = "0" + hours;
        }else{
            h = hours + "";
        }

        if(minutes < 10){
            m = "0" + minutes;
        }else{
            m = minutes + "";
        }

        if(seconds < 10){
            s = "0" + seconds;
        }else{
            s = seconds + "";
        }

        return h + ":" + m + ":" + s;
    }
}

到这里就本文就结束了,来看下最终的效果吧

640?wx_fmt=gif


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值