您的位置:首页 > 移动开发 > Android开发

Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器

2015-11-12 21:07 573 查看
效果图如下:



(PS本来是要给大家穿gif动态图的,无奈太大了,没法上传)

功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能

实现的思路:

在主布局中放置一个SurfaceView,在SurfaceView中放置一个MediaPlayer ,在其下方自定义一个MediaController,不过也不能称之为MediaController,使用的是PupupWindow来实现的,在PupupWindow布局中放置几个textView,Button,最重要的使我们的SeekBar控件,创建一个定时器,当用户触摸屏幕时,让其popupWindow显示5秒的时间,具体实现可以看代码(主程序的代码有点多,耐心点看啊)

主布局activity_main.xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<SurfaceView
android:layout_width="match_parent"
android:layout_height="260dp"
android:id="@+id/surfaceView_main"
/>

<ImageView
android:onClick="clickButton"
android:id="@+id/imageView_main_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:src="@drawable/ic_launcher" />

</RelativeLayout>


  popupwindow.xml的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/voip_toast_bg"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:weightSum="10" >

<ImageView
android:id="@+id/imageView_play"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:src="@drawable/video_btn_on" />

<SeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5.0"
android:max="100"
android:maxHeight="5dp"
android:minHeight="5dp"
android:layout_marginLeft="5dp"
android:progress="0"
android:thumbOffset="0dp" />

<TextView
android:id="@+id/textView_playtime"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.3"
android:gravity="center"
android:text="00:00"
android:textColor="@android:color/white"
android:textSize="12sp" />

<TextView
android:id="@+id/textView_playtime"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:gravity="center"
android:text="/"
android:textColor="@android:color/white"
android:textSize="12sp" />

<TextView
android:id="@+id/textView_totaltime"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.3"
android:gravity="center"
android:text="00:00"
android:textColor="@android:color/white"
android:textSize="12sp" />

<ImageView
android:id="@+id/imageView_fullscreen"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:src="@drawable/video_full_screen" />

</LinearLayout>


  

主Activity中的代码:

package com.amy.day43_03_SurfaceViewMediaPlayer;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.R.integer;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MainActivity extends Activity {
private final static String TAG = "MainActivity";
private Context mContext = this;
private SurfaceView surfaceView = null;
private SurfaceHolder surfaceHolder = null;
private MediaPlayer mediaPlayer = null;
private ImageView imageView_main_show = null;

// 自定义的控制条及其上的控件
private View controllerView;
private PopupWindow popupWindow;

private ImageView imageView_play;
private ImageView imageView_fullscreen;
private SeekBar seekBar;
private TextView textView_playTime;
private TextView textView_duration;
private String filePath = null;

private float densityRatio = 1.0f; // 密度比值系数(密度比值:一英寸中像素点除以160)

private Runnable r = new Runnable() {
@Override
public void run() {
// 又回到了主线程
showOrHiddenController();
}
};

private MyVideoBroadcastReceiver receiver = null;

// 设置定时器
private Timer timer = null;
private final static int WHAT = 0;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case WHAT:
if (mediaPlayer != null) {
int currentPlayer = mediaPlayer.getCurrentPosition();
if (currentPlayer > 0) {
mediaPlayer.getCurrentPosition();
textView_playTime.setText(formatTime(currentPlayer));

// 让seekBar也跟随改变
int progress = (int) ((currentPlayer / (float) mediaPlayer
.getDuration()) * 100);

seekBar.setProgress(progress);
} else {
textView_playTime.setText("00:00");
seekBar.setProgress(0);
}
}

break;

default:
break;
}
};
};

// 自动隐藏自定义播放器控制条的时间
private static final int HIDDEN_TIME = 5000;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initView();

initMediaPlayer();

initController();

// 动态注册广播接受者
receiver = new MyVideoBroadcastReceiver();
registerReceiver(receiver, new IntentFilter(
"com.amy.day43_03_SurfaceViewMediaPlayer"));
}

private String formatTime(long time) {
SimpleDateFormat formatter = new SimpleDateFormat("mm:ss");
return formatter.format(new Date(time));
}

private void initController() {

controllerView = getLayoutInflater().inflate(
R.layout.popupwindow_mediacontroller, null);

// 初始化popopWindow
popupWindow = new PopupWindow(controllerView,
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);

imageView_play = (ImageView) controllerView
.findViewById(R.id.imageView_play);
imageView_fullscreen = (ImageView) controllerView
.findViewById(R.id.imageView_fullscreen);

seekBar = (SeekBar) controllerView.findViewById(R.id.seekbar);

textView_playTime = (TextView) controllerView
.findViewById(R.id.textView_playtime);
textView_duration = (TextView) controllerView
.findViewById(R.id.textView_totaltime);

seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

// 表示手指拖动seekbar完毕,手指离开屏幕会触发以下方法
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 让计时器延时执行
handler.postDelayed(r, HIDDEN_TIME);
}

