序文
以前、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、ソース コードにもアクセスできます