软件编程
位置:首页>> 软件编程>> Android编程>> Android编程之播放器MediaPlayer实现均衡器效果示例

Android编程之播放器MediaPlayer实现均衡器效果示例

作者:迟做总比不做强  发布时间:2022-02-25 11:52:32 

标签: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程序设计有所帮助。

来源:http://blog.csdn.net/true100/article/details/51197896

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com