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

时间: 2024-09-28 15:30:43

Android编程之播放器MediaPlayer实现均衡器效果示例的相关文章

Android媒体播放器MediaPlayer架构介绍教程

本文主要介绍的是Android中很重要也最为复杂的媒体播放器(MediaPlayer)部分的架构.对于Android这样一个完整又相对复杂的系统,一个MediaPlayer功能的实现不在其具体的功能,而是具体功能如何适应Android系统Android MediaPlayer的主要具体实现在OpenCore的Player中,这部分不是本文的关注点.本文关注的是MediaPlayer系统的架构,其他的一些Android的应用程序也使用类似的架构. 第一部分 MediaPlayer概述 Androi

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

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

Android编程实现播放视频的方法示例

本文实例讲述了Android编程实现播放视频的方法.分享给大家供大家参考,具体如下: 播放视频文件其实并不比播放音频文件复杂,主要是使用 VideoView 类来实现的.这个 类将视频的显示和控制集于一身,使得我们仅仅借助它就可以完成一个简易的视频播放器. VideoView 的用法和 MediaPlayer 也比较类似,主要有以下常用方法: 方法名 功能描述 setVideoPath() 设置要播放的视频文件的位置. start() 开始或继续播放视频. pause() 暂停播放视频. res

Android编程实现播放音频的方法示例

本文实例讲述了Android编程实现播放音频的方法.分享给大家供大家参考,具体如下: 在 Android 中播放音频文件一般都是使用 MediaPlayer 类来实现的,它对多种格式的音 频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得十分简单.下表列出了 MediaPlayer 类中一些较为常用的控制方法. 方法名 功能描述 setDataSource() 设置要播放的音频文件的位置. prepare() 在开始播放之前调用这个方法完成准备工作. start() 开始或继续播放音频.

android 音乐播放器-android开发音乐播放器

问题描述 android开发音乐播放器 android开发音乐播放器怎么把歌曲放到项目中,一起打包到apk中??? 解决方案 一般多媒体文件都是放在raw目录下的,但音乐播放器的话,不建议把歌曲打包到apk中,可以把歌曲放在SD卡中,通过扫描sd卡的方式获取歌曲 解决方案二: 音乐播放器中综合了以下内容: SeekBar.ListView.广播接收者(以代码的形式注册Receiver).系统服务.MediaPlayer 实现的功能: 1.暂停/播放.下一首/上一首,点击某一首时播放 2.支持拖动

Android编程实现播放MP3功能示例

本文实例讲述了Android编程实现播放MP3功能.分享给大家供大家参考,具体如下: 在android中播放mp3非常简单,也是项目中经常使用的,比如说要做项目的背景音乐,应用中某些功能的提示音等的.应用非常广泛,下面提供一个简单的使用实例: layout文件的配置: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.and

Android仿音乐播放器功能

本文实例为大家分享了Android仿音乐播放器功能的具体代码,供大家参考,具体内容如下 读取本地音乐文件 源代码: import android.media.MediaPlayer; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ImageButton; import android.widget.

android音乐播放器-Android关于音乐播放器频谱可视化图形的问题,急!

问题描述 Android关于音乐播放器频谱可视化图形的问题,急! 如上图,底部频谱可视化图形不会动了,不知道是什么原因造成的.首先我说下我目前知道的可能造成这种情况的事情.因为我的这个播放器里的播放列表这一项,要同步android系统媒体库里的播放列表.也就是说在系统的播放器中的播放列表会出现在我的播放器的播放列表中.本来我的包名是这样的:com.music.musicmenu 这样就不会出现上述问题,当我把包名改成系统的com.android.music 这时就会出现上述问题.也就是频谱不会动

jamendo_android 一个开源的Android在线音乐播放器实例

一个开源的Android在线音乐播放器实例.整套源码主要实现了专辑浏览,音乐在线播放,下载等等.虽说看起来功能不多,但是绝对十分具有参考价值,考虑的十分严谨.因为里面应用了网络通讯,json解析,全局mediaservice,自定义View组件,自定义 Adapter,application全局缓存,变量等等,所有要在项目中考虑到的优化问题. 项目主页:http://www.open-open.com/lib/view/home/1344734233116