// 在手指正在拖动seekBar,而手指未离开屏幕触发的方法
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 让计时器取消计时
handler.removeCallbacks(r);
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
int playtime = progress * mediaPlayer.getDuration() / 100;
mediaPlayer.seekTo(playtime);
}

}
});

// 点击播放的时候,判断是播放还是暂停
imageView_play.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (imageView_main_show.getVisibility() == View.VISIBLE) {
imageView_main_show.setVisibility(View.GONE);
}

if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
imageView_play.setImageResource(R.drawable.video_btn_down);
} else {
mediaPlayer.start();
imageView_play.setImageResource(R.drawable.video_btn_on);

}

}
});

// 实现全屏和退出全屏(内容物横竖屏,不是屏幕的横竖屏)
imageView_fullscreen.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
imageView_fullscreen
.setImageResource(R.drawable.video_full_screen);

// 重新设置surfaceView的高度和宽度
surfaceView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
surfaceView.getLayoutParams().height = (int) (260 * densityRatio);
} else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
imageView_fullscreen
.setImageResource(R.drawable.video_inner_screen);

surfaceView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
surfaceView.getLayoutParams().height = LayoutParams.MATCH_PARENT;
}

surfaceView.setLayoutParams(surfaceView.getLayoutParams());
}
});
}

private void showOrHiddenController() {
if (popupWindow.isShowing()) {
popupWindow.dismiss();
} else {
// 将dp转换为px
int controllerHeightPixel = (int) (densityRatio * 50);
popupWindow.showAsDropDown(surfaceView, 0, -controllerHeightPixel);
// 延时执行
handler.postDelayed(r, HIDDEN_TIME);
}
}

private void initMediaPlayer() {
filePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
+ File.separator + "myabc.mp4";

Log.i("==main==",
"==========="
+ Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath());
if (mediaPlayer == null) {
// 1,创建MediaPlay对象
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
// mediaPlayer.start();
mediaPlayer.setLooping(false);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {

@Override
public void onPrepared(MediaPlayer mp) {
// 表示准备完成,设置总的时长,使用时间格式化工具

// String duration = mediaPlayer.getDuration() ;
textView_duration.setText(formatTime(mediaPlayer.getDuration()));
// 初始化定时器
timer = new Timer();
timer.schedule(new TimerTask() {

@Override
public void run() {
handler.sendEmptyMessage(WHAT);
}
}, 0, 1000);
}
});

mediaPlayer.setOnErrorListener(new OnErrorListener() {

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();

return false;
}
});

mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

@Override
public void onCompletion(MediaPlayer mp) {
// 发送广播,播放下一首歌曲

Intent intent = new Intent();
intent.setAction("com.amy.day43_03_SurfaceViewMediaPlayer");
sendBroadcast(intent);
}
});
}

private void initView() {
// TODO Auto-generated method stub
densityRatio = getResources().getDisplayMetrics().density; // 表示获取真正的密度

imageView_main_show = (ImageView) findViewById(R.id.imageView_main_play);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView_main);
surfaceHolder = surfaceView.getHolder();

surfaceHolder.addCallback(new Callback() {

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mediaPlayer != null) {

mediaPlayer.setDisplay(surfaceHolder);
// mediaPlayer.start() ;

}

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// TODO Auto-generated method stub

}
});

// 设置屏幕的触摸监听
surfaceView.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
// 表示在点击的瞬间就显示控制条
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
showOrHiddenController();
break;

default:
break;
}
return true;
}
});
}

/**
* 设置控件的监听事件
*
* @param v
*/
public void clickButton(View v) {
switch (v.getId()) {
case R.id.imageView_main_play:

imageView_main_show.setVisibility(View.GONE);
mediaPlayer.start();

break;

default:
break;
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();

unregisterReceiver(receiver);
timer.cancel();

if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}

handler.removeCallbacksAndMessages(null);
}

class MyVideoBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
"com.amy.day43_03_SurfaceViewMediaPlayer")) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.ic_launcher)
.setTitle("提示")
.setMessage("视屏播放完毕,是否播放")
.setNegativeButton("取消", null)
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog,
int which) {
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.setLooping(false);

mediaPlayer.start();
}
}).show();

}
}

}

}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: