音视频

音视频开发进阶指南(第四章)-AudioTrack播放PCM

2019-11-20  本文已影响0人  DD_Dog

书中示例源码地址
ffmpeg编译参考链接

使用AudioTrack播放PCM

为什么只播放PCM不播放Mp3呢?因为AudioTrack是基础API,没有解码功能,而MediaPlayer是有解码功能的。所以要播放Mp3,还需要自行添加解码功能,把Mp3解码为PCM再播放。
只要做好两件事情:

  1. AudioTrack的初始化参数的含义
  2. AudioTrack的播放流程:play->write->stop

1. 初始化AudioTrack

 //获取最小缓冲区大小
 int minBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE,    //采样率
         AudioFormat.CHANNEL_OUT_STEREO, //双声道
         AudioFormat.ENCODING_PCM_16BIT  //采样格式
 );
 //初始化AudioTrack对象
 AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,   //媒体类型
         SAMPLE_RATE,  //采样率
         AudioFormat.CHANNEL_IN_STEREO, //双声道
         AudioFormat.ENCODING_PCM_16BIT, //采样格式
         minBufferSize,  //缓冲区大小
         AudioTrack.MODE_STREAM  //流式加载
 );

参数详解:

public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_
public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;
public static final int STREAM_RING = AudioSystem.STREAM_RING;
public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;
public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
  1. MODE_STREAM 按照一定的时间间隔不间断地定入音频数据,理论上它可以应用于任何音频播放的场景
  2. MODE_STATIC 需要一次性将所有的数据都写入播放缓冲区中,简单高效,通常用于播放铃声、系统提醒的音频片段。

2. 启动播放

//先启动播放
audioTrack.play();

3. write音频数据

//分配缓冲区
byte[] buffer = new byte[minBufferSize * 3];
is = getAssets().open(pcmFilePath);
dis = new DataInputStream(is);
int readCount = 0;
while (dis.available() > 0) {
    //读取PCM
    readCount = dis.read(buffer);
    Log.d(MainActivity.class.getSimpleName(), "readCount=" + readCount);
    if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {
        continue;
    }
    if (readCount != 0 && readCount != -1) {
        //写入AudioTrack
        audioTrack.write(buffer, 0, readCount);
    }
}
...
audioTrack.stop();

完整的代码Demo地址

上一篇 下一篇

猜你喜欢

热点阅读