牙叔教程 简单易懂
效果展示
缘起
看视频的时候, 觉得人家的音乐动效特别好看, 上面这个效果还是没有人家的好看, 算个音乐动效雏形吧
环境
雷电模拟器: 4.0.63
Android版本: 7.1.2
Autojs版本: 8.8.20
思路
读取音频数据, 格式化数据, 再用canvas画数据
你将学到以下知识点
- 检查及申请录音权限
- 监听申请权限的结果
- Visualizer的基本使用
- canvas画线段
- 音乐暂停与播放
- 界面pause和resume的监听
- visualizer资源释放
- mediaPlayer资源释放
- 滤波, 就是把数据变的平滑一点
- 音频数据归一化
- 音乐播放及监听
- 音频数据采样, 平均抽样
- 随机颜色
代码讲解
1. 初始化一些全局变量, 方便修改
let currentData; let currentDataFft; let mSpectrumCount = 66; let mItemMargin = 8; let mediaPlayer; let kernel = 5; let visualizer;
2. 申请录音权限
ui.emitter.on("activity_result", (requestCode, resultCode, data) => { log("result"); if (resultCode == activity.RESULT_OK) { log(activity.RESULT_OK); if (requestCode == 6) { log("=6"); init(); } else { log("!=6"); } } }); ActivityCompat.requestPermissions(activity, ["android.permission.RECORD_AUDIO"], 6);
3. 检查权限
function checkPermission(permission) { let pm = context.getPackageManager(); return (havePermission = PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, context.getPackageName().toString())); }
4. UI界面
ui.layout( <vertical> <button id="play">play</button> <button id="pause">pause</button> <text id="info" textSize="22sp" textColor="#fbfbfe" bg="#00afff" w="*" gravity="center">牙叔教程</text> <canvas id="board" h="180dp"></canvas> <canvas marginTop="10" id="board2" h="180dp"></canvas> </vertical> );
5. 界面加载完成, 再去绘制音乐, 因为要用到画板的宽高
ui.post(function () { let h = ui.board.getHeight(); initListener(h); drawIt(ui.board, "up"); drawIt(ui.board2, "down"); });
6. 创建音乐数据监听事件
let dataCaptureListener = new Visualizer.OnDataCaptureListener({ onWaveFormDataCapture: function (visualizer, waveform, samplingRate) { //到waveform为波形图数据 let data = converter(waveform); currentData = sampling(data, mSpectrumCount); currentData = WaveFilter(currentData); currentData = WaveFilter(currentData); }, onFftDataCapture: function (visualizer, fft, samplingRate) { //FFT数据,展示不同频率的振幅 let data = converterFft(fft); currentDataFft = samplingFft(data, mSpectrumCount, h); currentDataFft = WaveFilter(currentDataFft); currentDataFft = WaveFilter(currentDataFft); }, });
7. Visualizer基本配置
visualizer = new Visualizer(mediaPlayer.getAudioSessionId()); // let visualizer = new Visualizer(0); //采样的最大值 let captureSize = Visualizer.getCaptureSizeRange()[1]; //采样的频率 let captureRate = (Visualizer.getMaxCaptureRate() * 2) / 3; visualizer.setCaptureSize(captureSize); visualizer.setDataCaptureListener(dataCaptureListener, captureRate, true, true); visualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED); visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS); visualizer.setEnabled(true);
8. 画笔基本配置
let mPaint = new Paint(); mPaint.setColor(mColor); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mPaint.setMaskFilter(new BlurMaskFilter(5, BlurMaskFilter.Blur.SOLID));
9. 定时器修改颜色
let colorList = ["#64b5f6", "#2196f3", "#1565c0"]; let step = mSpectrumCount / colorList.length; setInterval(function () { for (var i = 0; i < 3; i++) { let color = getRandomColor(); colorList[i] = color; } }, 3000);
10. 绘制线段
for (let i = step; i < step * 2; i++) { let x1 = startPoint.x + i * mSpectrumWidth + halfStrokeWidth; let y1 = h; let x2 = startPoint.x + i * mSpectrumWidth + halfStrokeWidth; let y2; if (position === "up") { y2 = h - unitY * currentData[i]; } else { y2 = h - currentDataFft[i]; } canvas.drawLine(x1, y1, x2, y2, mPaint); //绘制直线 }
11. 按键点击事件
ui.pause.click(function () { mediaPlayer.pause(); }); ui.play.click(function () { if (mediaPlayer.isPlaying()) { return true; } else { if (mediaPlayer) { mediaPlayer.start(); } } });
12. 界面不显示就不播放音乐, 回到界面就播放音乐
ui.emitter.on("pause", () => { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); } }); ui.emitter.on("resume", () => { ui.post(function () { mediaPlayer.start(); }, 200); });
13. 释放资源
events.on("exit", function () { visualizer.setEnabled(false); visualizer.release(); mediaPlayer.stop(); mediaPlayer.release(); //播放完成就释放媒体播放器 mediaPlayer = null; print("exit: " + mediaPlayer); });
参考
Android 使用MediaPlayer播放视频切换后台暂停再恢复互前台继续播放的bug修改
Android Visualizer音频可视化——让你的音频跳动起来
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, 安卓文档, autojs文档, 最后才是群里问问
--- 牙叔教程
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途