java 手势控制亮度,音量,缩放
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 手势控制亮度,音量,缩放相关的知识,希望对你有一定的参考价值。
使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放
medium avatar
tijing
发表于 2012-5-24 09:46:20 浏览(330542)
本帖最后由 tijing 于 2012-7-16 16:28 编辑
第一部分
一、实现目标
1.1 支持格式
支持主流的视音频格式:mp3/mp4/mkv/avi/3gp/rmvb/mov/flv等。
1.2 支持功能
1.2.1 当然最重要的是播放功能,含播放控制(播放、暂停,声音、亮度调整等)
1.2.2 可以扫描SDcard,用列表展现出来,可以搜索
1.2.3 可以播放网络视音频(http、rtsp、mms)
二、Vitamio项目简介
Vitamio是一个支持所有Android设备的多媒体框架。Vitamio与Android默认的MediaPlayer工作方式相似,但包含更加强大的功能,并且它是完全免费的!
2.1 项目网址
http://vov.io/vitamio/
2.2 成功案例
国内:VPlayer、熊猫影音、321影音等
国外:Tvltaliane、Dizi TV等
2.3 网络协议
支持以下协议的音频和视频播放:
* MMS
* RTSP (RTP, SDP)
* HTTP流式传输(progressive streaming)
* HTTP Live Streaming (M3U8), Android 2.1+
2.4 媒体格式
Vitamio集成了许多音频和视频的解码包,相比Android内置默认的媒体格式,这里列出其中的一些:
* divx/xvid
* wmv
* flv
* ts
* rmvb
* mkv
* mov
* m4v
* avi
* mp4
* 3gp
2.5 字幕
Vitamio支持显示一些内置或外挂字幕格式:
* SubRip(.srt)
* Sub Station Alpha(.ssa) / Advanced Sub Station 移步wiki
* Alpha(.ass)
* SAMI(.smi/.sami)
* MicroDVD(.sub/.txt)
* SubViewer2.0(.sub)
* MPL2(.mpl/.txt)
* Matroska (.mkv) 字幕轨迹
2.6 其他功能
* 后台播放
* 多音轨支持
* 多字幕支持,包括内部或外挂的
* 多平台处理器优化
* 可调长宽比
* 文字编码自动检测
2.7 许可/授权(Lisences)
Vitamio使用了sevral开源项目,感谢他们。
2.7.1 FFmpeg
FFmpeg提供软件解码器和多路输出(demuxers)。Vitamio使用LGPLv2.1许可下FFmpeg的代码,代码可以从这里下载。
2.7.2 Universalchardet (是Mozilla的一个自动检测页面文字编码的程序)
Universalchardet是Mozilla的编码检测库。Vitamio使用MPL许可下Universalchardet的代码来检测字母文本编码。
以上主要是对官方介绍进行了简单翻译。
三、示例代码
3.1 下载Vitamio的SDK
Vitamio-SDK.7z 含javadoc文档和vitamio.jar。
3.2 下载Demo代码
Vitamio-Demo.7z 这是一个使用vitamio.jar的Demo工程。
3.2 运行Demo代码
3.2.1 下载上面的Demo包后,补充工程文件.project、.classpath等,后面有重新打包下载。
3.2.2 运行工程,见如下图:
需要安装Vitamio插件来播放视频,这里选择Vitamio Website,下载安装重新运行,发现一抹黑,看看代码,发现没有视频,修改视频路径,并且上传视频到SD卡,这里提供一个测试视频下载这里,再次运行即可。
3.2.3 成功截图
3.2.4 修改后的Demo工程下载
Vitamio-Demo.zip
注意把上面的测试视频解压后拷贝到SD卡的根目录。
四、相关文章
移动流媒体移动协议综述.pdf (563.79 KB, 下载次数: 90)
Android开发者指南(12) —— Android Supported Media Formats
Android网络收音机项目
第二部分
一、实现目标
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>
复制代码
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方面的资料,双击、缩放手势都可以实现。
四、代码下载
Vitamio-Demo2012-5-22.zip (70.56 KB, 下载次数: 540)
注意:示例中的图片资源采用VPlayer的资源图片,仅供学习之用!
五、Vitamio相关信息
5.1 近期将发布新的SDK版本
5.1.1 将直接内置各平台解码器,无需外下载!
5.1.2 将支持自定义进度控制条等。
六、相关文章
6.1Android 播放电影时滑动屏幕调整屏幕亮度
6.2 android MediaPlayer API
以上是关于java 手势控制亮度,音量,缩放的主要内容,如果未能解决你的问题,请参考以下文章
Android手势检测——GestureDetector全面分析