Android のオーディオとビデオの開発 (3) - AudioTrack は 2 つの方法で pcm オーディオを再生します

序文

以前、pcm オーディオを録音する AudioRecord を学習しましたが、対応するのは pcm オーディオを再生する AudioTrack (MediaPlayer と SoundPool には別のアプリケーション シナリオがあります) で、2 つのデータ読み込みモード (MODE_STATIC、MODE_STREAM) があります。

モデル

  • MODE_STATIC : このモードでは、すべてのデータが一度に固定バッファーに入れられてから AudioTrack に書き込まれます。後で書き込みを続ける必要はありません。このモードはメモリの占有量が少なく、携帯電話の着信音やシステム プロンプトなどの短い音声に適しています。

  • MODE_STREAM : このモードはオーディオ データを AudioTrack に書き込み続けます。データ ストリームが Java レイヤーからネイティブ レイヤーに送信されるまで、書き込みアクションはブロックされます。これは、大きなファイルや再生時間が長いファイルに適しています。

STATIC モードのプロセス

1. 別のスレッドを開始して、オーディオ ファイルを固定バッファに書き込みます。

2. 書き込みが完了したら、AudioTrack を初期化し (パラメーターについては前のセクションで詳しく説明します)、バッファーを受け取り、再生します。

    public void initStatic() {
    
    
        if (staticThread != null) {
    
    
            staticThread.interrupt();
        }
        staticThread = new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                FileInputStream fileInputStream = null;
                try {
    
    
                    File file = new File(filePath);
                    fileInputStream = new FileInputStream(file);
                    long size = fileInputStream.getChannel().size();

                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(audiodata.length);
                    int byteValue = 0;
                    long startTime = System.currentTimeMillis();
                    while ((byteValue = fileInputStream.read()) != -1) {
    
    
                        byteArrayOutputStream.write(byteValue);
                    }
                    LogUtils.i("初始化完成" + (System.currentTimeMillis() - startTime));
                    audiodata = byteArrayOutputStream.toByteArray();

                    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO,
                            AudioFormat.ENCODING_PCM_16BIT, audiodata.length, AudioTrack.MODE_STATIC);
                    audioTrack.write(audiodata, 0, audiodata.length);
                    audioTrack.play();
                    LogUtils.i("Static播放");

                } catch (Exception e) {
    
    
                    e.printStackTrace();
                    LogUtils.e(e);
                } finally {
    
    
                    if (fileInputStream != null) {
    
    
                        try {
    
    
                            fileInputStream.close();
                        } catch (IOException e) {
    
    
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        staticThread.start();
    }

STREAM モードのプロセス

1. AudioTrack を初期化します。

2. 別のスレッドを開始し、オーディオ ストリーム ファイルの書き込み中に再生します。

3. 再生が終了したら、ストリームを閉じます。

    public void startStream() {
    
    
        if (streamThread != null) {
    
    
            streamThread.interrupt();
        }
        if (audioTrack != null) {
    
    
            audioTrack = null;
        }
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT, 1600, AudioTrack.MODE_STREAM);
        streamThread = new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                FileInputStream fileInputStream = null;
                File file = new File(filePath);
                try {
    
    
                    audioTrack.play();
                    fileInputStream = new FileInputStream(file);
                    int byteValue = 0;
                    while ((byteValue = fileInputStream.read(audiodata)) != -1) {
    
    
                        audioTrack.write(audiodata, 0, byteValue);
                    }
                } catch (Exception e) {
    
    
                    e.printStackTrace();
                    LogUtils.e(e);
                } finally {
    
    
                    if (audioTrack != null) {
    
    
                        audioTrack.stop();
                        audioTrack = null;
                    }
                    if (fileInputStream != null) {
    
    
                        try {
    
    
                            fileInputStream.close();
                        } catch (IOException e) {
    
    
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        streamThread.start();
    }

エピローグ

実際、MediaPlayer の最下層も AudioTrack を使用しますが、より包括的にパッケージ化されており、MP3、AAC、WAV、OGG などの複数のサウンド形式をサポートできますが、pcm ファイルを直接再生することはできません。各フレームのオーディオ データを制御および再生する AudioTrack を最下層の近くで使用します。

このブログの参考文献:

灰色のフローティング ブログ ガーデン

ソース コードが必要な友人は、私の gitub、ソース コードにもアクセスできます

おすすめ

転載: blog.csdn.net/m0_57372054/article/details/127200636