SoundPool を使用して効果音を再生する (Duang~)


このセクションの概要:

第 9 章では、Android でのマルチメディア開発について説明します。マルチメディア開発というよりも、マルチメディア関連の API について説明します。 MediaPlayer を呼び出して音楽ファイルを見つけて、 次に、 play メソッドを呼び出して再生します... もちろん、実際のマルチメディア開発は、オーディオとビデオのエンコードとデコードという別の分野です。 これらの API を呼び出す方法さえ知っていれば、今は見上げて待つことしかできません。ところで、Android マルチメディアの普及はまだ必要です フレームワークに関する常識:

Android では、デフォルトのマルチメディア フレームワークは

OpenCore

です。 OpenCore の利点は、両方の点を考慮していることです。 クロスプラットフォームで移植可能であり、多くの関係者によって検証されているため、比較的安定していますが、大規模で複雑すぎるという欠点があります。 維持するには非常に時間がかかります。 Android 2.0 から、Google はもう少し単純なアーキテクチャを持つ Stagefright を導入しました。もちろん、OpenCore を完全に放棄したわけではなく、主に OpenCore を変更しただけの OMX レイヤーを作成しました。 omx-component 部分が参照されます。 OpenCOREは徐々に置き換えられる傾向にありましたが、今年8月に Stagefright の脆弱性により、特別に細工された MMS メッセージを悪用してリモートでコードが実行される可能性があります。 この脆弱性は Android 2.2 以降のバージョンに影響し、Android 4.1 以降のバージョンへの影響は比較的弱いです。

何のことを言っているのか分かりません(JB が何のことを言っているのかさえ分かりません)、うーん、わかった、科学は終わった…これらのことを知るのは良いことです! 1.jpg ちなみに、このマルチメディア フレームワークは、Android アーキテクチャの第 3 層 (

ライブラリ

) の Media Framework にあります。 さらに、Android マルチメディア フレームワークでサポートされているオーディオおよびビデオ データの種類を知りたい場合は、公式ドキュメントを参照してください:

サポートされているメディア形式

ここをクリックして、

メディアとカメラ

をクリックしてから、次のドキュメントを見てください: 2.png

さて、冒頭でくだらない話が多すぎて、今日の主役が SoundPool であることを忘れてしまいましたが、タイトルの通り、SoundPool は一般的に使用されます。 ゲームでよく使われるスタント効果音「Duang~」など、密度が高く、短く、持続時間の短い効果音を追加して再生することもできます。 このアプリは、たとえば、Kugou Music を再生すると「Hello, Kugou」という効果音を追加します。実際、このアイデアは非常に優れています。 プレーヤーの現在の音量を間接的にユーザーに知らせます。そうしないと、ユーザーが曲を再生するとすぐに小さなリンゴが突然現れ、近くに引き寄せられます。 おばちゃんが踊ったらまずいですよね? 音楽プレーヤーに追加するだけでなく、プッシュ通知を受信するなど、通常のAPPに追加することもできます。 メッセージまたは新しいチャットメッセージを入力し、新しいバージョンのスーパーカリキュラムなどのプロンプトサウンドを再生し、これを追加し、プッシュ通知を受け取ります メッセージでは短い「テーブル」サウンドが再生されます。 SoundPool オブジェクトは、APK からインポートできるリソースとして見ることができます。 または、ファイル システムからファイルのサンプル コレクションをロードします。 MediaPlayer サービスを利用してオーディオを生の 16 ビットにデコードします。 PCMストリーム。この機能により、アプリケーションは、オーディオの再生中に解凍によって生じるCPU負荷や遅延に耐えることなく、ストリーム圧縮を実行できます。 SoundPool は、サウンド プール の概念を使用して、複数の プレーヤー ストリーム を管理します。ストリームの最大数を超えた場合、 SoundPool は、優先度に基づいて以前に再生されたストリームを自動的に停止します。また、SoundPool は音質の設定もサポートしています。 音量、再生率などのパラメータ。さて、さっそくこのセクションを始めましょう。 公式 API ドキュメント: SoundPool


1. 関連メソッドの紹介:


1) 構築メソッド:

SoundPool(int maxStreams, int streamType, int srcQuality) パラメータは次の順序です:

  • ① SoundPool オブジェクトでサポートされるサウンドの数と、同時に存在できるストリームの最大数を指定します。
  • ②サウンドの種類を指定します。ストリームの種類はSTREAM_VOICE_CALLSTREAM_SYSTEMSTREAM_RINGSTREAM_MUSICSTREAM_ALARMの4種類に分かれます。 AudioManager で定義されます。
  • ③音質(サンプリングレート変換品質)を指定します。通常は直接0に設定します!

上記の構築方法は以前のバージョンでも使用できますが、この構築方法は API 21 (Android 5.0) 以降では廃止されます。 SoundPool.Builder を使用する場合、SoundPool をインスタンス化したい場合は、次を呼び出すだけです:

SoundPool.Builder spb = new SoundPool.Builder();
spb.setMaxStreams(10);
spb.setAudioAttributes(null);    //转换音频格式
SoundPool sp = spb.build();      //创建SoundPool对象

上記のコードを使用したい場合は、TargetSDK バージョンを 21 以上に設定する必要があります。 minSDK バージョンが 21 未満の場合 次のリマインダーが表示されます:

3.png


2) 一般的な方法の紹介:


