AudioTrack使用
AudioTrack用来播放音频的原始数据PCM。MediaPlayer把音频解码后的数据交给AudioTrack来播放。
我们看下AudioTrack的构造函数
public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,int mode, int sessionId)throws IllegalArgumentException {this(attributes, format, bufferSizeInBytes, mode, sessionId, false /*offload*/,ENCAPSULATION_MODE_NONE, null /* tunerConfiguration */);}
AudioAttributes attributes
AudioAttributes audioAttributes = (new AudioAttributes.Builder()).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();
设置当前要播放什么内容的数据
我们看源码包括下面一下信息
public final class AudioAttributes implements Parcelable {private final static String TAG = "AudioAttributes";/*** Content type value to use when the content type is unknown, or other than the ones defined.*/public final static int CONTENT_TYPE_UNKNOWN = 0;/*** Content type value to use when the content type is speech.*/public final static int CONTENT_TYPE_SPEECH = 1;/*** Content type value to use when the content type is music.*/public final static int CONTENT_TYPE_MUSIC = 2;/*** Content type value to use when the content type is a soundtrack, typically accompanying* a movie or TV program.*/public final static int CONTENT_TYPE_MOVIE = 3;/*** Content type value to use when the content type is a sound used to accompany a user* action, such as a beep or sound effect expressing a key click, or event, such as the* type of a sound for a bonus being received in a game. These sounds are mostly synthesized* or short Foley sounds.*/public final static int CONTENT_TYPE_SONIFICATION = 4;
包括了 演讲 电影 音乐等类型。我们这里选择
CONTENT_TYPE_MUSIC
AudioFormat format
AudioFormat.Builder builder = new AudioFormat.Builder();builder.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO).setEncoding(AudioFormat.ENCODING_PCM_16BIT).setSampleRate(44100);AudioFormat audioFormat = builder.build();
设置声道掩码,比如采集音视频我们设置了AudioFormat.CHANNEL_IN_STEREO,那么播放的时候要设置成AudioFormat.CHANNEL_OUT_STEREO
设置编码格式AudioFormat.ENCODING_PCM_16BIT 每个采样大小是2个字节
设置采样率 44100
builder还提供了setChannelIndexMask方法,setChannelIndexMask和setChannelMask是互斥的。
setChannelIndexMask
Added in API level 23
AudioFormat.Builder setChannelIndexMask (int channelIndexMask)
设置频道索引掩码。 通道索引掩码指定帧中的音频采样与编号的端点通道的关联。 信道索引掩码中的第i位对应于第i个端点信道。 例如,具有四个通道的端点被表示为索引掩码位0至3.这个位置掩码解释的这个setChannelMask(int) 。AudioTrack和AudioRecord支持通道索引掩码。 如果指定了通道索引掩码,则使用该掩码,否则使用由setChannelMask指定的通道位置掩码。 对于AudioTrack和AudioRecord ,如果指定了通道索引掩码,则不需要通道位置掩码。
int bufferSizeInBytes
* See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size* for an AudioTrack instance in streaming mode.
注释中写道对于流模式AudioTrack getMinBufferSize
int mode
@param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}.
MODE_STATIC 一次把数据传进来
MODE_STREAM 传很多次数据
int sessionId 会话id
AudioManager.AUDIO_SESSION_ID_GENERATE
AudioManager.generateAudioSessionId()
开始播放
Runnable recordRunnable = new Runnable() {@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overridepublic void run() {try {//设置线程的优先级android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);byte[] tempBuffer = new byte[buffersize];int readCount = 0;while (inputStream.available() > 0) {readCount= inputStream.read(tempBuffer);if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {continue;}if (readCount != 0 && readCount != -1) {//一边播放一边写入语音数据//判断AudioTrack未初始化,停止播放的时候释放了,状态就为STATE_UNINITIALIZEDif(mAudioTrack.getState() == mAudioTrack.STATE_UNINITIALIZED){init();}mAudioTrack.play();mAudioTrack.write(tempBuffer, 0, readCount);}}stopPlay();//播放完就停止播放} catch (Exception e) {e.printStackTrace();}}};
停止播放
public void stopPlay() {try {if (mAudioTrack != null) {if (mAudioTrack.getState() == AudioRecord.STATE_INITIALIZED) {//初始化成功mAudioTrack.stop();//停止播放}if (mAudioTrack != null) {mAudioTrack.release();//释放audioTrack资源}}if (inputStream != null) {inputStream.close();//关闭数据输入流}} catch (Exception e) {e.printStackTrace();}}
完整代码
package com.yuanxuzhen.androidmedia.audio;import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;import androidx.annotation.RequiresApi;import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class AudioTrackManager {private static volatile AudioTrackManager instance;private AudioTrack mAudioTrack;private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;private int buffersize;private ExecutorService executorService;private DataInputStream inputStream;private AudioTrackManager() {init();}public static AudioTrackManager getInstance() {if (instance == null) {synchronized (AudioTrackManager.class) {if (instance == null) {instance = new AudioTrackManager();}}}return instance;}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)private void init() {executorService = Executors.newCachedThreadPool();AudioFormat.Builder builder = new AudioFormat.Builder();builder.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO).setEncoding(AudioFormat.ENCODING_PCM_16BIT).setSampleRate(44100);AudioFormat audioFormat = builder.build();buffersize = AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT);Log.e("yuanAudioTrack", "init buffersize=" + buffersize);AudioAttributes audioAttributes = (new AudioAttributes.Builder()).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();mAudioTrack = new AudioTrack(audioAttributes,audioFormat,buffersize,AudioTrack.MODE_STREAM,AudioManager.AUDIO_SESSION_ID_GENERATE);}/*** 播放线程*/Runnable recordRunnable = new Runnable() {@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overridepublic void run() {try {//设置线程的优先级android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);byte[] tempBuffer = new byte[buffersize];int readCount = 0;while (inputStream.available() > 0) {readCount= inputStream.read(tempBuffer);if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {continue;}if (readCount != 0 && readCount != -1) {//一边播放一边写入语音数据//判断AudioTrack未初始化,停止播放的时候释放了,状态就为STATE_UNINITIALIZEDif(mAudioTrack.getState() == mAudioTrack.STATE_UNINITIALIZED){init();}mAudioTrack.play();mAudioTrack.write(tempBuffer, 0, readCount);}}stopPlay();//播放完就停止播放} catch (Exception e) {e.printStackTrace();}}};private void setPath(String path) throws Exception {File file = new File(path);inputStream = new DataInputStream(new FileInputStream(file));}public void stopPlay() {try {if (mAudioTrack != null) {if (mAudioTrack.getState() == AudioRecord.STATE_INITIALIZED) {//初始化成功mAudioTrack.stop();//停止播放}if (mAudioTrack != null) {mAudioTrack.release();//释放audioTrack资源}}if (inputStream != null) {inputStream.close();//关闭数据输入流}} catch (Exception e) {e.printStackTrace();}}public void startPlay(String path) {try {setPath(path);executorService.execute(recordRunnable);} catch (Exception e) {e.printStackTrace();}}}
gitee地址
https://gitee.com/creat151/android-media.git
AudioTrack使用相关推荐
- android audiotrack使用问题:listener不回调的原因
部分人使用audiotrack,有可能会发现audiotrack的回调方法不回调,其实很多情况下是这样子的: 一般的音频数据源会起一个线程获取,一般新起的线程都没有looper,而audiotrack ...
- android audiotrack权限,Android中AudioRecord和AudioTrack的使用注意
AudioRecord需要至少 这项录音权限.有时候在AndroidManifest.xml中加进去后,有些手机系统仍然没有授予该权限.需要到手机的设置中的权限管理,把这项权限打开.没权限就会闪退.如 ...
- Android 音视频深入 十一 FFmpeg和AudioTrack播放声音(附源码下载)
项目地址,求star https://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpeg%E6%92%AD%E6%94%BE% ...
- android音频系统之AudioTrack的使用
今天,简单讲讲 AudioTrack的使用. 1.Android AudioTrack简介 在android中播放声音可以用MediaPlayer和AudioTrack两种方案的,但是两种方案是 ...
- WebRTC 的 AudioSource/AudioTrack
按照 WebRTC 的设计,AudioSource 是一个音频源,它可以向外提供 PCM 音频帧数据,比如麦克风录制可以提供 PCM 音频帧数据,它应该是一个 AudioSource.然而在 WebR ...
- ktm390蓝牙连接安卓_蓝牙音乐AudioTrack Session ID的获取
当今这个音视频无处不在的时代,音频跟踪会话ID(AudioTrack Session ID)是个很重要的参数,可以用来实现音频相关的一些特效.接下来的内容我们就探究如何在安卓蓝牙系统中获取该id. 熟 ...
- Android之 AudioTrack学习
AudioTrack主要是用来播放声音的,AudioTrack贯穿了JAVA层,JNI层和Native层. AudioTrack JAVA层: framework\base\media\java\an ...
- Andorid之MediaPlayer和AudioTrack播放Audio的区别与联系
播放声音可以用MediaPlayer和AudioTrack,两者都提供了java API供应用开发者使用.虽然都可以播放声音,但两者还是有很大的区别的. 其中最大的区别是MediaPlayer可以播放 ...
- android 使用 audiorecord 和 audiotrack 实现实时录音播放
基本思路就是用 audiorecord不断得到音频数据,然后使用audiotrack 播放 //得到音频 package com.ysg.audiotest;import java.io.IOExce ...
- AudioTrack 播放PCM音频数据
AudioTrack 可以用来播放PCM数据,上一篇博客我讲了AudioRecord可以录制PCM数据 AudioTrack实例可以在两种模式下运行:静态或流式传输. 在Streaming模式下,应用 ...
最新文章
- SAP MM初阶之事务代码MIGO界面批次拆分最多输入15行?
- 【华为出品】智能体白皮书2020(附全文下载)
- 2021年第十六届全国大学生智能汽车竞赛赛道铺设规范
- slf4j 使用方法---个人总结
- 什么是xmlschema
- datetimepicker弹出窗在iframe中部分遮挡_美军下一代班组武器项目,NGSW中的小秘密,你了解多少?...
- 电脑知识:电脑无法开机解决方案,赶紧收藏吧!
- LCS(2021牛客多校4)
- 【python】Macbook的Anaconda查看、创建和管理python环境
- 50元打造双网卡负载均衡服务器
- 寻宝处理器的引人入胜之旅——《大话处理器》新书出炉
- Dubbo自定义日志拦截器 1
- println()函数输出int类型返回值错误的问题
- Herev Falciani推出新的加密货币和区块链项目
- 【面经】深度学习算法岗(京东)
- 单链表插入时间复杂度分析
- HDLBits在线练习题之Exams/ece241 2014 q7b
- ecshop二次开发手册【基本结构】
- Unity UGUI Inputfield 回车submit 按下Enter回车完成
- Android开发使用Glide获取图片背景色淡绿色解决办法