Mediaplayerで現在の体積/振幅を取得するにはどうすればよいですか?
-
05-10-2019 - |
質問
オーディオファイルを録音し、そのファイルが記録されたら再生するオプションがあるアプリに取り組んでいます。 UIには、記録の現在の振幅と比較してアニメーション化するEQコンポーネントがあります。アニメーションが動作しています MediaRecorder.getMaxAmplitude()
方法ですが、Mediaplayerでこれを行う手段を見つけることができません。デフォルトではこの機能を実行する音楽視覚化ライブの壁紙があるので、可能である必要があることは知っていますが、AOSPを介したときにその情報を引き出す方法はわかりません。誰かがこの仕事をする方法を知っていますか?
解決
私はあなたが使わなければならないと思います オーディオマネージャー. 。 APIが述べているように、ボリュームコントロールに使用できます。
AudiOMANAGERは、ボリュームとリンガーモードのコントロールへのアクセスを提供します。
Context.GetSystemService(Context.Audio_Service)を使用して、このクラスのインスタンスを取得します。
それから私は思う この方法 便利です。
他のヒント
AudiAnagerクラスの助けを借りて、メディアプレーヤーの現在のボリュームを取得できます。コードは次のとおりです。
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int volume_level= am.getStreamVolume(AudioManager.STREAM_MUSIC);
同様に、メディアプレーヤーのデフォルトボリュームを設定する場合は、次のようにすることができます。
am.setStreamVolume(
AudioManager.STREAM_MUSIC,
volume_level,
0);
それだけです..ハッピーコーディング:)
あなたは幸運です。 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>
DatalineにGetLevel()を実装する必要があります。これは、Javaに入るのと同じくらいバスに近いです。
これには、サウンドストリームバッファーからの振幅の平均(波形)データを計算することが含まれます。
これにより、バッファにアクセスするために多くのバストラフィックが発生するため、抽象的な方法として残されます。
ルート平均平方(RMS)は1つのアプローチです。
https://community.oracle.com/message/5391003
FFTを備えたDSP(Visualizerクラスなど)は完全な周波数スペクトルを提供しますが、より多くのCPUリソースを消費します。
必要なのはRMSだけであれば、完全なDSPをバタンとしないでください(たとえば、単純なビート検出)。サンプルの品質を制限して、パフォーマンスを向上させます。
私はやる方法を探していました 似たような しばらくの間。メディアストリームでプレイされているもののボリューム/振幅を見たいと思っていますが、現在プレイしていることのためにできることに落ち着きます。
これまでのところ、私が見つけた最良の解決策はで実装されています リングドロイド. 。私はコードをあまり深く調べていませんが、RingDroidがサウンドマップを作成する方法は、実際にサウンドファイルを少しずつ分析することであるように見えます。
同様のアプローチを使用してから、オーディオファイルとは別に実行されるが、同期されたペースで実行されるVisualizerを表示することを検討しました。ただし、これは、はるかにシンプルなものにはあまりにも多くの仕事のようです。
私はこの解決策を手に入れました:
final int volume_level = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = (float) volume_level / maxVolume;