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 ...
随机推荐
- Python开源异步并发框架
Python开源异步并发框架的未来 2014年3月30日,由全球最大的中文IT社区CSDN主办的“开源技术大会·” (Open Source Technology Conference ,简称OSTC ...
- IT第九天 - 包、访问修饰符、变量的内存分配、String类中常用方法
IT第九天 上午 包 1.包的命名规则:域名.项目名称.模块名 2.如:Wfei.com.windows.login 访问限制符 1.四种访问限制符分别对应为: (1)default:默认的,默认为p ...
- 读懂Swift 2.0中字符串设计思路的改变
Swift提供了一种高性能的,兼容Unicode编码的String实现作为标准库的一部分.在 Swift2中,String类型不再遵守CollectionType协议.在以前,String类型是字符的 ...
- ExtJS4.2 - 从 Hello World 到 自定义组件 -01 (为爱女伊兰奋斗)
ExtJS4.2 - 从 Hello World 到 自定义组件 - 01 经验.概述.项目搭建.国际化.HelloWorld.布局 —— 为爱女伊兰而奋斗 ——少走弯路,简单才是王道 1. 写在前面 ...
- 【DWR】Annotation入门
DWR简介:http://baike.baidu.com/view/73492.htm?fr=aladdin DWR2.0以后新增加了JDK5的注解(Annotation)功能,使用注解功能之后可以从 ...
- iOS 开发http post 文件的上传
iOS开发网络篇—文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代 ...
- ubuntu15.04更新软件源
1,首先备份原来的源 sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup2,编辑软件源的文件 sudo vim /etc/apt/so ...
- fastxml Jackson JsonNode (ObjectNode) 转 List
做环聊开发, Java 后台示例 用的 fastxml Jackson 解析json(擦, 狗屎, 不能支持下国产吗?) 有的json字段是数组, 发现不会解析了, 谷歌了下, 用以下方法可行,(不知 ...
- 为什么 Flask 有那么多的好评?
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:松鼠奥利奥链接:http://www.zhihu.com/question/28902969/answer/42530571来 ...
- POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)
用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一 ...