SurfaceView与MediaPlayer搭配使用
实现音乐和歌词联动
视频联动
对应的第二个界面 专门负责播放
实现音乐和歌词联动
package com.example.mp_class;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import com.example.mp_class.bean.MySong;
import com.example.mp_class.bean.SongBean;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class SongActivity extends AppCompatActivity implements SurfaceHolder.Callback{
private static final String TAG = “123321”;
private SurfaceView surfaceView;
private SurfaceHolder holder;
private Timer time=new Timer();
private MediaPlayer mp;
private int index;
private List<MySong> list=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_song);
// readSong();
surfaceView=findViewById(R.id.song_surface);
holder=surfaceView.getHolder();
holder.addCallback(this);
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},111);
}
// @SuppressLint(“SdCardPath”)
private void play_music() {
mp=new MediaPlayer();
try {
mp.setDataSource("/sdcard/txt/凤凰传奇 - 最炫民族风(Live).mp3");
mp.prepareAsync();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
// if( mp!=null) {
mp.start();
//开清定时器,判断时间,加坐标
time.schedule(new TimerTask() {
@Override
public void run() {
if( index+1<list.size()&&list.size()>0) {
if (mp.getCurrentPosition() >= list.get(index+1).getTime()) {
index++;
}
}
}
},0,100);
}
// }
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if( requestCode==111&&grantResults[0]== PackageManager.PERMISSION_GRANTED){
readSong();
}
}
private void readSong() {
try {
// FileInputStream fis = new FileInputStream(new File("/sdcard/txt/最炫民族风"));
FileInputStream fis = new FileInputStream("/sdcard/txt/最炫民族风");
byte[] bytes = new byte[1024];
int len=0;
StringBuffer sb = new StringBuffer();
while( (len=fis.read(bytes))!=-1) {
sb.append(new String(bytes,0,len));
}
Log.i(TAG, “readFile: 歌词”+sb.toString());
Toast.makeText(this, “”+sb.toString(), Toast.LENGTH_SHORT).show();
//开始切割
String songs = sb.toString();
SongBean songBean = new Gson().fromJson(songs, SongBean.class);
String lyric = songBean.getLrc().getLyric();
String[] split = lyric.split("\n");
for (int i = 1; i < split.length; i++) {
String split1 = split[i].replace("[", "#")
.replace("]", "#")
.replace(".","#")
.replaceFirst(":", "#");
String[] split2 = split1.split("#");
Log.i(TAG, "readSong: split1"+ Arrays.toString(split2));
int time=Integer.parseInt(split2[1])*60*1000+Integer.parseInt(split2[2])*1000+Integer.parseInt(split2[3]);
Log.i(TAG, "readSong: 总毫秒数"+time);
if( split2.length>=5) {
Log.i(TAG, "readSong: 歌词" + split2[4]);
MySong mySong = new MySong(split2[4], time);
list.add(mySong);
Log.i(TAG, "readSong: mysong"+mySong.toString());
}
}
//播放
play_music();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
new Thread(new Runnable() {
@Override
public void run() {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(50);
// if( list.size()>0)
while( true) {
Canvas canvas = holder.lockCanvas();
canvas.drawColor(Color.WHITE);
if( list.size()>0) {
canvas.drawText(list.get(index).getText(), 100, 100, paint);
}
holder.unlockCanvasAndPost(canvas);
}
}
}).start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
}
视频联动
package com.example.mp_class;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.example.mp_class.adapter.MyAdapter;
import com.example.mp_class.bean.MyBean;
import com.example.mp_class.listener.MyListener;
import com.google.gson.Gson;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;
import java.util.ArrayList;
import java.util.List;
public class Main2Activity extends AppCompatActivity {
private RecyclerView rv;
private List<MyBean.DataBean> list=new ArrayList<>();
private MyAdapter aaa;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
init();
get_data();
}
private void get_data() {
OkGo.<String>get("https://www.apiopen.top/satinApi?type=1&page=2")
.execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
MyBean myBean = new Gson().fromJson(response.body(), MyBean.class);
list.addAll(myBean.getData());
aaa.notifyDataSetChanged();
}
@Override
public void onError(Response<String> response) {
super.onError(response);
Log.i("123321", "onError: "+response.message());
}
});
}
private void init() {
MyListener listener = new MyListener() {
@Override
public void click(int position) {
Intent it = new Intent(Main2Activity.this, PlayActivity.class);
it.putExtra("data",list.get(position).getVideouri());
startActivity(it);
}
};
rv=findViewById(R.id.main_recycler);
rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
aaa=new MyAdapter(this, this.list,listener);
rv.setAdapter(aaa);
}
}
对应的第二个界面 专门负责播放
package com.example.mp_class;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
public class PlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceView surfaceView;
private MediaPlayer mp;
private SurfaceHolder sh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
mp=new MediaPlayer();
surfaceView=findViewById(R.id.play_surface);
sh=surfaceView.getHolder();
sh.addCallback(this);
Intent intent = getIntent();
String data = intent.getStringExtra("data");
mp.reset();
try {
mp.setDataSource(data);
mp.prepareAsync();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mp.setDisplay(surfaceHolder);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mp.release();
mp=null;
}
}