#  使用 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

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

  1. python播放本地视频_python opencv 读取本地视频文件 修改ffmpeg的方法

    Python + opencv 读取视频的三种情况: 情况一:通过摄像头采集视频 情况二:通过本地视频文件获取视频 情况三:通过摄像头录制视频,再读取录制的视频 摄像头采集.本地视频文件的读取.写视频 ...

  2. 基于PyQt5实现读取本地视频后循环、洗脑播放

    基于Python和PyQt5实现读取本地视频后循环播放 在实现读取视频的程序代码中有如下一行代码: flag, self.image = self.cap.read() 当读取到视频时flag为Tru ...

  3. Android中调用系统已安装的播放器来播放网络流媒体视频

    2019独角兽企业重金招聘Python工程师标准>>> 实现思路比较简单几行代码就可以搞定,在界面放一个Button或者带有播放图标的imageview,点击事件中调用本地播放器来播 ...

  4. 多个VLC播放器同步播放本地VCam视频流

    多个VLC播放器同步播放本地VCam视频流 配置如下: 下载安装VLC播放器,VCam虚拟摄像头 VCam打开一个视频文件 VLC设置捕获设备选择适配设备名称为e2esoft VCam:然后点击播放 ...

  5. 视频在html不能播放器,网页无插件直播H265编码视频播放器EasyPlayer网页播放器不能播放怎么处理?...

    原标题:网页无插件直播H265编码视频播放器EasyPlayer网页播放器不能播放怎么处理? EasyPlayer播放器系列项目提供了非常简单易用的SDK及API接口,用户通过API调用就可以非常快速 ...

  6. C# 视频监控系列(13):H264播放器——控制播放和截图

    C# 视频监控系列(13):H264播放器--控制播放和截图 前言 本该把这部分和上一篇合成一篇的,无奈挣扎半天,还是想对称起来,客户端3篇.服务器端3篇--所有播放器也勉强凑3篇吧(封装API的文章 ...

  7. openGL ES进阶教程(五)制作一个简单的VR播放器,播放全景视频

    之前写过全景(VR)图片,和用openGL ES+MediaPlayer 渲染播放视频+滤镜效果 这一篇就在之前的基础上实现一个最简单的VR播放器,播放全景视频. 概述: 全景视频是一种用3D摄像机进 ...

  8. Win10系统播放器无法播放视频怎么办【系统天地】

    Win10自带的视频播放器叫做"电影和电视",简洁轻巧,如果没有安装第三方视频播放器,那么"电影和电视"也是个不错的选择,不过有时受其他软件或情况的影响,播放器 ...

  9. 沪江日语百度云视频 0-n1百度云网盘视频的swf需要特定的播放器才能播放

    Mark一下,沪江日语百度云视频 0-n1百度云网盘视频的swf需要特定的播放器才能播放, 测试下来SWF Player 0.3无限制版可以

  10. 任何播放器无法播放视频

    最近播放器无法播放视频文件..试了好几种播放器.都没有效果.最后只能在网上搜索答案了.在百度知道找到了一个类似的情况,但是只是说dll没有注册没有给出具体的修复方法,只能自己在搜索了.最后尝试了一下原 ...

最新文章

  1. java调优 视频_Java优化高性能高并发+高并发程序设计视频教程
  2. Netty实战 IM即时通讯系统(六)实战: 客户端和服务端双向通信
  3. java程序 输入10个数字并求和
  4. 导致Android手机崩溃的壁纸,使用错误的壁纸会使你的Android手机崩溃
  5. eclipse中配置jad反编译插件
  6. spring中@Value的使用(读取配置文件信息)
  7. 无法登录a6服务器可以修复么,航天A6登录常见问题
  8. 计算机网络数据链路层封装,计算机网络(3.3)数据链路层- 封装成帧
  9. android获取服务器时间格式,Android 获取服务器与客户端时差的实例代码
  10. Python-docx 读取word.docx内容
  11. SQL 2012企业版安装教程
  12. 将哔哩哔哩手机端缓存视频导出为正常mp4视频.
  13. Echarts 用GeoJson数据绘制地图
  14. 【用PROTEUS仿真点亮LED项目】
  15. Linux 远程工具 基础命令
  16. 这3款免费的Word转PDF转换器软件,建议收藏使用
  17. STM32内存分布学习
  18. 我的input /不可能这么可爱
  19. 去雾综述_偏振光学成像去雾技术综述
  20. R ggplot绘制双纵坐标轴

热门文章

  1. MQTT、CoAP 还是 LwM2M?主流物联网协议如何选择
  2. Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
  3. 小白学习倍福的必经之路
  4. 服务式GIS实践与发展——REST 服务
  5. MySQL经典练习50题
  6. java编写猜数字游戏_java编写猜数字游戏
  7. Linux操作系统(3.2.14find)
  8. jQuery WeUI动态获取省地市三级联动
  9. java:数据结构面试题
  10. haneWin NFS服务器配置