Android实现播放音频时的跳动频谱,并实现可以调节的均衡器。

Main.java

  1. package com.wjq.audiofx;
  2. import android.app.Activity;
  3. import android.media.AudioManager;
  4. import android.media.MediaPlayer;
  5. import android.media.audiofx.Equalizer;
  6. import android.media.audiofx.Visualizer;
  7. import android.os.Bundle;
  8. import android.util.Log;
  9. import android.view.Gravity;
  10. import android.view.ViewGroup;
  11. import android.widget.LinearLayout;
  12. import android.widget.SeekBar;
  13. import android.widget.TextView;
  14. public class Main extends Activity {
  15. private static final String TAG = "AudioFxDemo";
  16. private static final float VISUALIZER_HEIGHT_DIP = 50f;
  17. private MediaPlayer mMediaPlayer;
  18. private Visualizer mVisualizer;
  19. private Equalizer mEqualizer;//均横器
  20. private LinearLayout mLinearLayout;
  21. VisualizerView mVisualizerView;
  22. private TextView mStatusTextView;
  23. @Override
  24. public void onCreate(Bundle icicle) {
  25. super.onCreate(icicle);
  26. setVolumeControlStream(AudioManager.STREAM_MUSIC);
  27. mStatusTextView = new TextView(this);
  28. mLinearLayout = new LinearLayout(this);
  29. mLinearLayout.setOrientation(LinearLayout.VERTICAL);
  30. mLinearLayout.addView(mStatusTextView);
  31. setContentView(mLinearLayout);
  32. // Create the MediaPlayer
  33. mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
  34. if( null == mMediaPlayer )
  35. return ;
  36. Log.d(TAG, "MediaPlayer audio session ID: " + mMediaPlayer.getAudioSessionId());
  37. setupVisualizerFxAndUI();
  38. setupEqualizerFxAndUI();
  39. // Make sure the visualizer is enabled only when you actually want to receive data, and
  40. // when it makes sense to receive data.
  41. mVisualizer.setEnabled(true);
  42. // When the stream ends, we don't need to collect any more data. We don't do this in
  43. // setupVisualizerFxAndUI because we likely want to have more, non-Visualizer related code
  44. // in this callback.
  45. mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
  46. public void onCompletion(MediaPlayer mediaPlayer) {
  47. mVisualizer.setEnabled(false);
  48. }
  49. });
  50. mMediaPlayer.start();
  51. mStatusTextView.setText("播放音频...");
  52. }
  53. /**
  54. * 通过mMediaPlayer返回的AudioSessionId创建一个优先级为0均衡器对象,并且通过频谱生成相应的UI和对应的事件
  55. */
  56. private void setupEqualizerFxAndUI() {
  57. mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());
  58. // 启用均衡器
  59. mEqualizer.setEnabled(true);
  60. TextView eqTextView = new TextView(this);
  61. eqTextView.setText("均横器:");
  62. mLinearLayout.addView(eqTextView);
  63. // 通过均衡器得到其支持的频谱引擎
  64. short bands = mEqualizer.getNumberOfBands();
  65. // getBandLevelRange是一个数组,返回一组频谱等级数组,返回一组频谱等级数组
  66. // 第一个下标为最低的限度范围,第二个下标为最高的限度范围
  67. // 依次取出
  68. final short minEQLevel = mEqualizer.getBandLevelRange()[0];
  69. final short maxEQLevel = mEqualizer.getBandLevelRange()[1];
  70. for (short i = 0; i < bands; i++) {
  71. final short band = i;
  72. TextView freqTextView = new TextView(this);
  73. freqTextView.setLayoutParams(new ViewGroup.LayoutParams(
  74. ViewGroup.LayoutParams.FILL_PARENT,
  75. ViewGroup.LayoutParams.WRAP_CONTENT));
  76. freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);
  77. freqTextView.setText((mEqualizer.getCenterFreq(band) / 1000) + " Hz");
  78. mLinearLayout.addView(freqTextView);
  79. LinearLayout row = new LinearLayout(this);
  80. row.setOrientation(LinearLayout.HORIZONTAL);
  81. TextView minDbTextView = new TextView(this);
  82. minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
  83. ViewGroup.LayoutParams.WRAP_CONTENT,
  84. ViewGroup.LayoutParams.WRAP_CONTENT));
  85. minDbTextView.setText((minEQLevel / 100) + " dB");
  86. TextView maxDbTextView = new TextView(this);
  87. maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
  88. ViewGroup.LayoutParams.WRAP_CONTENT,
  89. ViewGroup.LayoutParams.WRAP_CONTENT));
  90. maxDbTextView.setText((maxEQLevel / 100) + " dB");
  91. LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
  92. ViewGroup.LayoutParams.FILL_PARENT,
  93. ViewGroup.LayoutParams.WRAP_CONTENT);
  94. layoutParams.weight = 1;
  95. SeekBar bar = new SeekBar(this);
  96. bar.setLayoutParams(layoutParams);
  97. bar.setMax(maxEQLevel - minEQLevel);
  98. bar.setProgress(mEqualizer.getBandLevel(band));
  99. bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
  100. public void onStopTrackingTouch(SeekBar seekBar) {}
  101. public void onStartTrackingTouch(SeekBar seekBar) {}
  102. public void onProgressChanged(SeekBar seekBar, int progress,
  103. boolean fromUser) {
  104. mEqualizer.setBandLevel(band, (short) (progress + minEQLevel));
  105. }
  106. });
  107. row.addView(minDbTextView);
  108. row.addView(bar);
  109. row.addView(maxDbTextView);
  110. mLinearLayout.addView(row);
  111. }
  112. }
  113. /**
  114. * 生成一个VisualizerView对象,使音频频谱的波段能够反映到 VisualizerView上
  115. */
  116. private void setupVisualizerFxAndUI() {
  117. mVisualizerView = new VisualizerView(this);
  118. mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(
  119. ViewGroup.LayoutParams.FILL_PARENT,
  120. (int)(VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density)));
  121. mLinearLayout.addView(mVisualizerView);
  122. int sessId = mMediaPlayer.getAudioSessionId() ;
  123. mVisualizer = new Visualizer(sessId);
  124. // 参数必须是2的位数
  125. mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
  126. // 设置允许波形表示,并且捕获它
  127. mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
  128. public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
  129. int samplingRate) {
  130. mVisualizerView.updateVisualizer(bytes);
  131. }
  132. public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {}
  133. }, Visualizer.getMaxCaptureRate() / 2, true, false);
  134. }
  135. @Override
  136. protected void onPause() {
  137. super.onPause();
  138. if (isFinishing() && mMediaPlayer != null) {
  139. mVisualizer.release();
  140. mEqualizer.release();
  141. mMediaPlayer.release();
  142. mMediaPlayer = null;
  143. }
  144. }
  145. }

