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

书中示例源码地址
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  //流式加载
 );

参数详解:

  • 参数一:streamType
    Android手机上提供了多重音频管理策略(例如按一下手机侧面音量键,会出现多个音量管理,这其实就是不同音频策略的音频控制展示),当系统有多个进程需要播放音频的时候,管理策略会决定最终的呈现效果,该参数的可选值将以常量的形式定义在类AudioManager中,主要包括以下内容:
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;
  • 参数二:sampleRateInHz
    采样率,即播放的音频每秒钟会有多少次采样,可选用的采样频率列表为:8000、16000、22050、24000、32000、44100、48000等,要根据播放的PCM的采样率来决定初始化AudioTrack时的具体值,否则可能导致声音变快或者变慢
  • 参数三:channelConfig
    声道数(通道数)配置,可选值以常量形式配置在类AudioFormat中,常用的是CHANNEL_IN_MONO(输入单声道),CHANNEL_IN_STEREO(输入双声道)。(因为现在大多数手机的麦克风都是伪立体声采集,为了性能考虑,建议使用单声道进行音频采集,而转变为立体声的过程可以在声音的特效处理阶段来完成)。
  • 参数四:audioFormat
    该参数是用来配置数据位宽,表示了采样精度,可选值以常量的形式定义在类AudioFormat中,分别为ENCODING_PCM_16BIT和ENCODING_PCM_8BIT,注意,前者是可以兼容安卓所有手机的。
  • 参数五:bufferSizeInBytes
    它配置的是AudioTrack内部缓冲区的大小,AudioTrack类提供了一个静态方法getMinBufferSize来帮忙开发者确定缓冲区的大小,在实际开发中,强烈建议使用该方法,而不是自己手动计算。
  • 参数六:mode
    AudioTrack提供了两种播放模式,可选的值以常量的形式定义在类AudioTrack中,分别为:
  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地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352