Android编程之播放器MediaPlayer实现均衡器效果示例
程序员文章站
2023-12-04 10:50:28
本文实例讲述了android播放器mediaplayer实现均衡器效果。分享给大家供大家参考,具体如下:
这几天在系统学习android官方api demos,看到实现均...
本文实例讲述了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程序设计有所帮助。