美文网首页大话安卓Android技术总结android share
功能强大的Vitamio视频播放器的使用教程

功能强大的Vitamio视频播放器的使用教程

作者: jxnk25 | 来源:发表于2016-05-24 11:47 被阅读14393次

    Vitamio简介:Vitamio是一个支持所有Android设备的多媒体框架。Vitamio与Android默认的MediaPlayer工作方式相似,但包含更加强大的功能!(注意:Vitamio商业化后个人免费、公司收费)

    vitamio官网:https://www.vitamio.org

    vitamio SDK地址:https://github.com/yixia/VitamioBundle

    之前开发一个视频播放类的项目,需要实现在线播放的功能,找了很多视频播放框架,觉得Vitamio视频播放框架还不错,也相对稳定,但是在网上找了很多教程都少之又少,Vitamio官网写的教程也不是很清晰,所以就自己就把Vitamio在github上的demo进行研究,花了点时间写了个demo出来并且将Vitamio的视频控制器界面进行自定义,支持视频亮度、音量的调节,话不多说,先上效果图。

    附上 Demo的github地址
    自定义视频控制器

    8F05796762EDAA5275D59EB31D3248E9.jpg

    目前,作者只实现了自定义手势调节亮度、音量的加减以及播放控制的功能,更多的功能等待着大家一起去挖掘。

    使用步骤:

    1.引入vitamio SDK的方式有两种:

    (1)直接以module的方式引入

    (2)通过Complie的方式引入

    作者是采用的第一种方式,下面是一些需要注意的地方:

    • 清单文件配置:
      1)权限设置:
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    2)application配置:

    <!-- 必须初始化 -->
    <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" />
    

    2.主要代码:

    • 播放视频代码
    package com.stx.vitamiodemo;
    import android.content.res.Configuration;
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import io.vov.vitamio.LibsChecker;
    import io.vov.vitamio.MediaPlayer;
    import io.vov.vitamio.Vitamio;
    import io.vov.vitamio.widget.MediaController;
    import io.vov.vitamio.widget.VideoView;
    /**
     * Vitamio视频播放框架Demo
     */
    public class MainActivity extends AppCompatActivity implements MediaPlayer.OnInfoListener, 
    
    MediaPlayer.OnBufferingUpdateListener{
        //视频地址
        private String path = "http://baobab.wdjcdn.com/145076769089714.mp4";
        private Uri uri;
        private ProgressBar pb;
        private TextView downloadRateView, loadRateView;
        private CustomMediaController mCustomMediaController;
        private VideoView mVideoView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //定义全屏参数
            int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
            //获得当前窗体对象
            Window window = MainActivity.this.getWindow();
            //设置当前窗体为全屏显示
            window.setFlags(flag, flag);
            //必须写这个,初始化加载库文件
            Vitamio.initialize(this);
            //设置视频解码监听
            if (!LibsChecker.checkVitamioLibs(this)) {
                return;
            }
            setContentView(R.layout.activity_main);
            initView();
            initData();
    
           //获取上一次保存的进度
            long progress = SPUtils.getLong(this, "progress");//此处使用SharedPreferences保存当前播放进度,SPUtils是我自己封装的工具类
    
            mVideoView.seekTo(progress);
            mVideoView.start();
        }
        //初始化控件
        private void initView() {
            mVideoView = (VideoView) findViewById(R.id.buffer);
            mCustomMediaController=new CustomMediaController(this,mVideoView,this);
            mCustomMediaController.setVideoName("白火锅 x 红火锅");
            pb = (ProgressBar) findViewById(R.id.probar);
            downloadRateView = (TextView) findViewById(R.id.download_rate);
            loadRateView = (TextView) findViewById(R.id.load_rate);
        }
    
        //初始化数据
        private void initData() {
            uri = Uri.parse(path);
            mVideoView.setVideoURI(uri);//设置视频播放地址
            mCustomMediaController.show(5000);
            mVideoView.setMediaController(mCustomMediaController);
            mVideoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH);//高画质
            mVideoView.requestFocus();
            mVideoView.setOnInfoListener(this);
            mVideoView.setOnBufferingUpdateListener(this);
            mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.setPlaybackSpeed(1.0f);
                }
            });
        }
    
        @Override
        public boolean onInfo(MediaPlayer mp, int what, int extra) {
            switch (what) {
                case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                    if (mVideoView.isPlaying()) {
                        mVideoView.pause();
                        pb.setVisibility(View.VISIBLE);
                        downloadRateView.setText("");
                        loadRateView.setText("");
                        downloadRateView.setVisibility(View.VISIBLE);
                        loadRateView.setVisibility(View.VISIBLE);
    
                    }
                    break;
                case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                    mVideoView.start();
                    pb.setVisibility(View.GONE);
                    downloadRateView.setVisibility(View.GONE);
                    loadRateView.setVisibility(View.GONE);
                    break;
                case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
                    downloadRateView.setText("" + extra + "kb/s" + "  ");
                    break;
            }
            return true;
        }
    
        @Override
        public void onBufferingUpdate(MediaPlayer mp, int percent) {
            loadRateView.setText(percent + "%");
        }
    
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            //屏幕切换时,设置全屏
            if (mVideoView != null){
                mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0);
            }
            super.onConfigurationChanged(newConfig);
        }
    
    
    
      @Override
        protected void onPause() {
            super.onPause();
            //保存进度
            SPUtils.putLong(this,"progress",mVideoView.getCurrentPosition());
        }
    
    }
    
    
    • 自定义视频控制器:
      主要实现了手势调节视频亮度、音量的加减控制。
    package com.stx.vitamiodemo;
    
    import android.app.Activity;
    import android.content.Context;
    import android.media.AudioManager;
    import android.os.Handler;
    import android.os.Message;
    import android.view.Display;
    import android.view.GestureDetector;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.ImageButton;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    import android.widget.SeekBar;
    import android.widget.TextView;
    
    import io.vov.vitamio.widget.MediaController;
    import io.vov.vitamio.widget.VideoView;
    
    /**
     * Created by xhb on 2016/3/1.
     * 自定义视频控制器
     */
    public class CustomMediaController extends MediaController {
        private static final int HIDEFRAM = 0;//控制提示窗口的显示
    
        private GestureDetector mGestureDetector;
        private ImageButton img_back;//返回按钮
        private TextView mFileName;//文件名
        private VideoView videoView;
        private Activity activity;
        private Context context;
        private String videoname;//视频名称
        private int controllerWidth = 0;//设置mediaController高度为了使横屏时top显示在屏幕顶端
    
    
        private View mVolumeBrightnessLayout;//提示窗口
        private ImageView mOperationBg;//提示图片
        private TextView mOperationTv;//提示文字
        private AudioManager mAudioManager;
        private SeekBar progress;
        private boolean mDragging;
        private MediaPlayerControl player;
        //最大声音
        private int mMaxVolume;
        // 当前声音
        private int mVolume = -1;
        //当前亮度
        private float mBrightness = -1f;
    
    
        //返回监听
        private View.OnClickListener backListener = new View.OnClickListener() {
            public void onClick(View v) {
                if (activity != null) {
                    activity.finish();
                }
            }
        };
    
        private Handler myHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                long pos;
                switch (msg.what) {
                    case HIDEFRAM://隐藏提示窗口
                        mVolumeBrightnessLayout.setVisibility(View.GONE);
                        mOperationTv.setVisibility(View.GONE);
                        break;
                }
            }
        };
    
    
        //videoview 用于对视频进行控制的等,activity为了退出
        public CustomMediaController(Context context, VideoView videoView, Activity activity) {
            super(context);
            this.context = context;
            this.videoView = videoView;
            this.activity = activity;
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            controllerWidth = wm.getDefaultDisplay().getWidth();
            mGestureDetector = new GestureDetector(context, new MyGestureListener());
    
        }
    
        @Override
        protected View makeControllerView() {
            //此处的   mymediacontroller  为我们自定义控制器的布局文件名称
            View v = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate
    
    (getResources().getIdentifier("mymediacontroller", "layout", getContext().getPackageName()), this);
            v.setMinimumHeight(controllerWidth);
            //获取控件
            img_back = (ImageButton) v.findViewById(getResources().getIdentifier("mediacontroller_top_back", "id", 
    
    context.getPackageName()));
            mFileName = (TextView) v.findViewById(getResources().getIdentifier("mediacontroller_filename", "id", 
    
    context.getPackageName()));
    
            if (mFileName != null) {
                mFileName.setText(videoname);
            }
            //声音控制
            mVolumeBrightnessLayout = (RelativeLayout) v.findViewById(R.id.operation_volume_brightness);
            mOperationBg = (ImageView) v.findViewById(R.id.operation_bg);
            mOperationTv = (TextView) v.findViewById(R.id.operation_tv);
            mOperationTv.setVisibility(View.GONE);
            mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            mMaxVolume = mAudioManager
                    .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    
            //注册事件监听
            img_back.setOnClickListener(backListener);
            return v;
        }
    
        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
            System.out.println("MYApp-MyMediaController-dispatchKeyEvent");
            return true;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (mGestureDetector.onTouchEvent(event)) return true;
            // 处理手势结束
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_UP:
                    endGesture();
                    break;
            }
            return super.onTouchEvent(event);
        }
    
        /**
         * 手势结束
         */
        private void endGesture() {
            mVolume = -1;
            mBrightness = -1f;
            // 隐藏
            myHandler.removeMessages(HIDEFRAM);
            myHandler.sendEmptyMessageDelayed(HIDEFRAM, 1);
        }
    
        private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return false;
            }
    
            /**
             * 因为使用的是自定义的mediaController 当显示后,mediaController会铺满屏幕,
             * 所以VideoView的点击事件会被拦截,所以重写控制器的手势事件,
             * 将全部的操作全部写在控制器中,
             * 因为点击事件被控制器拦截,无法传递到下层的VideoView,
             * 所以 原来的单机隐藏会失效,作为代替,
             * 在手势监听中onSingleTapConfirmed()添加自定义的隐藏/显示,
             *
             * @param e
             * @return
             */
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                //当手势结束,并且是单击结束时,控制器隐藏/显示
                toggleMediaControlsVisiblity();
                return super.onSingleTapConfirmed(e);
            }
    
            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
    
            //滑动事件监听
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                float mOldX = e1.getX(), mOldY = e1.getY();
                int y = (int) e2.getRawY();
                int x = (int) e2.getRawX();
                Display disp = activity.getWindowManager().getDefaultDisplay();
                int windowWidth = disp.getWidth();
                int windowHeight = disp.getHeight();
                if (mOldX > windowWidth * 3.0 / 4.0) {// 右边滑动 屏幕 3/4
                    onVolumeSlide((mOldY - y) / windowHeight);
                } else if (mOldX < windowWidth * 1.0 / 4.0) {// 左边滑动 屏幕 1/4
                    onBrightnessSlide((mOldY - y) / windowHeight);
                }
                return super.onScroll(e1, e2, distanceX, distanceY);
            }
    
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                playOrPause();
                return true;
            }
    
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                return super.onFling(e1, e2, velocityX, velocityY);
            }
        }
    
        /**
         * 滑动改变声音大小
         *
         * @param percent
         */
        private void onVolumeSlide(float percent) {
            if (mVolume == -1) {
                mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                if (mVolume < 0)
                    mVolume = 0;
    
                // 显示
                mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
                mOperationTv.setVisibility(VISIBLE);
            }
    
            int index = (int) (percent * mMaxVolume) + mVolume;
            if (index > mMaxVolume)
                index = mMaxVolume;
            else if (index < 0)
                index = 0;
            if (index >= 10) {
                mOperationBg.setImageResource(R.drawable.volmn_100);
            } else if (index >= 5 && index < 10) {
                mOperationBg.setImageResource(R.drawable.volmn_60);
            } else if (index > 0 && index < 5) {
                mOperationBg.setImageResource(R.drawable.volmn_30);
            } else {
                mOperationBg.setImageResource(R.drawable.volmn_no);
            }
            //DecimalFormat    df   = new DecimalFormat("######0.00");
            mOperationTv.setText((int) (((double) index / mMaxVolume) * 100) + "%");
            // 变更声音
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
    
        }
    
        /**
         * 滑动改变亮度
         *
         * @param percent
         */
        private void onBrightnessSlide(float percent) {
            if (mBrightness < 0) {
                mBrightness = activity.getWindow().getAttributes().screenBrightness;
                if (mBrightness <= 0.00f)
                    mBrightness = 0.50f;
                if (mBrightness < 0.01f)
                    mBrightness = 0.01f;
    
                // 显示
                mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
                mOperationTv.setVisibility(VISIBLE);
    
            }
    
    
            WindowManager.LayoutParams lpa = activity.getWindow().getAttributes();
            lpa.screenBrightness = mBrightness + percent;
            if (lpa.screenBrightness > 1.0f)
                lpa.screenBrightness = 1.0f;
            else if (lpa.screenBrightness < 0.01f)
                lpa.screenBrightness = 0.01f;
            activity.getWindow().setAttributes(lpa);
    
            mOperationTv.setText((int) (lpa.screenBrightness * 100) + "%");
            if (lpa.screenBrightness * 100 >= 90) {
                mOperationBg.setImageResource(R.drawable.light_100);
            } else if (lpa.screenBrightness * 100 >= 80 && lpa.screenBrightness * 100 < 90) {
                mOperationBg.setImageResource(R.drawable.light_90);
            } else if (lpa.screenBrightness * 100 >= 70 && lpa.screenBrightness * 100 < 80) {
                mOperationBg.setImageResource(R.drawable.light_80);
            } else if (lpa.screenBrightness * 100 >= 60 && lpa.screenBrightness * 100 < 70) {
                mOperationBg.setImageResource(R.drawable.light_70);
            } else if (lpa.screenBrightness * 100 >= 50 && lpa.screenBrightness * 100 < 60) {
                mOperationBg.setImageResource(R.drawable.light_60);
            } else if (lpa.screenBrightness * 100 >= 40 && lpa.screenBrightness * 100 < 50) {
                mOperationBg.setImageResource(R.drawable.light_50);
            } else if (lpa.screenBrightness * 100 >= 30 && lpa.screenBrightness * 100 < 40) {
                mOperationBg.setImageResource(R.drawable.light_40);
            } else if (lpa.screenBrightness * 100 >= 20 && lpa.screenBrightness * 100 < 20) {
                mOperationBg.setImageResource(R.drawable.light_30);
            } else if (lpa.screenBrightness * 100 >= 10 && lpa.screenBrightness * 100 < 20) {
                mOperationBg.setImageResource(R.drawable.light_20);
            }
    
        }
    
    
        /**
         * 设置视频文件名
         *
         * @param name
         */
        public void setVideoName(String name) {
            videoname = name;
            if (mFileName != null) {
                mFileName.setText(name);
            }
        }
    
        /**
         * 隐藏或显示
         */
        private void toggleMediaControlsVisiblity() {
            if (isShowing()) {
                hide();
            } else {
                show();
            }
        }
    
        /**
         * 播放/暂停
         */
        private void playOrPause() {
            if (videoView != null)
                if (videoView.isPlaying()) {
                    videoView.pause();
                } else {
                    videoView.start();
                }
        }
    }
    
    • 自定义控制器布局文件:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    android:orientation="vertical"    
    android:layout_width="match_parent"    
    android:background="@drawable/video_player_bg_color"    
    android:layout_height="match_parent">    
    <RelativeLayout        
    android:layout_width="match_parent"        
    android:layout_height="match_parent">        
    <RelativeLayout            
    android:layout_width="match_parent"            
    android:background="#77000000"            
    android:layout_height="34dp">            
    <ImageButton                
    android:id="@+id/mediacontroller_top_back"                
    android:layout_width="50dp"                
    android:layout_height="match_parent"                
    android:layout_alignParentLeft="true"                
    android:background="@null"                
    android:src="@drawable/ic_player_close_white"/>            
    <TextView                
    android:id="@+id/mediacontroller_filename"                
    style="@style/MediaController_Text"                
    android:layout_width="wrap_content"                
    android:layout_height="wrap_content"                
    android:layout_centerVertical="true"                
    android:layout_marginLeft="5dp"                
    android:layout_toRightOf="@+id/mediacontroller_top_back"                
    android:ellipsize="marquee"                
    android:singleLine="true"               
    android:text="file name"/>            
    <ImageButton                
    android:id="@+id/mediacontroller_share"                
    android:layout_width="50dp"                
    android:layout_height="match_parent"                
    android:background="@null"                
    android:src="@drawable/ic_action_share_without_padding"                
    android:layout_alignParentRight="true"/>            
    <ImageButton                
    android:id="@+id/mediacontroller_favorite"                
    android:layout_width="50dp"                
    android:layout_height="match_parent"                
    android:background="@null"                
    android:layout_toLeftOf="@id/mediacontroller_share"                
    android:src="@drawable/ic_action_favorites"/>        
    </RelativeLayout>        
    <ImageButton            
    android:id="@+id/mediacontroller_play_pause"            
    android:layout_width="wrap_content"            
    android:layout_height="wrap_content"            
    android:layout_centerInParent="true"            
    android:src="@drawable/paly_selector"            
    android:background="@null"/>        
    <RelativeLayout            
    android:id="@+id/operation_volume_brightness"            
    android:layout_width="150dp"            
    android:layout_height="75dp"            
    android:layout_centerInParent="true"            
    android:background="@drawable/videobg"            
    android:orientation="horizontal"            
    android:padding="0dip"            
    android:visibility="gone">            
    <ImageView                
    android:id="@+id/operation_bg"                
    android:layout_width="wrap_content"                
    android:layout_height="wrap_content"                
    android:layout_centerInParent="true"                
    android:src="@drawable/video_volumn_bg"/>            
    <TextView                
    android:id="@+id/operation_tv"                
    android:layout_width="wrap_content"                
    android:layout_height="wrap_content"                
    android:layout_alignBottom="@+id/operation_bg"                
    android:layout_centerHorizontal="true"                
    android:layout_alignParentBottom ="true"                
    android:text="32:22/45:00"                
    android:textColor="#ffffff"                
    android:textSize="10sp"                
    android:visibility="gone"               
    />        
    </RelativeLayout>        
    <RelativeLayout            
    android:layout_width="match_parent"            
    android:layout_alignParentBottom="true"            
    android:background="#77000000"            
    android:layout_height="50dp">            
    <TextView                
    android:id="@+id/mediacontroller_time_current"                
    style="@style/MediaController_Text"                
    android:layout_width="wrap_content"                
    android:layout_height="wrap_content"                
    android:layout_centerVertical="true"                
    android:layout_marginLeft="15dp"                
    android:text="33:33:33"                
    />            
    <TextView                
    android:id="@+id/mediacontroller_time_total"                
    style="@style/MediaController_Text"                
    android:layout_width="wrap_content"                
    android:layout_height="wrap_content"                
    android:layout_alignParentRight="true"                
    android:layout_centerVertical="true"                
    android:layout_marginRight="15dp"                
    android:text="33:33:33"/>            
    <SeekBar                
    android:id="@+id/mediacontroller_seekbar"                
    style="@style/MediaController_SeekBar"                
    android:layout_width="match_parent"                
    android:layout_height="wrap_content"                
    android:layout_centerVertical="true"                
    android:layout_toLeftOf="@id/mediacontroller_time_total"                
    android:layout_toRightOf="@id/mediacontroller_time_current"                
    android:focusable="true"                
    android:max="1000"/>        
    </RelativeLayout>    
    </RelativeLayout>
    </LinearLayout>
    
    • 视频播放界面布局:
    <?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.CenterLayout        
    android:layout_width="match_parent"        
    android:layout_height="match_parent"        
    android:orientation="vertical">        
    <io.vov.vitamio.widget.VideoView            
    android:id="@+id/buffer"            
    android:layout_width="match_parent"            
    android:layout_height="match_parent"            
    android:layout_centerHorizontal="true"            
    android:layout_centerVertical="true" />    
    </io.vov.vitamio.widget.CenterLayout>    
    <LinearLayout        
    android:layout_width="wrap_content"        
    android:layout_height="wrap_content"        
    android:layout_centerInParent="true"        
    android:orientation="horizontal">        
    <ProgressBar            
    android:id="@+id/probar"            
    style="?android:attr/progressBarStyleLarge"            
    android:layout_width="50dp"            
    android:layout_height="50dp" />        
    <TextView            
    android:id="@+id/download_rate"            
    android:layout_width="wrap_content"            
    android:layout_height="wrap_content"            
    android:layout_gravity="center"            
    android:textColor="#FFFFFF"           
    android:text="" />        
    <TextView            
    android:id="@+id/load_rate"            
    android:layout_width="wrap_content"            
    android:layout_height="wrap_content"            
    android:layout_gravity="center"            
    android:textColor="#FFFFFF"            
    android:text="" />    
    </LinearLayout>
    </RelativeLayout>
    

    解决部分视频不能全屏播放###

    播放界面的布局如下,即可拉伸视频,主要不要嵌套vitamio自定义的CenterLayout布局

    <!--解决部分视频视频由于分辨率问题,不能全屏播放,在此处不要嵌套vitamio的CenterLayout布局-->
        <!--<io.vov.vitamio.widget.CenterLayout-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="match_parent"-->
            <!--android:orientation="vertical">-->
    
            <io.vov.vitamio.widget.VideoView
                android:id="@+id/buffer"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_alignParentRight="true"
                android:layout_alignParentBottom="true"/>
    
        <!--</io.vov.vitamio.widget.CenterLayout>-->
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:orientation="horizontal">
    
            <ProgressBar
                android:id="@+id/probar"
                style="?android:attr/progressBarStyleLarge"
                android:layout_width="50dp"
                android:layout_height="50dp"/>
    
            <TextView
                android:id="@+id/download_rate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text=""
                android:textColor="#FFFFFF"/>
    
            <TextView
                android:id="@+id/load_rate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text=""
                android:textColor="#FFFFFF"/>
        </LinearLayout>
    
    </RelativeLayout>
    

    github地址
    写的不好之处还望大家见谅。、

    如果觉得文章帮到你,不求打赏,喜欢我的文章可以关注我和朋友一起运营的微信公众号,将会定期推送优质技术文章,求关注~~~##

    欢迎关注“大话安卓”公众号

    欢迎加入“大话安卓”技术交流群,一起分享,共同进步##

    欢迎加入“大话安卓”技术交流群,互相学习提升

    相关文章

      网友评论

      • 0a70bbb8e40e:楼主,我发现一个问题,运行你的项目后,在播放界面使用手势控制音量和亮度,发现根本不生效,我在GestureDetector方法里面打印日志发现根本没执行,但是在acticity界面里面使用GestureDetector进行手势监听发现可以生效。
      • 0a70bbb8e40e:你好,我下载了你的demo,把你的链接换了,然后我自己在云服务器里面放置了一些资源视频进去,我用其他的浏览器测试过了可以访问,但是运行你这个Demo的时候一直在主界面有个圈一直再转,半天都没加载出视频来啊? 我用的安卓7.0的真机测试的,请问大概是什么问题造成的?
      • 4c99b183a8c3:demo里的icon图片无法下载了
      • 8a5de26d7ba5:能设置播放倍数吗
        jxnk25:@我想换个网名了 vitamio商用要付费
        8a5de26d7ba5:@jxnk25 用ijk后,按照它的方法设置倍数出现问题了,不知道咋搞了,打算换一个库
        jxnk25:@我想换个网名了 播放倍数?目前不建议使用vitamio了哦,可以适应哔哩哔哩开源的ijk播放器
      • OneBelowZero:不支持部分视频播放?
        http://hehe.heheedu.com/uploadFiles/resources/2017/09/14/0f2eaba594f845ebad9bd5305bcecbec.mp4
        OneBelowZero:@jxnk25 嗯 已成功编译并使用了ijkplayer 发现也不行 原因是部分url部分会重定向以及会加密 导致ijkplayer和vitamio都不能在线播放 最后只能使用节操 或者mediaplayer+surface。
        jxnk25:@OneBelowZero 目前建议使用哔哩哔哩开源的播放器比vitamio更加好上手一些
      • 2143410bedcf:能问下我用module方式导入7.0以上版本手机,播放视频直接崩溃,低版本没有问题,希望能解答一下
        jxnk25:@小智_fd4b 7.0貌似不支持
        建议使用ijk 吧
      • 610e04b8ceec:WindowManager.LayoutParams.FLAG_FULLSCREEN
        这里有没有不全屏的参数啊
        我是想让窗体和视频一样大小
      • Stunner_W:用于企业要收费,用于个人免费。意思就是个人项目可以使用,但是公司项目的话不行?
        jxnk25:@Stunner_W 是的
      • 3e566325ea53:楼主 我想问一下 当mediacontroller是隐藏状态的时候 还怎么响应滑动事件 我想了很多办法不行 请问楼主有解决方法吗?
      • ssaaqq:楼主大大问个问题,比方说我的视频60秒,我用seekto跳转到60秒,为毛它自动给我返回10s左右,从50秒左右开始播放的,怎么解决
      • 7bdac540fd9a:楼主 我集成了项目之后 项目里的这一行代码报错 if (!LibsChecker.checkVitamioLibs(this)) {
        return;
        }
        报的是 LibsChecker找不到,可我导入的module 是官网下载的最新的呀
        jxnk25:最新的SDK,好像不需要这个判断了
      • fa47c82221a6:请教一下作者,横竖屏切换的时候怎么设置从当前位置播放,不从头开始
        jxnk25:@Roc_ 仔细看下我的文章里面贴出来的代码,有保存进度的方法
      • parkbaird:怎么小屏播放啊 小屏切换全屏
        jxnk25:@lt南墙 啥工具类
        parkbaird:@jxnk25 你居然不把你工具类贡献出来:flushed:
        jxnk25:@lt南墙 横竖屏切换
      • bb106613a129:Error:smallestScreenSize|keyboard|keyboardHidden) from AndroidManifest.xml:76:13-102
        Error:smallestScreenSize|keyboard|keyboardHidden|navigation).
        我按照说明配置完了,为什么报这个错误啊?
      • FlyMing123:支不支持直播?
        jxnk25:@FlyMing123 直播是可以的,由于vitamio商业收费,建议可以使用现在比较火的ijk视频播放框架
      • 潇洒的夏夏:用的vitamio是哪个版本的,是最新sdk5.2吗
        jxnk25:@潇洒的夏夏 github上用了最新的
      • 27c7534af0e9:现在遇到一个问题,就是当视频播放时,我锁屏,视频还会继续播放而且是重头开始,求解!
        jxnk25:@靠靠果 你看下我的这篇文章,我新增了如何保存的方法。
        27c7534af0e9: @jxnk25 怎么保存?我现在按home健,接电话,再重新回到视频播放页面,我在代码中没做任何操作,视频播到哪里就是那里,但是唯独锁频,不知道怎么保存,也没找到其中的方法,求指教
        jxnk25:@靠靠果 没有保存当前播放进度
      • jxnk25:循环播放么?这个我好像没做,其实就是重新将视频进度设置到开始位置。由于vitamio的商业收费限制,现在建议使用ijkplayer播放框架哈
        李艳珍:嗯,好的,谢谢!
      • 李艳珍:你好,我想知道你重复播放的是怎么做的?你有这个功能吗?我是流媒体格式的视频播放
        jxnk25:@李艳珍 重复播放没做,这个我好像没做,其实就是重新将视频进度设置到开始位置。你可以看下,就是设置VideoView 的position
      • 4b5624f4a07c:不太明白:
        MediaController mMediaController;
        CustomMediaController mCustomMediaController;

        为什么需要两个Controller,它们各自的职责是什么啊。不太理解,谢谢
        4b5624f4a07c:@jxnk25 非常感谢,之前弄懂了。现在vitamio不支持6.0的手机啊,知道怎么解决吗
        jxnk25:@一分逍遥 继承了MediaController,MediaController中作了处理
        4b5624f4a07c:还有一个是CustomMediaController中Seekbar好像没有关联控件啊,但是打开app拖动有效为啥呢
      • 翻身不做咸鱼:这个框架个人是免费的,如果用于企业要收费的吧
        jxnk25:@LinQG 是的,我的文章开头进行了说明的
      • 0a24b6438a9b:楼主,最新版本的vitamio5.0.2并不能播放音频文件...怎么办,很着急
      • 8a1133fffe23:先学习一下,感谢分享
      • aad38be4061a:楼主,我遇到一个问题,比方说我只要界面上面一部分播放视频,怎么让mediacontroller和videoview绑在一起呢?我的mediacontroller始终在屏幕的中间
        赵梦0915:setheight(getHeight.....)
        b210e135e7d8:去看下MediaController的源码。在show方法里面对mAnchor的位置重新设置了如下。如果有需要的。可以修改下该部分的代码。如果显示在顶部。可以把anchorRect.bottom改成0。

        mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, anchorRect.left, anchorRect.bottom);
      • chris_wu:先Mark
      • Fi7z:格式化下代码再发到简书上更好,这样看太吃力了
        jxnk25:@backkomyoung 好的,谢谢 :stuck_out_tongue_closed_eyes:
        Fi7z:@jxnk25 你在桌面上新建一个txt,然后把代码从AS中复制到txt,再从txt复制到简书上格式就不会乱的。偶然发现的。
        jxnk25:@backkomyoung 恩,第一次在简书上写,在AS上格式化过,copy过来之后格式就乱了
      • 键盘男:加了vgtamio,仅支持arm64,apk增大多少?
        jxnk25:@键盘男kkmike999 整体有增加一些,不是很多,具体没注意看 :sweat:
      • ab72c065186a:楼主我想提问几个问题:1.vitamio 没有缓冲这个问题怎么解决。 2.竖屏的时候播放小视频等到用户横屏的时候切换全屏并继续上次播放,这个有什么比较好的思路去完成。
        ab72c065186a:@jxnk25 对于第二个问题,之前我做的也是竖屏要切换横屏保存播放进度,然后跳转Activity,不过这样用户体验不太好,其一是因为切换后需要重新加载进度,比如竖屏加载了100%你一切换又要重新开始加载了。第二是视频切换前后连接有点误差,误差秒数大概会在5s内。。。。,缓冲问题找到了记得回答我哟 :kissing_heart:
        jxnk25:@凶残的程序员 1.缓冲的问题我也还在找,后面回答你
        2.横竖屏切换的问题,可以在切换的时候保存一下当前的播放进度,切换过去时再将进度获取到。
      • Marno:666,肖总,你的文章已经收录到稀土掘金了
        jxnk25:@Marno :blush:

      本文标题:功能强大的Vitamio视频播放器的使用教程

      本文链接:https://www.haomeiwen.com/subject/awlzrttx.html