使用 Kotlin 读取本地视频并使用Vitamio框架编写万能播放器进行播放(二)

#  使用 Kotlin 读取本地视频并使用Vitamio框架编写万能播放器进行播放(二)  #




## 一自定义一个VitamioVideoView ##

    public class VitamioVideoView extends io.vov.vitamio.widget.VideoView{

    public VitamioVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);//保持测量结果
    }

    /**
     * 设置视频的画面大小
     * @param width 要设置视频的宽
     * @param height 要设置视频的高
     */
    public void setVideoSize(int width,int height){
        ViewGroup.LayoutParams params = getLayoutParams();
        params.width = width;
        params.height = height;
        setLayoutParams(params);
    }


    }
说明:
 1.此view继承于io.vov.vitamio.widget.VideoView,主要自定义高度

 2.怎么添加vitamio库,你先在官网下vitamio, [https://www.vitamio.org/Download/](https://www.vitamio.org/Download/ "vitamio官网")
 然后导入你的项目File-->New-->Import Moudle ,导入你的项目之后,在你moudle引用即可

   ` compile project(':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">

    <LinearLayout
        android:id="@+id/ll_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_player_status"
            android:gravity="center_vertical"

            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_weight="1"
                android:text="视频的名称"
                android:textColor="#ffffff" />

            <ImageView
                android:id="@+id/iv_battery"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:src="@drawable/ic_battery_0" />


            <TextView
                android:id="@+id/tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:text="系统时间"
                android:textColor="#ffffff" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_player_top_control"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_voice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:background="@drawable/btn_voice_selector" />

            <SeekBar
                android:id="@+id/seekbar_voice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:maxHeight="6dp"
                android:minHeight="6dp"
                android:progress="20"
                android:progressDrawable="@drawable/progress_horizontal"
                android:thumb="@drawable/progress_thumb" />


            <Button
                android:id="@+id/btn_switch_player"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:background="@drawable/btn_switch_player_selector" />

        </LinearLayout>

    </LinearLayout>


    <LinearLayout
        android:id="@+id/ll_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_player_bottom_seekbar"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_current_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:text="01:20:30" />

            <SeekBar
                android:id="@+id/seekbar_video"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:maxHeight="6dp"
                android:minHeight="6dp"
                android:progress="20"
                android:progressDrawable="@drawable/progress_horizontal"
                android:thumb="@drawable/progress_thumb" />


            <TextView
                android:id="@+id/tv_duration"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:text="02:20:30" />

        </LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/bg_player_bottom_control"
            android:gravity="center"
            android:orientation="horizontal">

            <Button

                android:id="@+id/btn_video_exit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/btn_video_exit_selector" />


            <Button
                android:id="@+id/btn_video_pre"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/btn_video_pre_selector" />


            <Button
                android:id="@+id/btn_video_start_pause"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/btn_video_pause_selector" />


            <Button
                android:id="@+id/btn_video_next"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/btn_video_next_selector" />


            <Button
                android:id="@+id/btn_video_switch_screen"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/btn_switch_screen_full_selector" />

        </LinearLayout>


    </LinearLayout>

    </RelativeLayout>

主要是暂停 ,播放,下一个,上一个,视频的播放进度条,音量的进度条,电量等

在引用VitamioVideoView

     <com.modlileplayertest.VitamioVideoView
        android:id="@+id/videoview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />


## 三点击视频列表跳转 ##

之前写过使用 Kotlin 读取本地视频并使用Vitamio框架编写万能播放器进行播放(一)有兴趣的可以看一下

http://blog.csdn.net/o_xiaojian/article/details/72954689

这个主要说怎么使用Vitamio来播放视频实现声音,亮度,播放进度的改变



通过接口的回调,判断点击的是哪个item

传值跳转

     //传视频列表this
        val intent = Intent(this, SystemVideoPlayer::class.java)
        val bundle = Bundle()
        bundle.putSerializable("videolist", list)//视频列表信息
        intent.putExtras(bundle)
        intent.putExtra("position", property)//点击的是哪个item
        startActivity(intent)

接收

      val  mediaItems = getIntent().getSerializableExtra("videolist") as ArrayList<VideoBeen>?;

     val   position = getIntent().getIntExtra("position", 0);//列表中的位置



##     四初始化解码器 ##

        //初始化解码器
        Vitamio.isInitialized(applicationContext)


## 五播放视频 ##

1先判断是本地还是网络视频 如果是本地视频 给videoview设置播放视频的地址 和视频的名称
    private fun setData() {
        if (mediaItems != null && mediaItems!!.size > 0) {
            val mediaItem = mediaItems!![position]
            videoview!!.setVideoPath(mediaItem.data)

            tv_name!!.text = mediaItem.name
            isNetUri = utils!!.isNetUri(mediaItem.data)
        } else if (uri != null) {
            videoview!!.setVideoURI(uri)
            tv_name!!.text = uri!!.toString()
            isNetUri = utils!!.isNetUri(uri!!.toString())
        }

        setButtonState()

        //设置不锁屏
        videoview!!.keepScreenOn = true
        //        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    }


2.测试调用  ` videoview!!.start()//开始播放` 就可以播放了



3.设置播放监听 
   设置视频的总长度      

         val duration = videoview.duration.toInt()
            seekbar_video.max = duration


  视频播放   `videoview.start()//开始播放`


  视频播放的有记录

      if (mediaItems != null && mediaItems!!.size > 0) {
                val key = mediaItems!![position].data
                val history = CacheUtils.getInt(this@VitamioVideoPlayer, key)
                if (history > 0) {
                    videoview.seekTo(history.toLong())
                }
            }



源码


     private fun setListener() {
        //当底层解码器准备好的时候,回调这个方法
        videoview.setOnPreparedListener { mp ->
        
            videoWidth = mp.videoWidth
            videoHeight = mp.videoHeight

            //1.得到视频的总时长和SeeKBar.setMax();
            val duration = videoview.duration.toInt()
            seekbar_video.max = duration

            //设置总时长
            tv_duration.text = utils!!.stringForTime(duration)

            //2.发消息更新
            handler.sendEmptyMessage(PROGRESS)

            videoview.start()//开始播放

            if (mediaItems != null && mediaItems!!.size > 0) {
                val key = mediaItems!![position].data
                val history = CacheUtils.getInt(this@VitamioVideoPlayer, key)
                if (history > 0) {
                    videoview.seekTo(history.toLong())
                }
            } else if (uri != null) {
                val key = uri.toString()
                val history = CacheUtils.getInt(this@VitamioVideoPlayer, key)
                if (history > 0) {
                    videoview.seekTo(history.toLong())
                }
            }
            hideMediaController()

            setVideType(DEFAULT_SCREEN)
            //隐藏加载页面
            rl_loading.visibility = View.GONE
        }

        //当播放出错的时候回调这个方法
        videoview.setOnErrorListener { mp, what, extra ->
            //                Toast.makeText(SystemVideoPlayer.this, "播放出错了", Toast.LENGTH_SHORT).show();
            //1.播放不支持的视频格式
            //2.播放网络视频的过程中-网络中断 - 重新播放
            //3.视频文件中间部分有缺损---把下载模块解决掉
            showErrorDialog()
            true
        }

        //当播放完成的时候回调这个方法
        videoview.setOnCompletionListener {
            //                Toast.makeText(SystemVideoPlayer.this, "播放完成", Toast.LENGTH_SHORT).show();
            //                finish();
            setPlayNext()
        }

        seekbar_video.setOnSeekBarChangeListener(VideoOnSeekBarChangeListener())

        seekbar_voice.setOnSeekBarChangeListener(VoiceOnSeekBarChangeListener())

      
    }




4.设置视屏播放的进度条的监听


写个内部类 ,实现SeekBar.OnSeekBarChangeListener的监听



    internal inner class VideoOnSeekBarChangeListener : SeekBar.OnSeekBarChangeListener {

        /**
         * 当进度跟新的时候回调这个方法

         * @param seekBar
         * *
         * @param progress 当前进度
         * *
         * @param fromUser 是否是由用于引起
         */
        override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
            if (fromUser) {
                videoview.seekTo(progress.toLong())
            }

        }

        /**
         * 当手触碰SeekBar的时候回调这个方法

         * @param seekBar
         */
        override fun onStartTrackingTouch(seekBar: SeekBar) {
            handler.removeMessages(HIDE_MEDIACONTROLLER)
        }

        /**
         * 当手指离开SeeKbar的时候回调这个方法

         * @param seekBar
         */
        override fun onStopTrackingTouch(seekBar: SeekBar) {
            handler.sendEmptyMessageDelayed(HIDE_MEDIACONTROLLER, 5000)
        }
    }

