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. 首届全球RTB(实时竞价)广告DSP算法大赛

    首届全球RTB(实时竞价)广告DSP算法大赛 竞赛指南     RTB (Real Time Bidding, 实时竞价) 是近年来计算广告领域最激动人心的进展之一. 它增加了展示广告的透明度与效率, ...

  2. uva11021 - Tribles(概率)

    11021 - Tribles GRAVITATION, n.“The tendency of all bodies to approach one another with a strengthpr ...

  3. 2-06. 数列求和(20)(ZJUPAT 数学)

    题目链接:http://pat.zju.edu.cn/contests/ds/2-06 给定某数字A(1<=A<=9)以及非负整数N(0<=N<=100000).求数列之和S ...

  4. 【Eclipse】离线插件安装

    1.在eclipse里根目录里,dropins里建一个目录,名字叫sonar(这个名字随便),再在svn下面建一个目录eclipse.在根目录里建一个目录links目录,并建一个sonar.link文 ...

  5. OpenSSL命令---req

    用途: 本指令用来创建和处理PKCS#10格式的证书.它还能够建立自签名证书,做Root CA. 用法: openssl req [-inform PEM|DER] [-outform PEM|DER ...

  6. HDU 3932 Groundhog Build Home 【基础模拟退火】

    和刚才那道是一模一样 不过求的是最小的,只要稍微修改一下就可以了~ //#pragma comment(linker, "/STACK:16777216") //for c++ C ...

  7. HTML 5 Web Storage 使用

    在html中,可以使用 Web Storage API 来保存数据在浏览器客户端,这样可以避免重复从服务器加载数据. 有两种API, sessionStorage 和 localStorage ,它们 ...

  8. Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactory

    Error creating bean with name ‘org.springframework.validation.beanvalidation.LocalValidatorFactoryBe ...

  9. 转:CSS选择器笔记

    作者: 阮一峰 日期: 2009年3月12日 去年我学jQuery的时候,曾经做过一点选择器(selector)的笔记. 这几天拿出来看了一下,发现很多都忘记了.所以,我决定把它们贴在这里,方便以后查 ...

  10. JMS和消息驱动Bean(MDB)

    一.说明 本示例使用的ActiveMQ作为消息中间件,服务器为Glassfish,使用JMS发送消息,在MDB接收到消息之后做打印输出. 二.ActiveMQ安装配置 1.安装console war包 ...