MediaPlayer+SeekBar暂停快进快退
今天学习了音乐播放器超低配版,但是我已经很满足了,因为她没有广告…
话不多说让我们来看一下实现过程吧
首先供上布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="20dp"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="400dp" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
<LinearLayout
android:layout_above="@id/mypro"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/left_i"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="80dp"
android:background="@drawable/back"/>
<ImageView
android:id="@+id/cen"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="80dp"
android:background="@drawable/a7r" />
<ImageView
android:id="@+id/right_i"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/goon"/>
</LinearLayout>
<SeekBar
android:id="@+id/mypro"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
出来是这么个样子
颜值方面尽力了,她要是长的比我好看了我就该酸了
然后来上代码实现,先来个整体的,然后分开说一下
public class MainActivity extends AppCompatActivity {
private SurfaceView surfaceView;
private MediaPlayer player;
private SurfaceHolder holder;
private ProgressBar progressBar;
private SeekBar mypro;
ImageView left,right,cen;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
progressBar= (ProgressBar) findViewById(R.id.progressBar);
mypro = findViewById(R.id.mypro);
cen = findViewById(R.id.cen);
left = findViewById(R.id.left_i);
right = findViewById(R.id.right_i);
//视频链接可能已失效
String uri="http://vfx.mtime.cn/Video/2019/03/19/mp4/190319125415785691.mp4";
player=new MediaPlayer();
try {
player.setDataSource(this, Uri.parse(uri));
holder=surfaceView.getHolder();
holder.addCallback(new MyCallBack());
player.prepare();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
progressBar.setVisibility(View.INVISIBLE);
player.start();
player.setLooping(true);
}
});
} catch (IOException e) {
e.printStackTrace();
}
mypro.setMax(player.getDuration());
final Handler handler = new Handler();
final Runnable updateThread = new Runnable() {
public void run() {
if (player != null) {
mypro.setProgress(player.getCurrentPosition());
handler.postDelayed(this, 100);
}
}
};
new Thread(updateThread).start();
mypro.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(updateThread);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
player.seekTo(seekBar.getProgress());
handler.postDelayed(updateThread, 1000);
}
});
cen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (player.isPlaying()) {
player.pause();//暂停播放
cen.setImageResource(R.drawable.a7r);
} else {
player.start();//继续播放
cen.setImageResource(R.drawable.a7v);
}
}
});
left.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(updateThread);
player.seekTo(player.getCurrentPosition()-1000);
handler.postDelayed(updateThread, 1000);
}
});
right.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(updateThread);
player.seekTo(player.getCurrentPosition()+2000);
handler.postDelayed(updateThread, 1000);
}
});
}
private class MyCallBack implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
}
抱歉没能养成打注释的好习惯,我们就来看一下吧
首先是,如何能够播放一个视频(网络权限小伙伴们自己盘上)
通过给播放器设置Uri数据源,先prepare准备然后打开监听通过start播放
Loogping设置为循环播放,有其他需求的小伙伴可以做,但是需要另外在线程加判断了
然后是进度条Seekbar
这是一个进度条实时更新监听,通过handle接收,线程中没0.1秒跟进一次
然后是点击时改变视频播放进度
这个地方没什么可说的,就是在点击时先断掉监听,然后重新设置进度,再打开监听
快进慢进的实现和这个原理一样,后面我就不单独拿出来了,需要的去上面找
最后是暂停和继续,
先通过isPlaying判断当前的状态
然后分别调用pause和start,同时改变图标样式m
因为是在不会发动图没法给各位看效果,抱歉喽