播放器android程序设计,Android编程之播放器MediaPlayer实现均衡器效果示例

本文实例讲述了Android播放器MediaPlayer实现均衡器效果。分享给大家供大家参考,具体如下:

这几天在系统学习Android官方API Demos,看到实现均衡器效果,就把官方API中代码copy下来,根据网上前辈的指引略有修改,添加了注释。

public class AudioFxDemo extends Activity {

private static final String TAG = "AudioFxDemo";

private static final float VISUALIZER_HEIGHT_DIP = 50f;

// 定义播放器

private MediaPlayer mMediaPlayer;

// 定义系统的频谱

private Visualizer mVisualizer;

// 定义系统的均衡器

private Equalizer mEqualizer;

private LinearLayout mLinearLayout;

private VisualizerView mVisualizerView;

private TextView mStatusTextView;

@Override

public void onCreate(Bundle bundle) {

super.onCreate(bundle);

// 音量控制

setVolumeControlStream(AudioManager.STREAM_MUSIC);

mStatusTextView = new TextView(this);

mLinearLayout = new LinearLayout(this);

mLinearLayout.setOrientation(LinearLayout.VERTICAL);

mLinearLayout.addView(mStatusTextView);

setContentView(mLinearLayout);

// 创建MediaPlayer对象

mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);

Log.d(TAG,

"MediaPlayer audio session ID: "

+ mMediaPlayer.getAudioSessionId());

// 设置频谱显示

setupVisualizerFxAndUI();

// 设置示波器显示

setupEqualizerFxAndUI();

// Make sure the visualizer is enabled only when you actually want to

// receive data, and

// when it makes sense to receive data.

mVisualizer.setEnabled(true);

// When the stream ends, we don't need to collect any more data. We

// don't do this in

// setupVisualizerFxAndUI because we likely want to have more,

// non-Visualizer related code

// in this callback.

mMediaPlayer

.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

public void onCompletion(MediaPlayer mediaPlayer) {

mVisualizer.setEnabled(false);

mStatusTextView.setText("播放结束");

}

});

mMediaPlayer.start();

mStatusTextView.setText("正在播放中");

}

private void setupEqualizerFxAndUI() {

// Create the Equalizer object (an AudioEffect subclass) and attach it

// to our media player,

// with a default priority (0).

mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());

mEqualizer.setEnabled(true);

TextView eqTextView = new TextView(this);

eqTextView.setText("Equalizer:");

mLinearLayout.addView(eqTextView);

short bands = mEqualizer.getNumberOfBands();

final short minEQLevel = mEqualizer.getBandLevelRange()[0];

final short maxEQLevel = mEqualizer.getBandLevelRange()[1];

for (short i = 0; i < bands; i++) {

final short band = i;

TextView freqTextView = new TextView(this);

freqTextView.setLayoutParams(new ViewGroup.LayoutParams(

ViewGroup.LayoutParams.MATCH_PARENT,

ViewGroup.LayoutParams.WRAP_CONTENT));

freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);

freqTextView.setText((mEqualizer.getCenterFreq(band) / 1000)

+ " Hz");

mLinearLayout.addView(freqTextView);

LinearLayout row = new LinearLayout(this);

row.setOrientation(LinearLayout.HORIZONTAL);

TextView minDbTextView = new TextView(this);

minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(

ViewGroup.LayoutParams.WRAP_CONTENT,

ViewGroup.LayoutParams.WRAP_CONTENT));

minDbTextView.setText((minEQLevel / 100) + " dB");

TextView maxDbTextView = new TextView(this);

maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(

ViewGroup.LayoutParams.WRAP_CONTENT,

ViewGroup.LayoutParams.WRAP_CONTENT));

maxDbTextView.setText((maxEQLevel / 100) + " dB");

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(

ViewGroup.LayoutParams.MATCH_PARENT,

ViewGroup.LayoutParams.WRAP_CONTENT);

layoutParams.weight = 1;

SeekBar bar = new SeekBar(this);

bar.setLayoutParams(layoutParams);

bar.setMax(maxEQLevel - minEQLevel);

bar.setProgress(mEqualizer.getBandLevel(band));

bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

public void onProgressChanged(SeekBar seekBar, int progress,

boolean fromUser) {

mEqualizer.setBandLevel(band,

(short) (progress + minEQLevel));

}

public void onStartTrackingTouch(SeekBar seekBar) {

}

public void onStopTrackingTouch(SeekBar seekBar) {

}

});

row.addView(minDbTextView);

row.addView(bar);

row.addView(maxDbTextView);