VisualizerView.java

  1. package com.wjq.audiofx;
  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Color;
  5. import android.graphics.Paint;
  6. import android.graphics.Rect;
  7. import android.view.View;
  8. public class VisualizerView extends View {
  9. private byte[] mBytes;
  10. private float[] mPoints;
  11. //矩形区域
  12. private Rect mRect = new Rect();
  13. // 画笔
  14. private Paint mForePaint = new Paint();
  15. // 初始化画笔
  16. private void init() {
  17. mBytes = null;
  18. mForePaint.setStrokeWidth(1f);
  19. mForePaint.setAntiAlias(true);
  20. mForePaint.setColor(Color.GREEN);
  21. }
  22. public VisualizerView(Context context) {
  23. super(context);
  24. init();
  25. }
  26. public void updateVisualizer(byte[] bytes) {
  27. mBytes = bytes;
  28. invalidate();
  29. }
  30. @Override
  31. protected void onDraw(Canvas canvas) {
  32. super.onDraw(canvas);
  33. if (mBytes == null) {
  34. return;
  35. }
  36. if (mPoints == null || mPoints.length < mBytes.length * 4) {
  37. mPoints = new float[mBytes.length * 4];
  38. }
  39. mRect.set(0, 0, getWidth(), getHeight());
  40. for (int i = 0; i < mBytes.length - 1; i++) {
  41. mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1);
  42. mPoints[i * 4 + 1] = mRect.height() / 2
  43. + ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128;
  44. mPoints[i * 4 + 2] = mRect.width() * (i + 1) / (mBytes.length - 1);
  45. mPoints[i * 4 + 3] = mRect.height() / 2
  46. + ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2) / 128;
  47. }
  48. canvas.drawLines(mPoints, mForePaint);
  49. }
  50. }

