android在播放音乐时如何实现动态波形?
进口?Android . app . activity;
进口?Android . content . context;
进口?Android . graphics . canvas;
进口?Android . graphics . color;
进口?Android . graphics . paint;
进口?Android . graphics . rect;
进口?Android . media . audio manager;
进口?Android . media . media player;
进口?android.media.audiofx .均衡器;
进口?Android . media . audio FX . visualizer;
进口?Android . OS . bundle;
进口?Android . util . log;
进口?Android . view . gravity;
进口?Android . view . view;
进口?Android . view . view group;
进口?Android . view . window manager;
进口?Android . widget . linear layout;
进口?Android . widget . seek bar;
进口?Android . widget . textview;
公共?班级?AudioFxActivity?延伸?活动
{
私人?静电?决赛?字符串?标签?=?”AudioFxActivity”;
私人?静电?决赛?浮动?VISUALIZER_HEIGHT_DIP?=?160 f;
私人?MediaPlayer?多媒体播放器;
私人?可视化工具?mVisualizer
私人?均衡器?mEqualizer
私人?LinearLayout?mLinearLayout
私人?VisualizerView?mVisualizerView
私人?TextView?mStatusTextView
私人?TextView?mInfoView
@覆盖
公共?作废?onCreate(捆绑?冰柱)
{
super . oncreate(icicle);
mStatusTextView?=?新的?TextView(这个);
mLinearLayout?=?新的?LinearLayout(这个);
mlinearlayout . set orientation(linear layout。垂直);
mlinearlayout . add view(mStatusTextView);
setContentView(mLinearLayout);
//?创造?那个?媒体播放器
多媒体播放器?=?MediaPlayer.create(this,?r . raw . my _ life);
Log.d(标签,
“MediaPlayer?音频?会话?ID:?"
+?mmediaplayer . getaudiosessionid());
setup visualizerfxandui();
setupequilizerfxandui();
//?制造?确定吗?那个?可视化工具?是吗?启用?只有?什么时候?你呢。真的吗?想要吗?到
//?接收?数据,?和
//?什么时候?它?制造?感觉?去哪?接收?数据。
mvisualizer . set enabled(true);
//?什么时候?那个?溪流?结束吗?我们?不要?需要?去哪?收藏?有吗?更多?数据。?我们
//?不要?做什么?这个?在
//?setupVisualizerFxAndUI?因为?我们?可能吗?想要吗?去哪?有吗?更多,
//?非可视化者?相关?密码
//?在?这个?回电。
mmediaplayer . setoncompletionlistener(新?媒体播放器。OnCompletionListener()
{
公共?作废?onCompletion(MediaPlayer?媒体播放器)
{
mvisualizer . set enabled(false);
getWindow()。clearFlags(WindowManager。layout params . FLAG _ KEEP _ SCREEN _ ON);
setVolumeControlStream(audio manager。STREAM _ SYSTEM);
MStatusTextView.setText("音乐完成");
}
});
getWindow()。addFlags(WindowManager。layout params . FLAG _ KEEP _ SCREEN _ ON);
setVolumeControlStream(audio manager。STREAM _ MUSIC);
mmediaplayer . start();
MStatusTextView.setText("播放音乐...");
}
私人?作废?setupEqualizerFxAndUI()
{
//?创造?那个?均衡器?对象?(安?音效?子类)?然后呢。附上?它
//?去哪?我们的?媒体?玩家,
//?用什么?答?违约?优先?(0).
mEqualizer?=?新的?均衡器(0,?mmediaplayer . getaudiosessionid());
me qualizer . set enabled(true);
TextView?eqTextView?=?新的?TextView(这个);
EqTextView.setText("均衡器:");
mlinearlayout . addview(eqTextView);
矮?乐队?=?me qualizer . getnumberofbands();
决赛?矮?minEQLevel?=?me qualizer . getbandlevelrange()[0];
决赛?矮?maxEQLevel?=?me qualizer . getbandlevelrange()[1];
为了什么?(短?我?=?0;?我?& lt?乐队;?i++)
{
决赛?矮?乐队?=?我;
TextView?freqTextView?=?新的?TextView(这个);
freqTextView.setLayoutParams(新?视图组。布局参数(
视图组。LayoutParams.FILL_PARENT,
视图组。layout params . WRAP _ CONTENT));
freqtextview . set Gravity(Gravity。居中_水平);
freqtextview . settext((me qualifier . getcenterfreq(band)?/?1000)
+?"?Hz”);
mlinearlayout . add view(freqTextView);
LinearLayout?划?=?新的?LinearLayout(这个);
row . set orientation(linear layout。横向);
TextView?minDbTextView?=?新的?TextView(这个);
minDbTextView.setLayoutParams(新?视图组。布局参数(
视图组。LayoutParams.WRAP_CONTENT,
视图组。layout params . WRAP _ CONTENT));
mindbtextview . settext((minEQLevel?/?100)?+?"?dB”);
TextView?maxDbTextView?=?新的?TextView(这个);
maxDbTextView.setLayoutParams(新?视图组。布局参数(
视图组。LayoutParams.WRAP_CONTENT,
视图组。layout params . WRAP _ CONTENT));
maxdbtextview . settext((maxEQLevel?/?100)?+?"?dB”);
线性布局。LayoutParams?layoutParams?=?新的?线性布局。布局参数(
视图组。LayoutParams.FILL_PARENT,
视图组。layout params . WRAP _ CONTENT);
布局参数。重量?=?1;
SeekBar?酒吧?=?新的?SeekBar(这个);
bar . setlayoutparams(layout params);
bar.setMax(maxEQLevel?-?minEQLevel);
bar . set progress(me qualizer . get band level(band));
bar.setOnSeekBarChangeListener(新?SeekBar。OnSeekBarChangeListener()
{
公共?作废?onProgressChanged(SeekBar?seekBar?int?进步,
布尔?fromUser)
{
mEqualizer.setBandLevel(band,?(短)?(进步?+?minEQLevel));
}
公共?作废?onStartTrackingTouch(参见kBar?seekBar)
{
}
公共?作废?onStopTrackingTouch(SeekBar?seekBar)
{
}
});
row . add view(minDbTextView);
row . add view(bar);
row . addview(maxDbTextView);
mlinearlayout . add view(row);
}
}
私人?作废?setupVisualizerFxAndUI()
{
mVisualizerView?=?新的?visualizer view(this);
mvisualizerview . setlayoutparams(新?视图组。布局参数(
视图组。LayoutParams.FILL_PARENT,
(int)?(VISUALIZER_HEIGHT_DIP?*?getResources()
。getDisplayMetrics()。密度)));
mlinearlayout . add view(mVisualizerView);
mInfoView?=?新的?TextView(这个);
字符串?infoStr?=?"";
int[]?csr?=?visualizer . getcapturesizerange();
如果(csr?!=?空)
{
字符串?csrStr?=?" CaptureSizeRange:";
for(int?我?=?0;?我?& lt?csr .长度;?我?++)
{
csrStr?+=?CSR[I];
csrStr?+="?";
}
infoStr?+=?csrStr
}
决赛?int?maxCR?=?visualizer . getmaxcapturerate();
infoStr?=?infoStr?+?" nMaxCaptureRate:?"?+?maxCR
minfoview . settext(infoStr);
mlinearlayout . add view(mInfoView);
mVisualizer?=?新的?可视化工具(mmediaplayer . getaudiosessionid());
mvisualizer . setcapturesize(256);
mvisualizer . setdatacapturelistener(
新的?可视化工具。OnDataCaptureListener()
{
公共?作废?onWaveFormDataCapture(可视化工具?可视化工具,
byte[]?字节,?int?采样率)
{
mvisualizerview . update visualizer(字节);
}
公共?作废?onFftDataCapture(可视化工具?可视化工具,
byte[]?fft,?int?采样率)
{
mvisualizerview . update visualizer(FFT);
}
},?maxCR?/?2,?假的,?真);
}
@覆盖
受保护?作废?onPause()
{
super . on pause();
如果?(isFinishing()?& amp& amp?多媒体播放器?!=?空)
{
mvisualizer . release();
me qualizer . release();
mmediaplayer . release();
多媒体播放器?=?null
}
}
/**
?*?答?简单?班级?那个?平局?波形?数据?收到?从哪里?a
?*?{@link?可视化工具。ondatapturelistener # onWaveFormDataCapture?}
?*/
班级?VisualizerView?延伸?视角
{
私人?byte[]?兆字节;
私人?float[]?mPoints
私人?Rect?mRect?=?新的?rect();
私人?油漆?mForePaint?=?新的?paint();
私人?int?mSpectrumNum?=?48;
私人?布尔?mFirst?=?真实;
公共?VisualizerView(上下文?上下文)
{
超级(上下文);
init();
}
私人?作废?初始化()
{
兆字节?=?null
mfore paint . setstrokewidth(8f);
mfore paint . setantialias(true);
mfore paint . set color(color . RGB(0,?128,?255));
}
公共?作废?updateVisualizer(byte[]?fft)
{
if(mFirst?)
{
minfoview . settext(minfoview . gettext()。toString()?+?" \ n捕获大小:"?+?FFT . length);
mFirst?=?假的;
}
byte[]?模特?=?新的?byte[fft.length?/?2?+?1];
型号[0]?=?(字节)?math . ABS(FFT[0]);
为了什么?(int?我?=?2,?j?=?1;?j?& lt?光谱图;)
{
型号[j]?=?(字节)?Math.hypot(fft[i],?fft【我?+?1]);
我?+=?2;
j++;
}
兆字节?=?模型;
invalidate();
}
@覆盖
受保护?作废?onDraw(画布?画布)
{
super.onDraw(画布);
如果?(兆字节?==?空)
{
返回;
}
如果?(mPoints?==?null?||?mPoints.length?& lt?兆字节。长度?*?4)
{
mPoints?=?新的?float[mBytes.length?*?4];
}
mRect.set(0,0,?getWidth(),?getHeight());
//绘制波形
//?为了什么?(int?我?=?0;?我?& lt?兆字节。长度?-?1;?i++)?{
//?mPoints[i?*?4]?=?mRect.width()?*?我?/?(兆字节.长度?-?1);
//?mPoints[i?*?4?+?1]?=?mRect.height()?/?2
//?+?((字节)?(mBytes[i]?+?128))?*?(mRect.height()?/?2)?/?128;
//?mPoints[i?*?4?+?2]?=?mRect.width()?*?(我?+?1)?/?(兆字节.长度?-?1);
//?mPoints[i?*?4?+?3]?=?mRect.height()?/?2
//?+?((字节)?(mBytes[i?+?1]?+?128))?*?(mRect.height()?/?2)?/?128;
//?}
//绘制频谱
决赛?int?baseX?=?mrect . width()/mSpectrumNum;
决赛?int?身高?=?mrect . height();
为了什么?(int?我?=?0;?我?& lt?mSpectrumNum?;?i++)
{
如果?(mBytes[i]?& lt?0)
{
兆字节[i]?=?127;
}
决赛?int?xi?=?baseX*i?+?baseX/2;
mPoints[i?*?4]?=?Xi;
mPoints[i?*?4?+?1]?=?身高;
mPoints[i?*?4?+?2]?=?Xi;
mPoints[i?*?4?+?3]?=?身高?-?兆字节[I];
}
canvas.drawLines(mPoints,?mfore paint);
}
}
}