Android播放音乐时跳动的屏谱demo
Android实现播放音频时的跳动频谱,并实现可以调节的均衡器。
Main.java
- package com.wjq.audiofx;
- import android.app.Activity;
- import android.media.AudioManager;
- import android.media.MediaPlayer;
- import android.media.audiofx.Equalizer;
- import android.media.audiofx.Visualizer;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.Gravity;
- import android.view.ViewGroup;
- import android.widget.LinearLayout;
- import android.widget.SeekBar;
- import android.widget.TextView;
- public class Main 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;
- VisualizerView mVisualizerView;
- private TextView mStatusTextView;
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setVolumeControlStream(AudioManager.STREAM_MUSIC);
- mStatusTextView = new TextView(this);
- mLinearLayout = new LinearLayout(this);
- mLinearLayout.setOrientation(LinearLayout.VERTICAL);
- mLinearLayout.addView(mStatusTextView);
- setContentView(mLinearLayout);
- // Create the MediaPlayer
- mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
- if( null == mMediaPlayer )
- return ;
- 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);
- }
- });
- mMediaPlayer.start();
- mStatusTextView.setText("播放音频...");
- }
- /**
- * 通过mMediaPlayer返回的AudioSessionId创建一个优先级为0均衡器对象,并且通过频谱生成相应的UI和对应的事件
- */
- private void setupEqualizerFxAndUI() {
- mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());
- // 启用均衡器
- mEqualizer.setEnabled(true);
- TextView eqTextView = new TextView(this);
- eqTextView.setText("均横器:");
- mLinearLayout.addView(eqTextView);
- // 通过均衡器得到其支持的频谱引擎
- short bands = mEqualizer.getNumberOfBands();
- // getBandLevelRange是一个数组,返回一组频谱等级数组,返回一组频谱等级数组
- // 第一个下标为最低的限度范围,第二个下标为最高的限度范围
- // 依次取出
- 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.FILL_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.FILL_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 onStopTrackingTouch(SeekBar seekBar) {}
- public void onStartTrackingTouch(SeekBar seekBar) {}
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- mEqualizer.setBandLevel(band, (short) (progress + minEQLevel));
- }
- });
- row.addView(minDbTextView);
- row.addView(bar);
- row.addView(maxDbTextView);
- mLinearLayout.addView(row);
- }
- }
- /**
- * 生成一个VisualizerView对象,使音频频谱的波段能够反映到 VisualizerView上
- */
- private void setupVisualizerFxAndUI() {
- mVisualizerView = new VisualizerView(this);
- mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- (int)(VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density)));
- mLinearLayout.addView(mVisualizerView);
- int sessId = mMediaPlayer.getAudioSessionId() ;
- mVisualizer = new Visualizer(sessId);
- // 参数必须是2的位数
- 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;
- }
- }
- }
VisualizerView.java
- package com.wjq.audiofx;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.view.View;
- public class VisualizerView extends View {
- private byte[] mBytes;
- private float[] mPoints;
- //矩形区域
- private Rect mRect = new Rect();
- // 画笔
- private Paint mForePaint = new Paint();
- // 初始化画笔
- private void init() {
- mBytes = null;
- mForePaint.setStrokeWidth(1f);
- mForePaint.setAntiAlias(true);
- mForePaint.setColor(Color.GREEN);
- }
- public VisualizerView(Context context) {
- super(context);
- init();
- }
- public void updateVisualizer(byte[] bytes) {
- mBytes = bytes;
- invalidate();
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (mBytes == null) {
- return;
- }
- if (mPoints == null || mPoints.length < mBytes.length * 4) {
- mPoints = new float[mBytes.length * 4];
- }
- mRect.set(0, 0, getWidth(), getHeight());
- for (int i = 0; i < mBytes.length - 1; i++) {
- mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1);
- mPoints[i * 4 + 1] = mRect.height() / 2
- + ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128;
- mPoints[i * 4 + 2] = mRect.width() * (i + 1) / (mBytes.length - 1);
- mPoints[i * 4 + 3] = mRect.height() / 2
- + ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2) / 128;
- }
- canvas.drawLines(mPoints, mForePaint);
- }
- }
Android播放音乐时跳动的屏谱demo的更多相关文章
- android 播放视频时切换全屏隐藏状态栏
1. Demo: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...
- android 播放音乐-进度条
今天学渣研究了一下使用MediaPlayer播放音乐时加入进度条,进度条如今用的是android自带的seekbar,后期会跟换UI的,在之前可以播放音乐的基础上,如今加入的主要功能有两个: 1实时显 ...
- 绘制播放音乐时的音波图形的View
绘制播放音乐时的音波图形的View 这个效果类似于这个哦: 效果如下: 源码: MusicView.h 与 MusicView.m // // MusicView.h // Music // // C ...
- android 播放音乐媒体文件(一)
Audio formats and codecs Format / Codec Encoder Decoder Details Supported File Type(s) / Container F ...
- Android 播放电影时滑动屏幕调整屏幕亮度(转)
(转自:http://blog.csdn.net/piaozhiye/article/details/6544450) 发现有一些主流的播放器播放电影时可以通过滑动屏幕调整屏幕亮度,其实实现起来也很容 ...
- 关于Windows 8使用WMP播放音乐时WUDFHost跑CPU和硬盘的问题解决
Windows 8使用Windows Media Player播放音乐的时候.事实上有一个这种情况,WMP和某个什么名字看起来非常屌的进程跑CPU非常高,这个跑非常高视你插入的SD卡内的文件数或者移动 ...
- android修改系统时系统黑屏时不进入休眠状态
基于android4.4修改,在frameworks/base/services/java/com/android/server/power/PowerManagerService.java里,查看休 ...
- android关闭屏幕时不锁屏实现
所需权限: <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> 关闭系统锁屏服务 ...
- 解决Android Activity切换时出现白屏问题
有些性能低的机器,在切换activity时候出现白屏一段时候后才显示正确的视图 高性能的机器可能太快看不到,但是事实是存在的, 特别是当你新开一个进程的时候,A进程的activity跳转到B进程的Ac ...
随机推荐
- (step8.2.4)hdu 1846(Brave Game——巴什博奕)
题目大意:输入一个整数t,表示测试用例是.接着输入2个整数n,m.分别表示这堆石头中石头的个数,和每次所能取得最大的石头数.判断那一方为赢家 解题思路: 1)这是一道简单的巴什博弈: 所谓巴什博弈,是 ...
- Python中单引号、双引号和三引号的区别
ython单引号.双引号和三双引号的区别 python字符串通常有单引号('...').双引号("...").三引号("""..."&quo ...
- MFC中SDI程序创建流程的回顾
SDI程序创建流程的回顾 从CWinApp.InitialInstance()开始, 1.首先应用程序对象创建文档模板; CSingleDocTemplate* pDocTemplate; pDocT ...
- Lua,Lua API,配置文件
想像一个场景:你的c程序须要有一个窗体,你想让用户能够自己定义窗体大小.方法非常多.比方使用环境变量,或键值对的文件. 无论如何,你须要解析它. 使用lua配置文件是个不错的选择. 首先,你能够定义例 ...
- iOS之UITableViewCell左右滑动效果
首先在 UITableViewCell.h 中声明一个代理 @protocol UITableViewCellSlideDelegate <UITableViewDelegate> @op ...
- linux 内核头文件 linux kernel header
概述:在进行有关系统软件的安装的时候(编译一个新的驱动,或者安装一个系统级别的测试工具,例如systemtap),经常需要重新编译内核,相应的问题往往与内核头文件有关.那么,什么是内核头文件,为什么需 ...
- c# datagridviewcomboboxcell值无效的解决办法
一直认为是数据库存储的数据和datagridviewcomboboxcell对不上导致,今天碰到两者对应上了,预览的时候还是提示错误, 查看了下网上其他大神的解决方法,是数据库字段类型有误,查看了下, ...
- ViewPager实现启动引导页面(个人认为很详细)
效果如图: 启动页面是一张图片+延时效果,这里就不给出布局文件了. WelcomeActivity分析:在启动页面检测是否是第一次运行程序,如果是,则先跳转到引导界面的Activity——AndyVi ...
- Miller_Rabin、 Pollard_rho Template
Multiply and pow Function: //计算 (a*b)%c. a,b都是ll的数,直接相乘可能溢出的 // a,b,c <2^63 ll mult_modq(ll a,ll ...
- ORACLE存储过程笔记1
ORACLE存储过程笔记1 一.基本语法(以及与informix的比较) create [or replace] procedure procedure_name (varible {IN|OUT ...