Android中播放视频,简单就直接用VideoView,这是系统集成的一个视频播放组件,使用起来还是比较方便的。
这里要写的是使用SurfaceView播放视频,SurfaceView的方便之处我不再多说,具体使用方法如下。
直接上代码:
布局文件长这样:
<?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:background="@color/color_black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true">
<SurfaceView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/video_surfaceview"
android:layout_centerInParent="true">
</SurfaceView>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/layout_loading"
android:gravity="center"
android:visibility="visible"
android:layout_centerInParent="true">
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载..."
android:id="@+id/tv_loading"
android:textColor="@color/color_white"
android:layout_marginLeft="5dp" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#88000000"
android:padding="5dp"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_play"
android:src="@mipmap/media_pause_ic" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="5dp"
android:layout_marginLeft="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"
android:id="@+id/tv_end_time"
android:textColor="@color/color_white"
android:layout_marginLeft="5dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.SeekBar.Normal"
android:layout_toLeftOf="@+id/tv_end_time"
android:layout_centerVertical="true" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
然后在Activity中使用,用SurfaceHolder.Callback,不多说,直接上代码:
大致内容是这样的:
public class MediaPlayActivity extends Activity implements SurfaceHolder.Callback{
public static final String NATIVE_MEDIA_URLS = "native_media";
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder mHolder;
private boolean isShow = false;
private ImageView btnPlay;
private SeekBar mSeekBar;
private TextView tvEndTime;
private Timer mTimer;
private int surfaceWidth,surfaceHeight;
private View loadingView;
private TextView tvLoading;
private String mediaUrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.screen_media_player);
isShow = true;
mediaUrl = getIntent().getStringExtra("mediaUrl");
registerComponent();
}
private void registerComponent(){
mPreview = (SurfaceView)findViewById(R.id.video_surfaceview);
mPreview.setFocusable(true);
mHolder = mPreview.getHolder();
mHolder.addCallback(this);
btnPlay = (ImageView)this.findViewById(R.id.btn_play);
btnPlay.setImageResource(R.mipmap.media_pause_ic);
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isPlaying()) {
pauseMedia();
} else {
replayMedia();
}
setMediaPlayerStatus(isPlaying());
}
});
mSeekBar = (SeekBar)this.findViewById(R.id.seekBar);
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mMediaPlayer != null) {
mMediaPlayer.seekTo(seekBar.getProgress() * 1000);
}
setMediaPlayerStatus(isPlaying());
}
});
tvEndTime = (TextView)this.findViewById(R.id.tv_end_time);
loadingView = this.findViewById(R.id.layout_loading);
loadingView.setVisibility(View.GONE);
tvLoading = (TextView)this.findViewById(R.id.tv_loading);
}
private void setMediaPlayerStatus(boolean playing){
if(playing){
btnPlay.setImageResource(R.mipmap.media_pause_ic);
}else{
btnPlay.setImageResource(R.mipmap.media_play_ic);
}
}
private void setProgress(int duration,int max){
int time = (max-duration)/1000;
mSeekBar.setMax(max / 1000);
if(duration<50)
mSeekBar.setProgress(0);
else
mSeekBar.setProgress((duration / 1000)+1);
tvEndTime.setText(String.format("%02d", time / 60) + ":" + String.format("%02d", time));
}
private void startTimer(){
if(mTimer == null){
mTimer = new Timer();
}
setProgress(-1, mMediaPlayer.getDuration());
mTimer.schedule(new TimerTask() {
@Override
public void run() {
if (isPlaying()) {
mHandler.sendEmptyMessage(0);
}
}
}, 0, 1000);
}
private Handler mHandler = new Handler(){
public void handleMessage(Message msg){
setProgress(mMediaPlayer.getCurrentPosition(),mMediaPlayer.getDuration());
}
};
private void initMedia(Uri uri){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
setMediaPlayerStatus(false);
setProgress(-1, mMediaPlayer.getDuration());
//mMediaPlayer.seekTo(500);
}
});
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mediaPlayer, int whatError, int extra) {
Toast("播放失败");
releaseMedia();
return true;
}
});
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
resetDisplay(mWidth, mHeight);
//setProgress(mMediaPlayer.getCurrentPosition()+1, mMediaPlayer.getDuration());
loadingView.setVisibility(View.GONE);
setMediaPlayerStatus(true);
}
});
mMediaPlayer.setDisplay(mHolder);
}
private void resetDisplay(int width,int height){
int vWidth = mMediaPlayer.getVideoWidth();
int vHeight = mMediaPlayer.getVideoHeight();
float scale = 1.0f * width / vWidth;
if (vWidth < vHeight) {
scale = 1.0f * height / vHeight;
}
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) (vWidth * scale), (int) (vHeight * scale));
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
params.addRule(RelativeLayout.CENTER_VERTICAL);
mPreview.setLayoutParams(params);
mMediaPlayer.setDisplay(mHolder);
}
private void playMedia(Uri uri){
if(mMediaPlayer == null){
initMedia(uri);
}
mMediaPlayer.reset();
try {
mMediaPlayer.setDataSource(this, uri);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.prepare();
startTimer();
mMediaPlayer.start();
}catch(Exception e){
e.printStackTrace();
Toast("播放失败");
}
}
private void pauseMedia(){
if (mMediaPlayer != null) {
mMediaPlayer.pause();
}
}
private void replayMedia(){
if(mMediaPlayer != null){
mMediaPlayer.start();
}
}
private boolean isPlaying(){
if(mMediaPlayer != null){
return mMediaPlayer.isPlaying();
}
return false;
}
private void releaseMedia(){
if(mTimer != null){
mTimer.cancel();
mTimer = null;
}
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
//播放本地视频
playMedia(Uri.fromFile(new File(mediaUrl)));
//若是网络视频,可先下载,然后播放
}
public void surfaceChanged(SurfaceHolder arg0, int format, int width, int height) {
// TODO Auto-generated method stub
this.surfaceWidth = width;
this.surfaceHeight = height;
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
releaseMedia();
}
public void onPause(){
isShow = false;
super.onPause();
pauseMedia();
setMediaPlayerStatus(isPlaying());
}
public void onDestroy(){
super.onDestroy();
releaseMedia();
}
}
如此便可以使用surfaceview来播放视频了。其中细节不到位之处,只能自行补全。