Android播放音乐时跳动的屏谱demo的更多相关文章

  1. android 播放视频时切换全屏隐藏状态栏

    1. Demo: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...

  2. android 播放音乐-进度条

    今天学渣研究了一下使用MediaPlayer播放音乐时加入进度条,进度条如今用的是android自带的seekbar,后期会跟换UI的,在之前可以播放音乐的基础上,如今加入的主要功能有两个: 1实时显 ...

  3. 绘制播放音乐时的音波图形的View

    绘制播放音乐时的音波图形的View 这个效果类似于这个哦: 效果如下: 源码: MusicView.h 与 MusicView.m // // MusicView.h // Music // // C ...

  4. android 播放音乐媒体文件(一)

    Audio formats and codecs Format / Codec Encoder Decoder Details Supported File Type(s) / Container F ...

  5. Android 播放电影时滑动屏幕调整屏幕亮度(转)

    (转自:http://blog.csdn.net/piaozhiye/article/details/6544450) 发现有一些主流的播放器播放电影时可以通过滑动屏幕调整屏幕亮度,其实实现起来也很容 ...

  6. 关于Windows 8使用WMP播放音乐时WUDFHost跑CPU和硬盘的问题解决

    Windows 8使用Windows Media Player播放音乐的时候.事实上有一个这种情况,WMP和某个什么名字看起来非常屌的进程跑CPU非常高,这个跑非常高视你插入的SD卡内的文件数或者移动 ...

  7. android修改系统时系统黑屏时不进入休眠状态

    基于android4.4修改,在frameworks/base/services/java/com/android/server/power/PowerManagerService.java里,查看休 ...

  8. android关闭屏幕时不锁屏实现

    所需权限: <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> 关闭系统锁屏服务 ...

  9. 解决Android Activity切换时出现白屏问题

    有些性能低的机器,在切换activity时候出现白屏一段时候后才显示正确的视图 高性能的机器可能太快看不到,但是事实是存在的, 特别是当你新开一个进程的时候,A进程的activity跳转到B进程的Ac ...

随机推荐

  1. TabSpec和TabHost实例

    TabSpec与TabHost TabHost相当于浏览器中浏览器分布的集合,而Tabspec则相当于浏览器中的每一个分页面.d在Android中,每一个TabSpec分布可以是一个组件,也可以是一个 ...

  2. [每日一题] 11gOCP 1z0-052 :2013-09-14 repeated parsing activity.................................A70

    转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/11699299 正确答案:D SQL语句的执行过程: 1.客户端输入sql语句update ...

  3. 王立平--android事件监听的3种方式

    第一种通常在activity组件的oncreate事件中直接定义,直接动作. 这样的方式每一个控件都定义一次.通常不方便. Button btn = (Button) findViewById(R.i ...

  4. 【Hibernate】HQL new map

    HQL 查询如果需要带出对象(比如:OneToOne子对象)的一两个属性,而不是全部带出.可以使用 select new map的方法带出. 1.lazy还是设置为false /**关联属性对象*/ ...

  5. 04-C语言数据类型

    目录: 一. 注释 二.数据类型 三. 输入函数scanf 四.转义符\ 五.char数据范围 六.int整形 七.float与double 八.进制转换 回到顶部 一. 注释 1 解释代码的意义,注 ...

  6. Week4(9月30日):

    Part I:提问  =========================== 1.什么是DRY? 2.解释下面的模型验证规则. public class Movie { public int ID { ...

  7. Delphi启动/停止Windows服务,启动类型修改为"自动"

    unit U_StartServices; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Contr ...

  8. fancyBox简单入门

    1. 下载 fancyBox,解压后根据需要将文件复制到网页文件夹中(建议不要更改目录结构),并在网页源码中引入相应的 css 样式和 js 文件(如果更改了目录结构,引入的时候请调整相应代码,对应它 ...

  9. 执行Git命令时出现 SSL certificate problem 的解决办法

    比如我在windows下用git clone gitURL 就提示  SSL certificate problem: self signed certificate 这种问题,在windows下出现 ...

  10. JavaScript 中的日期和时间

    前言 本篇的介绍涵盖以下部分: 1. 时间标准指的是什么?UCT和GMT 的概念.关联和区别? 2. 时间表示标准有哪些? 3. JS 中时间的处理 日期时间标准 日期的标准就不多说了 -- 公元纪年 ...