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

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

(0)

相关推荐

  • Android提高之MediaPlayer播放网络音频的实现方法

    前面有文章曾经地介绍过MediaPlayer的基本用法,这里就更加深入地讲解MediaPlayer的在线播放功能.本文主要实现MediaPlayer在线播放音频的功能,由于在线视频播放比在线音频播放复杂,因此先介绍在线音频播放的实现,这样可以帮助大家逐步深入了解MediaPlayer的在线播放功能. 先来看看本文程序运行的结果如下图所示: main.xml的源码如下: <?xml version="1.0" encoding="utf-8"?> <

  • android webvie指定视频播放器播放网站视频

    过滤掉其他的播放器,使用我自己的播放器来做 复制代码 代码如下: wv.setWebViewClient(new WebViewClient() {            public boolean shouldOverrideUrlLoading(final WebView view,                    final String url) { if (url.contains("3gp") || url.contains("mp4")) {/

  • android音乐播放器监听电话状态实现代码

    如下代码是监听电话的状态,代码简单不做介绍直接看代码: 复制代码 代码如下: private boolean mResumeAfterCall = false; private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {  @Override  public void onCallStateChanged(int state, String incomingNumber) {   if (state ==

  • 深入Android MediaPlayer的使用方法详解

    1)如何获得MediaPlayer实例:可以使用直接new的方式:MediaPlayer mp = new MediaPlayer();也可以使用create的方式,如:MediaPlayer mp = MediaPlayer.create(this, R.raw.test);//这时就不用调用setDataSource了 2) 如何设置要播放的文件:MediaPlayer要播放的文件主要包括3个来源:a. 用户在应用中事先自带的resource资源例如:MediaPlayer.create(t

  • Android MediaPlayer实现音乐播放器实例代码

    Android MediaPlayer实现音乐播放器 1.布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height=&qu

  • Android提高之MediaPlayer播放网络视频的实现方法

    前面讲解了MediaPlayer播放网络音频,主要介绍了MediaPlayer关于网络音频的缓冲和进度条控制的方法,本文再来讲解一下MediaPlayer播放网络视频的方法.播放网络视频比播放网络音频需要多一个SurfaceView而已,在已经熟悉了MediaPlayer播放网络音频之后,相信大家对本文所述的播放网络视频也能很快地掌握. 先来看看本文程序运行截图,如下所示: 本文程序的视频来自http://daily3gp.com,大家可以替换程序中的视频链接,试试其他影片. main.xml的

  • android多媒体音乐(MediaPlayer)播放器制作代码

    本文实例为大家分享了android多媒体音乐播放器的具体实现代码,供大家参考,具体内容如下 首先,在AndroidManifest.xml中配置权限 <!-- 读取手机中的音乐 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 注释:Android多媒体音乐的几种来源 1.在andriod的应用中 MediaPlayer.create(this, R.r

  • Android自定义播放器控件VideoView

    介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了.在写VideoView播放视频时候定义控制的代码全写在Actvity里了,写完一看我靠代码好乱,于是就写了个自定义的播放器控件,支持指定大小,可以横竖屏切换,手动左右滑动快进快退.好了,下面开始. 效果图有点卡,我也不知道为啥..... VideoView介绍 这个是我们实现视频播放最主要的控件,详细的介绍大家百度就去看,这里介绍几个常用的方法. 用于播放视频

  • Android实现简单音乐播放器(MediaPlayer)

    Android实现简单音乐播放器(MediaPlayer),供大家参考,具体内容如下 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个简单的音乐播放器,要求功能有: 播放.暂停功能: 进度条显示播放进度功能 拖动进度条改变进度功能: 后台播放功能: 停止功能: 退出功能: 代码实现 导入歌曲到手机SD卡的Music目录中,这里我导入了4首歌曲:仙剑六里面的<誓言成晖>.<剑客不能说>.<镜中人>和<

  • Android编程开发音乐播放器实例

    本文实例讲述了Android编程开发音乐播放器,分享给大家供大家参考,具体如下: 音乐播放器中综合了以下内容: SeekBar.ListView.广播接收者(以代码的形式注册Receiver).系统服务.MediaPlayer 实现的功能: 1.暂停/播放.下一首/上一首,点击某一首时播放 2.支持拖动进度条快进 3.列表排序 4.来电话时,停止播放,挂断后继续播放 5.可在后台播放 效果图: 界面: main.xml: <?xml version="1.0" encoding=

  • android暂停或停止其他音乐播放器的播放实现代码

    代码如下: 复制代码 代码如下: public static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged";    public static final String META_CHANGED = "com.android.music.metachanged";    public static final String QUEUE_CHANGED = "com

随机推荐