使用 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
使用 Kotlin 读取本地视频并使用Vitamio框架编写万能播放器进行播放(二)相关推荐
- python播放本地视频_python opencv 读取本地视频文件 修改ffmpeg的方法
Python + opencv 读取视频的三种情况: 情况一:通过摄像头采集视频 情况二:通过本地视频文件获取视频 情况三:通过摄像头录制视频,再读取录制的视频 摄像头采集.本地视频文件的读取.写视频 ...
- 基于PyQt5实现读取本地视频后循环、洗脑播放
基于Python和PyQt5实现读取本地视频后循环播放 在实现读取视频的程序代码中有如下一行代码: flag, self.image = self.cap.read() 当读取到视频时flag为Tru ...
- Android中调用系统已安装的播放器来播放网络流媒体视频
2019独角兽企业重金招聘Python工程师标准>>> 实现思路比较简单几行代码就可以搞定,在界面放一个Button或者带有播放图标的imageview,点击事件中调用本地播放器来播 ...
- 多个VLC播放器同步播放本地VCam视频流
多个VLC播放器同步播放本地VCam视频流 配置如下: 下载安装VLC播放器,VCam虚拟摄像头 VCam打开一个视频文件 VLC设置捕获设备选择适配设备名称为e2esoft VCam:然后点击播放 ...
- 视频在html不能播放器,网页无插件直播H265编码视频播放器EasyPlayer网页播放器不能播放怎么处理?...
原标题:网页无插件直播H265编码视频播放器EasyPlayer网页播放器不能播放怎么处理? EasyPlayer播放器系列项目提供了非常简单易用的SDK及API接口,用户通过API调用就可以非常快速 ...
- C# 视频监控系列(13):H264播放器——控制播放和截图
C# 视频监控系列(13):H264播放器--控制播放和截图 前言 本该把这部分和上一篇合成一篇的,无奈挣扎半天,还是想对称起来,客户端3篇.服务器端3篇--所有播放器也勉强凑3篇吧(封装API的文章 ...
- openGL ES进阶教程(五)制作一个简单的VR播放器,播放全景视频
之前写过全景(VR)图片,和用openGL ES+MediaPlayer 渲染播放视频+滤镜效果 这一篇就在之前的基础上实现一个最简单的VR播放器,播放全景视频. 概述: 全景视频是一种用3D摄像机进 ...
- Win10系统播放器无法播放视频怎么办【系统天地】
Win10自带的视频播放器叫做"电影和电视",简洁轻巧,如果没有安装第三方视频播放器,那么"电影和电视"也是个不错的选择,不过有时受其他软件或情况的影响,播放器 ...
- 沪江日语百度云视频 0-n1百度云网盘视频的swf需要特定的播放器才能播放
Mark一下,沪江日语百度云视频 0-n1百度云网盘视频的swf需要特定的播放器才能播放, 测试下来SWF Player 0.3无限制版可以
- 任何播放器无法播放视频
最近播放器无法播放视频文件..试了好几种播放器.都没有效果.最后只能在网上搜索答案了.在百度知道找到了一个类似的情况,但是只是说dll没有注册没有给出具体的修复方法,只能自己在搜索了.最后尝试了一下原 ...
最新文章
- java调优 视频_Java优化高性能高并发+高并发程序设计视频教程
- Netty实战 IM即时通讯系统(六)实战: 客户端和服务端双向通信
- java程序 输入10个数字并求和
- 导致Android手机崩溃的壁纸,使用错误的壁纸会使你的Android手机崩溃
- eclipse中配置jad反编译插件
- spring中@Value的使用(读取配置文件信息)
- 无法登录a6服务器可以修复么,航天A6登录常见问题
- 计算机网络数据链路层封装,计算机网络(3.3)数据链路层- 封装成帧
- android获取服务器时间格式,Android 获取服务器与客户端时差的实例代码
- Python-docx 读取word.docx内容
- SQL 2012企业版安装教程
- 将哔哩哔哩手机端缓存视频导出为正常mp4视频.
- Echarts 用GeoJson数据绘制地图
- 【用PROTEUS仿真点亮LED项目】
- Linux 远程工具 基础命令
- 这3款免费的Word转PDF转换器软件,建议收藏使用
- STM32内存分布学习
- 我的input /不可能这么可爱
- 去雾综述_偏振光学成像去雾技术综述
- R ggplot绘制双纵坐标轴