一、介绍MediaPlay类和SurfaceView常用方法:
MediaPlay类常用方法:
方法名 | 功能 |
void seDataSource(String path) | 设置数据源(http/rtsp地址) |
void seDataSource(FileDescriptor fd,long offset,long length ) | 设置数据源 |
void seDataSource(Context context,Uri uri) | 设置一个Uri的数据源 |
static MediaPlayercreate(Context context,int resid) | 根据给定的资源id方便创建MediaPlayer对象的方法 |
static MediaPlayercreate(Context context,Uri uri,SurfaceHolder holder) | 根据给定的URI创建MediaPlayer对象 |
boolean isPlaying() | 判断MediaPlayer是否在播放 |
getCurrentPosition() | 得到当前播放位置 |
getDuration() | 得到文件的时间 |
isLooping(boolean b) | 是否循环播放 |
getVideoHeight()、getVideoWidth() | 获取视频的宽高 |
pause() | 暂停 |
prepare() | 准备(同步) |
prepareAsync() | 准备(异步) |
release() | 释放MediaPlayer对象相关的资源 |
reset() | 重置MediaPlayer对象为刚刚创建的状态 |
seekTo(int seek) | 指定播放的位置(以毫秒为单位的时间) |
setAudioStreamType(int type) | 设置流媒体的类型 |
setDisplay(SurfaceHolder sh) | 设置用SurfaceHolder来显示多媒体 |
stop() | 停止播放 |
setVolume(float leftVolume,float rightVolume) | 设置音量 |
setScreenOnWhilePlaying(boolean b) | 设置是否使用SurfaceHolder来保持屏幕显示 |
start() | 开始播放 |
监听方法:
setOnButteringUpdateListener | 网络流媒体的缓冲监听 |
setOnErrorListener | 设置错误信息监听 |
setOnVideoSizeChangedListener | 视频尺寸监听 |
SurfaceView类的常用方法:
构造方法 | 功能 |
purblic SurfaceView(Context context) | 创建SurfaceView对象 |
purblic SurfaceView(Context context,AttributeSet attrs) | 创建SurfaceView对象 |
purblic SurfaceView(Context context,AttributeSet attrs,int defStyle) | 创建SurfaceView对象 |
常用方法 | 功能 |
public SurfaceHolder getHolder() | 得到SurfaceHolder对象用来管理surfaceview |
public void setVisibility(int visibility) | 设置是否可见 |
SurfaceHolder是一个接口,类似一个Surface的监听器。有三个回调方法来监听Surface的创建、销毁、改变。
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
// 创建
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
// 改变
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
// 销毁
}
二、例子:
MainActivity:
package com.example.surfaceview;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentResolver;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener,SurfaceHolder.Callback, View.OnClickListener {
private SurfaceView sv;
private SurfaceHolder mHolder;
private MediaPlayer mPlayer;
private RelativeLayout rl;
private Timer mTimer;
private TimerTask mTimerTask;
private SeekBar sbar;
private ImageView play,forward,backward,loop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
mTimer = new Timer();
// 定时器的任务:
mTimerTask = new TimerTask() {
@Override
public void run() {
if (mPlayer!=null&&mPlayer.isPlaying()){
// 获取视频长度并设置进度条最大值
int total = mPlayer.getDuration();
sbar.setMax(total);
// 获取当前位置
int progress = mPlayer.getCurrentPosition();
sbar.setProgress(progress);
}
}
};
// 开启定时器
mTimer.schedule(mTimerTask,500,500);
}
private void initView() {
sv = findViewById(R.id.sv);
loop = findViewById(R.id.loop_Im);
loop.setOnClickListener(this);
forward = findViewById(R.id.backward_Im);
forward.setOnClickListener(this);
backward = findViewById(R.id.forward_Im);
backward.setOnClickListener(this);
// 获取SurfaceHolder对象,用于管理SurfaceView
mHolder = sv.getHolder();
mHolder.setType(3);
mHolder.addCallback(this);
rl = findViewById(R.id.rl);
play = findViewById(R.id.play);
play.setOnClickListener(this);
sbar = findViewById(R.id.sbar);
sbar.setOnSeekBarChangeListener(this);
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
mPlayer = new MediaPlayer();
mPlayer .setAudioStreamType(AudioManager.STREAM_MUSIC);
Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
getPackageName() + "/"+R.raw.video);
try {
// 设置数据源
mPlayer.setDataSource(MainActivity.this,uri);
// surfaceView 与 MediaPlay进行关联
mPlayer.setDisplay(mHolder);
mPlayer.prepareAsync(); // 准备播放(异步)
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
}
});
}catch (Exception e){
Toast.makeText(MainActivity.this,"播放失败!",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
if (mPlayer!=null)
mPlayer.stop();
}
/
// 进度条的进度发生变化时
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (seekBar.getProgress()==seekBar.getMax()){
play.setBackgroundResource(R.drawable.stop);
}
}
// 进度条拖动时触发
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
// 进度条停止拖动时触发
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int position = seekBar.getProgress();
if (mPlayer!=null){
mPlayer.seekTo(position);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if (rl.getVisibility() == INVISIBLE) {
rl.setVisibility(VISIBLE);
CountDownTimer cdt = new CountDownTimer(3000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
System.out.println(millisUntilFinished);
}
@Override
public void onFinish() {
// 隐藏进度条和播放按钮
rl.setVisibility(INVISIBLE);
}
};
cdt.start();
}else if(rl.getVisibility() == VISIBLE){
rl.setVisibility(INVISIBLE);
}
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onDestroy() {
// 释放资源
mTimerTask.cancel();
mTimer.cancel();
mTimer = null;
mTimerTask =null;
mPlayer.release();
mPlayer=null;
super.onDestroy();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.backward_Im:
int bPosition = mPlayer.getCurrentPosition()-100;
mPlayer.seekTo(bPosition);
sbar.setProgress(bPosition);
break;
case R.id.forward_Im:
int fPosition = mPlayer.getCurrentPosition()+200;
mPlayer.seekTo(fPosition);
sbar.setProgress(fPosition);
break;
case R.id.loop_Im:
if (mPlayer.isPlaying()){
loop.setBackgroundResource(R.drawable.flooping);
Toast.makeText(this, "1111", Toast.LENGTH_SHORT).show();
mPlayer.setLooping(false);
}else {
loop.setBackgroundResource(R.drawable.tlooping);
Toast.makeText(this, "1222", Toast.LENGTH_SHORT).show();
mPlayer.setLooping(true);
}
break;
case R.id.play:
if (mPlayer!=null&&mPlayer.isPlaying()){
mPlayer.pause();
play.setImageResource(R.drawable.stop);
}else {
mPlayer.start();
play.setImageResource(R.drawable.start);
}
break;
}
}
}
activity_main:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<RelativeLayout
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<SeekBar
android:id="@+id/sbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:max="100"
android:progress="0" />
<ImageView
android:id="@+id/play"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="@drawable/start" />
<ImageView
android:id="@+id/backward_Im"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:layout_toLeftOf="@+id/play"
android:background="@drawable/backward" />
<ImageView
android:id="@+id/forward_Im"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_toRightOf="@+id/play"
android:layout_centerInParent="true"
android:background="@drawable/forward" />
<ImageView
android:id="@+id/loop_Im"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="@+id/forward_Im"
android:layout_centerInParent="true"
android:background="@drawable/flooping" />
</RelativeLayout>
</FrameLayout>