本文实例讲述了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相关内容感兴趣的读者可查看本站专题:《Android多媒体操作技巧汇总(音频,视频,录音等)》、《Android开发入门与进阶教程》、《Android视图View技巧总结》、《Android编程之activity操作技巧总结》、《Android文件操作技巧汇总》、《Android资源操作技巧汇总》及《Android控件用法总结》

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

更多相关文章

  1. [置顶] Canvas开篇之drawBitmap方法讲解
  2. Android-2D绘图基础-更新中
  3. Android自定义View(五)Canvas的常用方法
  4. Android之BaseAdapter的使用
  5. View 绘制流程
  6. Android(安卓)RecycleView(二)——添加分割线
  7. android仿ios开关按钮
  8. Android(安卓)自定义View之View的绘制
  9. 一起学android openg 纹理

随机推荐

  1. c语言数组冒泡排序是如何实现的?
  2. c语言怎么实现三个数从小到大输出?
  3. 在C语言里二维数组在内存中的存放顺序是
  4. c语言n次方怎么输入?
  5. c语言三目运算符怎么用?
  6. C++与C语言的区别与联系
  7. C++语言标识符的命名规则是什么?
  8. 深入学习C++必读书籍(推荐)
  9. C++中字符串比较函数strcmp怎么用?
  10. c++如何比较两个字符串?