5.电池电量的设置 通过发送广播

   发广播

        val intentFilter = IntentFilter()
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED)
        receiver = BatteryReceiver()
        registerReceiver(receiver, intentFilter)

 广播的接收

    internal inner class BatteryReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            val level = intent.getIntExtra("level", 0)//电量:0~100
            //主线程
            setBattery(level)
        }
    }

6.声音的调节

     override fun onTouchEvent(event: MotionEvent): Boolean {
        //3.把事件给手势识别器解析
        detector!!.onTouchEvent(event)
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                //1.按下的时候记录初始值
                startY = event.y
                touchRang = Math.min(screenHeight, screenWidth).toFloat()//screenHeight
                mVol = am!!.getStreamVolume(AudioManager.STREAM_MUSIC)
                handler.removeMessages(HIDE_MEDIACONTROLLER)
            }
            MotionEvent.ACTION_MOVE -> {
                //2.来到新的坐标
                val endY = event.y
                //3.计算偏移量
                val distanceY = startY - endY
                //屏幕滑动的距离: 总距离 = 改变的声音: 最大音量
                val changVolume = distanceY / touchRang * maxVolume

                //最终的声音= 原来的音量 + 改变的声音;
                val volume = Math.min(Math.max(mVol + changVolume, 0f), maxVolume.toFloat())

                if (changVolume != 0f) {
                    updateVolumeProgress(volume.toInt())
                }
            }
            MotionEvent.ACTION_UP -> handler.sendEmptyMessageDelayed(HIDE_MEDIACONTROLLER, 5000)
        }//                startY = event.getY();
        return super.onTouchEvent(event)
    }





最后附上源码
链接: `http://pan.baidu.com/s/1kVuoUpx` 密码:9rmo




 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值