由于公司项目需要自己写播放器,于是用VideoView写了个,废话不多说,直接进入主题。 首先介绍播放器的主界面
<?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"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/vv_RelativeLayout"
android:layout_width="fill_parent"
android:layout_height="320dp" >
<com.example.vediotest.FullScreenVideoView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<LinearLayout
android:id="@+id/vv_progress_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal"
android:visibility="gone" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/vv_show_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="正在加载..." />
</LinearLayout>
<RelativeLayout
android:id="@+id/vv_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible" >
<Button
android:id="@+id/vv_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/play" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<TextView
android:id="@+id/vv_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"
android:textColor="#ffffffff" />
<Button
android:id="@+id/vv_fullscreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="全屏" />
<TextView
android:id="@+id/vv_end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/vv_fullscreen"
android:text="00:00"
android:textColor="#ffffffff" />
<SeekBar
android:id="@+id/vv_seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/vv_end_time"
android:layout_toRightOf="@id/vv_current_time"
android:progress="20"
android:secondaryProgress="40" />
</RelativeLayout>
</RelativeLayout>
<FrameLayout
android:id="@+id/operation_volume_brightness"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#00000000"
android:orientation="horizontal"
android:padding="0dip"
android:visibility="invisible" >
<ImageView
android:id="@+id/operation_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/video_volumn_bg" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:paddingBottom="25dip" >
<ImageView
android:id="@+id/operation_full"
android:layout_width="94dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:src="@drawable/video_num_bg" />
<ImageView
android:id="@+id/operation_percent"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:scaleType="matrix"
android:src="@drawable/video_num_front" />
</FrameLayout>
</FrameLayout>
</RelativeLayout>
</RelativeLayout>
以上是播放器的主界面,主要包括 自定义视频播放界面 <span style="font-family: 'Source Code Pro', monospace; font-size: 0.9em;">com.example.vediotest.FullScreenVideoView 播放暂停按钮 、 当前播放进度、视频总时间、进度条、手势改变音量和亮度大小、全屏切换、载入视频及缓冲提示loading.</span>
下面介绍 视频播放代码
<pre name="code" class="java">Uri uri = Uri.parse("http://ignhdvod-f.akamaihd.net/i/assets.ign.com/videos/zencoder/,"
+ "416/d4ff0368b5e4a24aee0dab7703d4123a-110000,640/d4ff0368b5e4a24aee0dab7703d4123a-500000,"
+ "640/d4ff0368b5e4a24aee0dab7703d4123a-1000000,960/d4ff0368b5e4a24aee0dab7703d4123a-2500000,"
+ "1280/d4ff0368b5e4a24aee0dab7703d4123a-3000000,-1354660143-w.mp4.csmil/master.m3u8");
mVideoView.setVideoURI(uri);
mVideoView.requestFocus();
mVideoView.start();
这个是视频播放的原理代码,逻辑实现可自己定义。
另外不得不说的是视频播放器VideoView的几个监听类
mVideoView.setOnErrorListener(this);//视频播放出现错误时
mVideoView.setOnPreparedListener(this);//视频准备监听类
<span style="white-space:pre"> </span>/**
* 视频播放完成
*/
mVideoView.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.i("123", "onCompletion");
}
});
<span style="white-space:pre"> </span>/**
* 视频播放过程中信息,比如出现缓冲状态,我们可以在这里进行监听
*/
mVideoView.setOnInfoListener(new OnInfoListener() {
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
mProgressBar.setVisibility(View.VISIBLE);
Log.i("123", "缓冲中...." + mVideoView.getBufferPercentage());
} else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
// 此接口每次回调完START就回调END,若不加上判断就会出现缓冲图标一闪一闪的卡顿现象
if (mp.isPlaying()) {
mProgressBar.setVisibility(View.GONE);
Log.i("123",
"缓冲完成..." + mVideoView.getBufferPercentage());
}
}
return true;
}
});
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
Log.i("123", "播放出错");
return false;
}
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer = mp;
Log.i("123", "onPrepared");
mProgressBar.setVisibility(View.GONE);
mVideoView.start();
mStart.setBackgroundResource(R.drawable.pause);
}
在进行全屏切换过程中的时候 我们在使用onConfigurationChanged ,看到网上有在OnStart()和onResume()总切换,试了下 效果不好,下面附上代码
<pre name="code" class="java"> @Override
public void onConfigurationChanged(Configuration newConfig) {
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
/**
* 改变窗口,去掉Title
*/
WindowManager.LayoutParams mParams = getWindow().getAttributes();
mParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(mParams);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT);
mRelativeLayout.setLayoutParams(params);//重新定义播放器界面大小
} else {
WindowManager.LayoutParams mParams = getWindow().getAttributes();
mParams.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(mParams);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, 400);
mRelativeLayout.setLayoutParams(params);
}
super.onConfigurationChanged(newConfig);
}
在使用这个时候 一定要修改Manifest中activity的configChanges
添加android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
如下
<activity
android:name="com.example.vediotest.VideoPlyerActivity"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
如不加
onConfigurationChanged 方法不能触发
以上就是播放器的原理及部分代码,本人不善言辞,如有错误,请帮忙指正批评,谢谢!
源码下载请移步 播放器源码
本文属于原创,若转载 请说明