mLinearLayout.addView(row);

}

}

private void setupVisualizerFxAndUI() {

// Create a VisualizerView (defined below), which will render the

// simplified audio

// wave form to a Canvas.

mVisualizerView = new VisualizerView(this);

mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(

ViewGroup.LayoutParams.MATCH_PARENT,

(int) (VISUALIZER_HEIGHT_DIP * getResources()

.getDisplayMetrics().density)));

mLinearLayout.addView(mVisualizerView);

// Create the Visualizer object and attach it to our media player.

mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());

mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);

mVisualizer.setDataCaptureListener(

new Visualizer.OnDataCaptureListener() {

public void onWaveFormDataCapture(Visualizer visualizer,

byte[] bytes, int samplingRate) {

mVisualizerView.updateVisualizer(bytes);

}

public void onFftDataCapture(Visualizer visualizer,

byte[] bytes, int samplingRate) {

}

}, Visualizer.getMaxCaptureRate() / 2, true, false);

}

@Override

protected void onPause() {

super.onPause();

if (isFinishing() && mMediaPlayer != null) {

mVisualizer.release();

mEqualizer.release();

mMediaPlayer.release();

mMediaPlayer = null;

}

}

}

/**

* 绘制波状View

*

* @description:

* @author ldm

* @date 2016-4-20 上午9:11:49

*/

class VisualizerView extends View {

// 数组保存了波形抽样点的值

private byte[] bytes;

private float[] points;

// 定义画笔

private Paint paint = new Paint();

// 矩形区域

private Rect rect = new Rect();

private byte type = 0;

public VisualizerView(Context context) {

super(context);

bytes = null;

// 设置画笔的属性

paint.setStrokeWidth(1f);// 设置空心线宽

paint.setAntiAlias(true);// 抗锯齿

paint.setColor(Color.BLUE);// 画笔颜色

paint.setStyle(Style.STROKE);// 非填充模式

}

public void updateVisualizer(byte[] ftt) {

bytes = ftt;

// 通知组件重绘

invalidate();

}

@Override

public boolean onTouchEvent(MotionEvent me) {

// 当用户触碰该组件时,切换波形类型

if (me.getAction() != MotionEvent.ACTION_DOWN) {

return false;

}

type++;

if (type >= 3) {

type = 0;

}

return true;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (bytes == null) {

return;

}

// 绘制黑色背景

canvas.drawColor(Color.BLACK);

// 使用rect对象记录该组件的宽度和高度

rect.set(0, 0, getWidth(), getHeight());

switch (type) {

// 绘制块状的波形图

case 0:

for (int i = 0; i < bytes.length - 1; i++) {

float left = getWidth() * i / (bytes.length - 1);

// 根据波形值计算该矩形的高度

float top = rect.height() - (byte) (bytes[i + 1] + 128)

* rect.height() / 128;

float right = left + 1;

float bottom = rect.height();

canvas.drawRect(left, top, right, bottom, paint);

}

break;

// 绘制柱状的波形图(每隔18个抽样点绘制一个矩形)

case 1:

for (int i = 0; i < bytes.length - 1; i += 18) {

float left = rect.width() * i / (bytes.length - 1);

// 根据波形值计算该矩形的高度

float top = rect.height() - (byte) (bytes[i + 1] + 128)

* rect.height() / 128;

float right = left + 6;

float bottom = rect.height();

canvas.drawRect(left, top, right, bottom, paint);

}

break;

// -绘制曲线波形图

case 2:

// 如果point数组还未初始化

if (points == null || points.length < bytes.length * 4) {

points = new float[bytes.length * 4];

}

for (int i = 0; i < bytes.length - 1; i++) {

// 计算第i个点的x坐标

points[i * 4] = rect.width() * i / (bytes.length - 1);

// 根据bytes[i]的值(波形点的值)计算第i个点的y坐标

points[i * 4 + 1] = (rect.height() / 2)

+ ((byte) (bytes[i] + 128)) * 128 / (rect.height() / 2);

// 计算第i+1个点的x坐标

points[i * 4 + 2] = rect.width() * (i + 1) / (bytes.length - 1);

// 根据bytes[i+1]的值(波形点的值)计算第i+1个点的y坐标

points[i * 4 + 3] = (rect.height() / 2)

+ ((byte) (bytes[i + 1] + 128)) * 128

/ (rect.height() / 2);

}

// 绘制波形曲线

canvas.drawLines(points, paint);

break;

}

}

}

自己新建 项目时,记得在res/raw下添加一个名为test_cbr的mp3格式文件。

希望本文所述对大家Android程序设计有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值