Как получить текущий объем/амплитуду в MediaPlayer?

Я работаю над приложением, которое будет записывать аудиофайл, а затем иметь возможность воспроизводить этот файл после его записи. Пользовательский интерфейс имеет компонент EQ, который оживляет относительно текущей амплитуды записи. У меня есть анимация, работающая с помощью метода MediaRecorder.getMaxAmplitude(), но не могу найти способ сделать это с помощью MediaPlayer. Я знаю, что это возможно, так как есть музыкальная визуализация Live Wallpapers по умолчанию, которая выполняет эту функцию, но я не вижу никакого способа, которым она извлекает эту информацию при расчесывании через AOSP. Кто-нибудь знает, как сделать эту работу?

Ответы

Ответ 1

Думаю, вам нужно использовать AudioManager. Поскольку состояния API могут использоваться для управления громкостью:

AudioManager обеспечивает доступ к тому и управление режимом звонка.

Использование Context.getSystemService(Context.AUDIO_SERVICE) для получения экземпляра этого класса.

Тогда я думаю, этот метод был бы полезен.

Ответ 2

Вы можете получить текущий объем медиаплеера с помощью класса Audiomanager. Код выглядит следующим образом: -

AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int volume_level= am.getStreamVolume(AudioManager.STREAM_MUSIC);

Аналогично, если вы хотите установить уровень по умолчанию для медиаплеера. Вы можете сделать это как: -

am.setStreamVolume(
            AudioManager.STREAM_MUSIC,
            volume_level,
            0);

Что все..Хорошая кодировка:)

Ответ 3

Вам повезло. Существует класс под названием 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);
}


}

вам понадобятся эти разрешения:

<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>

Ответ 4

Я искал способ сделать нечто подобное некоторое время. Я действительно хочу видеть громкость/амплитуду чего-либо, воспроизводимого через медиа-поток, но я соглашусь на то, что смогу сделать это за то, что я сейчас играю.

Пока лучшее решение, которое я нашел, реализовано в RingDroid. Я не слишком глубоко заглядывал в код, но похоже, что RingDroid создает свою звуковую карту, фактически анализируя звуковой файл по частям.

Я рассмотрел использование подобного подхода, а затем отобразил визуализатор, который работает отдельно от аудиофайла, но работает в синхронизированном темпе. Однако это кажется слишком большой работой для чего-то, что должно быть проще.

Ответ 5

Вы должны реализовать getLevel() в DataLine. Это так близко к шине, как это происходит в Java.

Это включает в себя расчет скользящего среднего значения амплитуды (формы сигнала) из буфера звукового потока.

Это приводит к большому трафику шины для доступа к буферу, поэтому он остается абстрактным методом.

Среднеквадратичное значение (RMS) является одним из подходов:

https://community.oracle.com/message/5391003

DSP с БПФ (например, класс Visualizer) дает полный частотный спектр, но потребляет гораздо больше ресурсов процессора.

Не нажимайте на полный DSP, если все, что вам нужно, это RMS (например, простое обнаружение ударов). Ограничьте качество ваших образцов для улучшения производительности.

Ответ 6

Я получил это решение:

final int volume_level = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = (float) volume_level / maxVolume;