我按照此链接的教程 - > http://android-er.blogspot.com/2015/02/create-audio-visualizer-for-mediaplayer.html 通过扩展视图类来完成图形。现在我尝试用表面视图做同样的事情。这是代码:
MainActivity:
public class MainActivity extends Activity {
VisualizerView mVisualizerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mVisualizerView= new VisualizerView(this);
setContentView(mVisualizerView);
}
@Override
protected void onPause(){
super.onPause();
if(isFinishing()){
mVisualizerView.clean();
}
}}
Sufaceview课程:
public class VisualizerView extends SurfaceView implements SurfaceHolder.Callback {
private byte[] mBytes;
private float[] mPoints;
private Rect mRect = new Rect();
private Paint mForePaint = new Paint();
SurfaceThread _thread;
private MediaPlayer player;
private Visualizer visualizer;
private Context context;
public VisualizerView(Context context) {
super(context);
init();
getHolder().addCallback(this);
_thread = new SurfaceThread(getHolder(), this);
this.context=context;
}
private void init(){
mBytes = null;
mForePaint.setStrokeWidth(1f);
mForePaint.setAntiAlias(true);
mForePaint.setColor(Color.rgb(0,0, 255));
}
public void updateVisualizer(byte[] bytes) {
mBytes = bytes;
// invalidate();
}
private void initAudio(){
player= MediaPlayer.create(context, R.raw.duck);
setupVisualizerFxAndUI();
visualizer.setEnabled(true);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mediaPlayer){
visualizer.setEnabled(false);
}
}
);
player.start();
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBytes == null) {
return;
}
if (mPoints == null || mPoints.length < mBytes.length * 4) {
mPoints = new float[mBytes.length * 4];
}
mRect.set(0, 0, getWidth(), getHeight());
for (int i = 0; i < mBytes.length - 1; i++) {
mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1);
mPoints[i * 4 + 1] = mRect.height() / 2
+ ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128;
mPoints[i * 4 + 2] = mRect.width() * (i + 1) / (mBytes.length - 1);
mPoints[i * 4 + 3] = mRect.height() / 2
+ ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2)
/ 128;
}
canvas.drawColor(Color.WHITE);
canvas.drawLines(mPoints, mForePaint);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
_thread.setRunning(true);
_thread.start();
initAudio();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
public void clean(){
if(player!=null){
visualizer.release();
player.release();
player= null;
}
}
private void setupVisualizerFxAndUI(){
Equalizer mEqualizer = new Equalizer(0, player.getAudioSessionId());
mEqualizer.setEnabled(false);
visualizer =new Visualizer(player.getAudioSessionId());
visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
visualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform,
int samplingRate) {
// TODO Auto-generated method stub
updateVisualizer(waveform);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft,
int samplingRate) {
// TODO Auto-generated method stub
}
},Visualizer.getMaxCaptureRate()/2,true,false) ;
// Log.d(Tag,String.valueOf(Visualizer.getMaxCaptureRate()));
}}
主题类:
public class SurfaceThread extends Thread {
private SurfaceHolder surfaceHolder;
private VisualizerView panel;
private boolean run = false;
public SurfaceThread(SurfaceHolder surfaceHolder, VisualizerView panel) {
this. surfaceHolder = surfaceHolder;
this. panel = panel;
}
public void setRunning(boolean run) {
this.run = run;
}
@Override
public void run() {
Canvas c;
while (run) {
c = null;
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}}
现在问题是应用程序在运行两次后会崩溃。我知道我是 没有正确传递数据:
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform,
int samplingRate) {
// TODO Auto-generated method stub
updateVisualizer(waveform);
}
那么,我该如何管理呢? 此外,我对哪个线程可视化工具/媒体播放器正在运行以及应该去哪里感到困惑?