欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-04 10:50:28
本文实例讲述了android播放器mediaplayer实现均衡器效果。分享给大家供大家参考,具体如下: 这几天在系统学习android官方api demos,看到实现均...

本文实例讲述了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程序设计有所帮助。