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

2019-02-25 13:54:45 / 打印

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

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

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

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

我们首先推荐的也是Android Studio:

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

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

觉得功能问题:potplayer安卓版官网,温暖编码器逗乐

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

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

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

include ':app',":vitamio"然后在 app/build.gradle中配置如下

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

//Vitamioimplementation 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" />现在我们就可以开始封装了

使用方法跟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);    }}这里特别注意一下,我封装的过程中增加了进度的反馈,所以大家可以根据更方便的更新进度条

先看下我的界面吧

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns: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>

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

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

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();    }}这份代码可谓是很精简了,大概的流程我说下:

一个(金刚不坏)-干预、kmplayer播放器

首先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;    }}到这里就本文就结束了,来看下最终的效果吧