项目需要获取播放视频的实时音量值,最简捷的方法是监听音频输出端,取得音频输出流,再进行转换。
调查时,首先找到这篇博客:
http://blog.csdn.net/jinzhuojun/article/details/33748031
即利用API 19中新加的MediaRecorder.AudioSource.REMOTE_SUBMIX参数,实时录制输出流数据。
因为使用REMOTE_SUBMIX参数需要系统级权限
获取系统权限的调查
java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk
即使更改应用为系统权限,仍不可用:
原因是使用的是目标系统的签名文件,生成的程序只能在原生Android系统或者是自己所编译的系统中才可以使用,其他定制系统无法安装,这样也是为了保护系统的安全。
参考:
http://gqdy365.iteye.com/blog/2111949
http://www.eoeandroid.com/thread-329398-1-1.html?_dsign=039d0c16
此方案下获取系统音频输出的尝试就此宣告破产!
正当我准备放弃的时候,事情又出现了转机:Google 时发现有人建议尝试android.media.audiofx.Virtualizer
Record Android Audio Output
android get device overall audio output in pcm
初步查看好像有利用的可能,就仔细调查了一下,没想到问题就此解决,真是车到山前必有路,船到桥头自然直。
Virtualizer是Android 2.3 给出的API,主要功能是实现音频的可视化,用于音乐播放时绘制柱状、块状或曲线的波形图
实例化:Visualizer mVisualizer = new Visualizer(int audioSession)
这种方法获取系统输出音频的关键是参数audioSession,API中给的解释如下:
@param audioSession system wide unique audio session identifier.
If audioSession is not 0, the visualizer will be attached to the MediaPlayer or AudioTrack in the same audio session.
Otherwise, the Visualizer will apply to the output mix.
主要流程是:
1. 初始化Visualizer控件,Visualizer mVisualizer = new Visualizer(0);
2. 实现数据截获监听,mVisualizer.setDataCaptureListener(OnDataCaptureListener listener, int rate, boolean waveform, boolean fft);
这里需要实现OnDataCaptureListener的两个接口,其中onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate)
中的waveform即为所截获的音频输出流,对其执行想要的操作即可。
关键代码:
mVisualizer = new Visualizer(0); // get output audio stream mVisualizer.setEnabled(false); mVisualizer.setCaptureSize(1024); mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() { @Override public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) { // 用waveform波形数据更新mVisualizerView组件 mVisualizerView.updateVisualizer(waveform);
int max = 0;
for (int i = 0; i < waveform.length - 1; i += 32) {
int top = (byte) (waveform[i + 1] + 128 + 1) * 2;
if (top > max){
max = top;
}
}
Log.i(TAG, "MAX1: " + max);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
}
}, Visualizer.getMaxCaptureRate(), true, false); // waveform not freq data
说明:这个项目并不需要完整的输出音频,而只是需要输出音频的实时音量,因此后续处理并不复杂。
如果想要录制完整的输出音频,请参考上面的两个链接,可以实现,但音频质量非常非常差,根本不可用。