サウンドリソースのロード:

  • load(Context context、int resId、int priority)
  • load(文字列パス、int priority)
  • load(FileDescriptor fd、long offset、long length、int priority)
  • load (AssetFileDescriptor afd、int 優先度) 上記のメソッドはすべてサウンド ID を返し、後でこの ID を使用して指定されたサウンドを再生できます

パラメータの紹介:

  • context: context
  • resId: resource id
  • priority: 役に立たないパラメータ、将来との互換性を維持するために、1に設定することをお勧めします
  • path: ファイルパス
  • FileDescriptor: ストリームのようですが、これはわかりません
  • AssetFileDescriptor: アセットから特定のリソースファイルを読み取りますディレクトリ、使用法: AssetFileDescriptor descriptor =assetManager.openFd("biaobiao.mp3");

再生制御:

play(int soundID, float leftVolume, float rightVolume, int priority, intループ、浮動小数点レート)

パラメータは次のとおりです:

  • soundID: Load() によって返されるサウンド ID 番号
  • leftVolume: 左チャンネルの音量設定
  • rightVolume: 右チャンネルの音量設定
  • priority: の優先順位を指定します値が大きいほど音を再生します。 優先度が高いほど優先度が高くなります。
  • loop: ループするかどうかを指定します: -1 は無限ループを意味し、0 はループなしを意味し、その他の値は繰り返し再生される回数を示します
  • rate: 再生レートを指定します: 再生レート 1.0 は、サウンドは元の周波数に従いますが、再生レート 2.0 の場合、サウンドは元の周波数に従うことができます。 元の周波数の 2 倍で再生します。再生レートが 0.5 の場合、再生レートは元の周波数の半分になります。再生レートの範囲は 0.5 ~ 2.0 です。

リソースの解放:

は、release()メソッドを呼び出して、すべてのSoundPoolオブジェクトによって占有されているメモリとリソースを解放できます。もちろん、サウンドに基づいて解放することもできます。 ID公開します!


3. 使用コード例:

レンダリングを実行します:

4.png

ボタンをクリックすると、「Duang」という 2 つのロード方法が表示されます。つまり、raw と Assets です。

キーコード:

MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_play1;
    private Button btn_play2;
    private Button btn_play3;
    private Button btn_play4;
    private Button btn_play5;
    private Button btn_release;
    private AssetManager aManager;
    private SoundPool mSoundPool = null;
    private HashMap soundID = new HashMap();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        aManager = getAssets();
        try {
            initSP();
        } catch (Exception e) {
            e.printStackTrace();
        }
        bindViews();
    }

    private void bindViews() {
        btn_play1 = (Button) findViewById(R.id.btn_play1);
        btn_play2 = (Button) findViewById(R.id.btn_play2);
        btn_play3 = (Button) findViewById(R.id.btn_play3);
        btn_play4 = (Button) findViewById(R.id.btn_play4);
        btn_play5 = (Button) findViewById(R.id.btn_play5);
        btn_release = (Button) findViewById(R.id.btn_release);

        btn_play1.setOnClickListener(this);
        btn_play2.setOnClickListener(this);
        btn_play3.setOnClickListener(this);
        btn_play4.setOnClickListener(this);
        btn_play5.setOnClickListener(this);
        btn_release.setOnClickListener(this);

    }

    private void initSP() throws Exception{
        //设置最多可容纳5个音频流,音频的品质为5
        mSoundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 5);
        soundID.put(1, mSoundPool.load(this, R.raw.duang, 1));
        soundID.put(2 , mSoundPool.load(getAssets().openFd("biaobiao.mp3") , 1));  //需要捕获IO异常
        soundID.put(3, mSoundPool.load(this, R.raw.duang, 1));
        soundID.put(4, mSoundPool.load(this, R.raw.duang, 1));
        soundID.put(5, mSoundPool.load(this, R.raw.duang, 1));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_play1:
                mSoundPool.play(soundID.get(1), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play2:
                mSoundPool.play(soundID.get(2), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play3:
                mSoundPool.play(soundID.get(3), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play4:
                mSoundPool.play(soundID.get(4), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_play5:
                mSoundPool.play(soundID.get(5), 1, 1, 0, 0, 1);
                break;
            case R.id.btn_release:
                mSoundPool.release();   //回收SoundPool资源
                break;
        }
    }
}

コードは非常に単純で、最後のボタンをクリックするとサウンドプールが解放され、その後他のボタンが解放されます。 ドゥアンにはなりませんよ〜


4.OnLoadCompleteListenerはサウンドファイルが完全にロードされているかどうかを監視します

さて、これは書き終えてから、別の記事を書いているときにふと思い出したものです。使い方もとても簡単です。 OnLoadCompleteListener を上記のコードに追加し、onLoadComplete() メソッドをオーバーライドします。 そして最後にこれを SoundPool オブジェクトに設定します。

mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
    @Override
    public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
        Toast.makeText(MainActivity.this,"加特技准备完毕~",Toast.LENGTH_SHORT).show();
    }
});

5. サンプル コードのダウンロード:

SoundPoolDemo.zip


このセクションの概要:

このセクションでは、Andorid マルチメディアに関する一般常識を説明し、その方法を説明します。自分でアプリに効果音を追加し、 それは単純なSoundPoolを通じて実現できます。これをアプリケーションに追加してアプリケーションを作成してください~

5.gif

、デモと一緒に使用する方が良いです~