使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放
一、实现目标
1.1 亮度控制
模仿VPlayer界面:
1.2 声音控制
模仿VPlayer界面:
1.3 画面缩放
根据下面API提供画面的拉伸、剪切、100%、全屏
二、Vitamio API 介绍
VideoView
2.1 public void start()
开始播放
2.2 public void pause()
暂停播放
2.3 public long getDuration()
获取视频的时长
2.4 public long getCurrentPosition()
获取已经播放的时长
2.5 public void seekTo(long msec)
设置播放器从指定的位置开始播放
2.6 public boolean isPlaying()
是否正在播放
2.7 public int getVideoWidth()
获取视频宽
2.8 public int getVideoHeight()
获取视频高
2.9 public void setBufferSize(int bufSize)
设置缓存大小,默认1024KB
2.10 public void setVideoQuality(int quality)
设置视频质量,低、中、高(MediaPlayer.VIDEOQUALITY_LOW、MediaPlayer.VIDEOQUALITY_MEDIUM 、MediaPlayer.VIDEOQUALITY_HIGH ),
默认低(最流畅)。
2.11 public void setSubShown(boolean shown)
设置是否显示字幕
2.12 public void setAudioTrack(int audioIndex)
设置音轨,必须是getAudioTrackMap(String) 的返回值。
2.13 public void setVolume(float leftVolume, float rightVolume)
设置立体音左右音量。
2.14 public void setSubPath(String subPath)
设置外挂字幕路径
2.15 public int getBufferPercentage()
获取缓冲百分比
2.16 public void stopPlayback()
停止播放
2.17 public void setVideoPath(String path)
设置视频播放路径
2.18 public void setVideoURI(Uri uri)
设置视频播放路径
2.19 public void setVideoLayout(int layout, float aspectRatio)
设置视频缩放(拉伸、剪切、100%、全屏)
三、 实现代码
3.1 xml
?xml version="1.0" encoding="utf-8"?RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
io.vov.vitamio.widget.VideoView
android:id="@+id/surface_view" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_centerHorizontal="true"
android:layout_centerVertical="true" /
FrameLayout android:id="@+id/operation_volume_brightness"
android:visibility="invisible" android:layout_centerInParent="true"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="#00000000" android:orientation="horizontal"
android:padding="0dip"
ImageView android:id="@+id/operation_bg"
android:layout_gravity="center" android:src="@drawable/video_volumn_bg"
android:layout_width="wrap_content" android:layout_height="wrap_content" /
FrameLayout android:layout_gravity="bottom|center_horizontal"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="25dip"
ImageView android:id="@+id/operation_full"
android:layout_gravity="left" android:src="@drawable/video_num_bg"
android:layout_width="94dip" android:layout_height="wrap_content" /
ImageView android:id="@+id/operation_percent"
android:layout_gravity="left" android:src="@drawable/video_num_front"
android:layout_width="0dip" android:layout_height="wrap_content"
android:scaleType="matrix" /
/FrameLayout
/FrameLayout
/RelativeLayout
3.2 Activity
/***
* Android万能播放器
*
* @author 农民伯伯
* @version 2012-5-22
*
*/
public class VideoViewDemo extends Activity {
private String path = Environment.getExternalStorageDirectory()
+ "/Moon.mp4";
private VideoView mVideoView;
private View mVolumeBrightnessLayout;
private ImageView mOperationBg;
private ImageView mOperationPercent;
private AudioManager mAudioManager;
/** 最大声音 */
private int mMaxVolume;
/** 当前声音 */
private int mVolume = -1;
/** 当前亮度 */
private float mBrightness = -1f;
/** 当前缩放模式 */
private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
private GestureDetector mGestureDetector;
private MediaController mMediaController;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.videoview);
mVideoView = (VideoView) findViewById(R.id.surface_view);
mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
mOperationBg = (ImageView) findViewById(R.id.operation_bg);
mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mMaxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mVideoView.setVideoPath(path);
mMediaController = new MediaController(this);
mVideoView.setMediaController(mMediaController);
mVideoView.requestFocus();
mGestureDetector = new GestureDetector(this, new MyGestureListener());
}
@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;
// 隐藏
mDismissHandler.removeMessages(0);
mDismissHandler.sendEmptyMessageDelayed(0, 500);
}
private class MyGestureListener extends SimpleOnGestureListener {
/** 双击 */
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
else
mLayout++;
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
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();
Display disp = getWindowManager().getDefaultDisplay();
int windowWidth = disp.getWidth();
int windowHeight = disp.getHeight();
if (mOldX windowWidth * 4.0 / 5)// 右边滑动
onVolumeSlide((mOldY - y) / windowHeight);
else if (mOldX windowWidth / 5.0)// 左边滑动
onBrightnessSlide((mOldY - y) / windowHeight);
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
/** 定时隐藏 */
private Handler mDismissHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mVolumeBrightnessLayout.setVisibility(View.GONE);
}
};
/**
* 滑动改变声音大小
*
* @param percent
*/
private void onVolumeSlide(float percent) {
if (mVolume == -1) {
mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (mVolume 0)
mVolume = 0;
// 显示
mOperationBg.setImageResource(R.drawable.video_volumn_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
int index = (int) (percent * mMaxVolume) + mVolume;
if (index mMaxVolume)
index = mMaxVolume;
else if (index 0)
index = 0;
// 变更声音
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
// 变更进度条
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = findViewById(R.id.operation_full).getLayoutParams().width
* index / mMaxVolume;
mOperationPercent.setLayoutParams(lp);
}
/**
* 滑动改变亮度
*
* @param percent
*/
private void onBrightnessSlide(float percent) {
if (mBrightness 0) {
mBrightness = getWindow().getAttributes().screenBrightness;
if (mBrightness = 0.00f)
mBrightness = 0.50f;
if (mBrightness 0.01f)
mBrightness = 0.01f;
// 显示
mOperationBg.setImageResource(R.drawable.video_brightness_bg);
mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
}
WindowManager.LayoutParams lpa = 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;
getWindow().setAttributes(lpa);
ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
mOperationPercent.setLayoutParams(lp);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mVideoView != null)
mVideoView.setVideoLayout(mLayout, 0);
super.onConfigurationChanged(newConfig);
}
}
3.3 代码说明
3.3.1 缩放功能
该功能SDK已经提供好了接口,直接使用即可。
3.3.2 音量和亮度控制实现
根据layout可以看得出,利用FrameLayout的特点(后面视图会覆盖前面视图),通过控制后一个视图的宽度来达到进度条的效果。
3.3.3 自动隐藏
可用Handle来实现自定延时隐藏的功能,比较实用。
3.3.4 手势
手势方面大家可用多查查GestureDetector方面的资料,双击、缩放手势都可以实现。
四、代码下载
请移步#Taocode(SVN):(没有账户的请注册一个账户即可。)
项目地址:http://code.taobao.org/p/oplayer
五、Vitamio相关信息
5.1 近期将发布新的SDK版本
5.1.1 将直接内置各平台解码器,无需外下载!
5.1.2 将支持自定义进度控制条等。
六、相关文章
本系列文章承诺每周至少出一篇,以帮助需要的朋友尽快将Vitamio融合入自己或公司的项目中。
转载:http://www.cnblogs.com/over140/archive/2012/05/22/2473019.html
最近偶然抓到某直播平台的api,而且这也是Android的基础技能,所以突发奇想做个直播功能。
相关文章
- android onresume方法,非静态方法’onResume’Android Studio
- Android 加密 AES
- android 的hook技术,Android Native Hook技术(一)
- android 混淆不起作用,Android代码混淆的写法总结
- android json解析及简单例子
- android退出app代码,Android应用退出代码各种方式
- mac 电脑android环境变量设置,mac上Android环境变量配置[通俗易懂]
- android 安装p12证书,如何在Android中使用p12证书(客户端证书)
- android短信验证码方案,Android开发之属于你的短信验证码(一)
- Android保存图片到相册(适配android 10以下及以上)
- Android :ScaleAnimation「建议收藏」
- android横竖屏切换问题
- 【Android 应用开发】AndroidUI设计 之 图片浏览器
- 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )
- 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取要注入事件的 View 对象 | 通过反射获取 View 组件的事件设置方法 )
- 【Android 逆向】ELF 文件格式 ( ELF 程序头入口大小 | ELF 程序头入口个数 | ELF 文件节区头入口大小 | ELF 文件节区头入口个数 | 字符表序号 )
- 【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ② ( 组件化基本实现 | Project 相关目录 | 定义组件切换标志位 | 切换插件导入 | 切换设置应用 ID )
- 【错误记录】Android Studio 集成 ARoute 编译报错 ( 兼容 support 库和 androidx 库 | add ‘tools:replace=“android:appCo )
- 【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ⑤ ( 优化 Gradle 构建脚本 | 构建脚本结构 | 闭包定义及用法 | 依赖配置 | android 块配置 )
- 安装包立减1M--微信Android资源混淆打包工具
- Android控制文字水平间距android:letterSpacing详解手机开发
- [android] 手机卫士自定义滚动控件详解手机开发
- 攻击者宣称可利用 0day 漏洞完全控制 Android 手机
- 此应用程序可显示和控制通过USB(或通过TCP / IP)连接的Android设备
- Android左右滑出菜单实例分析
- Android入门之ListView应用解析(一)
- Android开发之获取网络链接状态