Android 如何获取 MediaPlayer 中的当前音量/幅度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2924676/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get the current volume/amplitude in a MediaPlayer?
提问by Scott Ferguson
I'm working on an app that will both record an audio file, and then have the option to play back that file once it's been recorded. The UI has an EQ component that animates relative to the current amplitude of the recording. I've got the animation working via the MediaRecorder.getMaxAmplitude()
method, but can't find any means to do this with MediaPlayer. I know it must be possible since there are music visualization Live Wallpapers by default that perform this functionality but I can't see any way that it's pulling that information when combing through AOSP. Does anybody know how to make this work?
我正在开发一个应用程序,它既可以录制音频文件,也可以选择在录制后播放该文件。UI 有一个 EQ 组件,可以根据录音的当前幅度进行动画处理。我已经通过该MediaRecorder.getMaxAmplitude()
方法使动画工作,但找不到任何方法来使用 MediaPlayer 执行此操作。我知道这一定是可能的,因为默认情况下有音乐可视化动态壁纸可以执行此功能,但我看不到它在通过 AOSP 进行梳理时提取该信息的任何方式。有谁知道如何使这项工作?
采纳答案by Ohiovr
I think you have to use AudioManager. As the API states it can be used for volume control:
我认为您必须使用AudioManager。正如 API 所述,它可用于音量控制:
AudioManager provides access to volume and ringer mode control.
Use Context.getSystemService(Context.AUDIO_SERVICE) to get an instance of this class.
AudioManager 提供对音量和振铃器模式控制的访问。
使用 Context.getSystemService(Context.AUDIO_SERVICE) 获取此类的实例。
Then I think this methodwould be useful.
那么我认为这个方法会很有用。
回答by Deepak Sharma
You can get the current volume of media player with the help of Audiomanager class.The code is as follows:-
您可以借助 Audiomanager 类获取媒体播放器的当前音量。代码如下:-
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int volume_level= am.getStreamVolume(AudioManager.STREAM_MUSIC);
Similarly,if you want to set the default volume of media player.You can do that like as:-
同样,如果您想设置媒体播放器的默认音量。您可以这样做:-
am.setStreamVolume(
AudioManager.STREAM_MUSIC,
volume_level,
0);
That's all..Happy coding :)
就是这样..快乐编码:)
回答by Ohiovr
You are in luck. There is a class called Visualizer which will do what you want I think.
你很幸运。有一个叫做 Visualizer 的类,它会做你想做的我认为。
import android.app.Activity;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
private Visualizer audioOutput = null;
public float intensity = 0; //intensity is a value between 0 and 1. The intensity in this case is the system output volume
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createVisualizer();
}
private void createVisualizer(){
int rate = Visualizer.getMaxCaptureRate();
audioOutput = new Visualizer(0); // get output audio stream
audioOutput.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
intensity = ((float) waveform[0] + 128f) / 256;
Log.d("vis", String.valueOf(intensity));
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
}
},rate , true, false); // waveform not freq data
Log.d("rate", String.valueOf(Visualizer.getMaxCaptureRate()));
audioOutput.setEnabled(true);
}
}
you will need these permissions:
您将需要这些权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>
回答by Dominic Cerisano
You have to implement getLevel() in DataLine. This is as close to the bus as it gets in Java.
您必须在 DataLine 中实现 getLevel()。这与 Java 中的总线一样接近。
This involves calculating a running average of amplitude (waveform) data from the sound stream buffer.
这涉及计算来自声音流缓冲区的幅度(波形)数据的运行平均值。
This causes a lot of bus traffic to access the buffer, so left as abstract method.
这会导致大量总线流量访问缓冲区,因此保留为抽象方法。
Root Mean Square (RMS) is one approach:
均方根 (RMS) 是一种方法:
https://community.oracle.com/message/5391003
https://community.oracle.com/message/5391003
DSP with FFT (eg. Visualizer class) gives a complete frequency spectrum, but consumes much more CPU resources.
带有 FFT 的 DSP(例如 Visualizer 类)提供完整的频谱,但消耗更多的 CPU 资源。
Don't slam on full DSP if all you need is RMS (eg. simple beat detection). Limit the quality of your samples to improve performance.
如果您只需要 RMS(例如简单的节拍检测),请不要猛烈使用全 DSP。限制样品的质量以提高性能。
回答by HenryAdamsJr
I've been looking for a way to do something similarfor a while. I really want to be able to see the volume/amplitude of anything being played over the media stream, but I'll settle for being able to do it for something I'm currently playing.
一段时间以来,我一直在寻找一种方法来做类似的事情。我真的希望能够看到通过媒体流播放的任何东西的音量/幅度,但我会满足于能够为我目前正在播放的东西做到这一点。
So far, the best solution I've found is implemented in RingDroid. I haven't looked into the code too deeply, but it looks like the way that RingDroid creates its soundmap is by actually analyzing the sound file bit by bit.
到目前为止,我发现的最佳解决方案是在RingDroid 中实现的。我没有深入研究代码,但看起来 RingDroid 创建声音图的方式是通过实际一点一点地分析声音文件。
I've considered using a similar approach and then displaying a visualizer that runs separate from the audio file, but runs at a synchronized pace. However, this seems like too much work for something that should be way simpler.
我考虑过使用类似的方法,然后显示一个与音频文件分开运行但以同步速度运行的可视化工具。然而,这对于应该更简单的事情来说似乎太多了。
回答by Hadi Note
As follow:
如下:
audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolumeLevel = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int volumePercent = (int) (((float) volumeLevel / maxVolumeLevel) * 100);
回答by Vivek Thummar
I got this solution:
我得到了这个解决方案:
final int volume_level = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = (float) volume_level / maxVolume;