当前位置:首页 » 安卓系统 » androidaudiotrack播放

androidaudiotrack播放

发布时间: 2022-12-30 05:08:19

‘壹’ Android播放音频AudioManager踩坑

问题描述:某些APP会调用该接口实现静音铃声播放或将手机切换为振铃模式的功能,用户在使用此类APP进行上述两种操作中任意一种后,会导致手机系统中所有与铃声相关音频都会被静音,用户接收不到铃声、手机提示音等,严重影响用户使用体验。
建议:非声音设置类型的应用不调用setRingerMode接口,交由手机系统控制。

问题描述:语音社交类APP为满足用户语音外放的需求,会调用此接口,但若未在播放结束后,将该接口参数设置为false,会导致之后语音和通话音频流会一直被强制从扬声器输出,影响用户使用其他APP。
建议:一旦APP调用了setSpeakerphoneOn(此时参数为true),
在播放音频流结束后,需要设置setSpeakerphoneOn参数为false,把音频通路还原。

问题描述:该接口会使得用户在使用APP时,静音了某个音频流后,手机中已安装的其他APP,其相应类型的音频流都会被设置为静音。
建议:setStreamMute接口即将被废除,建议开发者使用相应音频实例对应的调节音量参数来实现静音APP自身播放的音频流的功能,例如:AudioTrack实例中的setVolume;MediaPlayer实例中的setVolume;mPlayer.setVolume(0)。

问题描述:在不同的使用场景,用户会有调节不同音频流音量的需求,APP可以调用接口setStreamVolume(int streamType, int index, int flags)来满足这一需求,但往往开发者并没有将streamType参数与当前场景正在播放的音频流类型设置一致,并且该接口可以截获系统的音量按键,导致用户使用APP时,按音量键调节音量后,当前的声音音量大小却没有变化。
建议:
(1)当前vivo手机系统已经可以实现智能识别用户调节音量的场景,并且精准定位用户需要调节的音频流类型,因此建议音量按键交由手机系统来控制。
(2)如若开发者需要调节特定音量,要使用setStreamVolume接口,请设置好符合用户需求场景的正确音频流类型。

问题描述:当前很多APP(常见于社交类)使用这个接口来设置手机通话模式,改变手机声音的输出设备。用户在使用APP时,使用“语音通话模式”(AudioManager.MODE_IN_COMMUNICATION)后,手机会默认从听筒输出音频,导致用户听不见手机提示音、来电铃声等音频。
建议:开发过程中,需要注意在播放音频流结束后,调用接口setMode (AudioManager. MODE_NORMAL),把手机模式还原为正常模式。

问题描述:当用户需要声音从蓝牙输出时,某些APP会使用蓝牙Sco-link通路来传送语音数据到蓝牙耳机。如果开发者没有使用startBluetoothSco成功建立 sco-link连接通路后就直接调用setBluetoothScoOn(true
),会使得蓝牙耳机无声音输出。
建议:开发者应使用startBluetoothSco和stopBluetoothSco接口来建立/断开sco-link连接通路,在建立sco-link连接后,有场景需要将音频从蓝牙切换到手机上时候,调用setBluetoothScoOn(false),再次将音频切换回蓝牙播放时,使用setBluetoothScoOn(true)。

问题描述:某些社交/直播类APP会调用该接口实现语音静音发送的功能,但有些开发者在APP退出的时候没有设置接口为unmute,导致后续其他APP使用手机麦克风录制出来的音频都是静音状态的,影响用户的使用。
建议:由于这个接口直接作用在手机的底层麦克风数据通路,影响范围很大,不建议使用这个接口来实现语音静音发送的需求。开发者可以通过将APP获取到的音频数据直接替换为值=0(静音)的方式,或采取把录制上来的数据直接丢弃不处理的方式来实现这种需求。

‘贰’ Android AudioTrack详解

我们知道播放声音能够用MediaPlayer和AudioTrack,MediaPlayer会在framework层创建相应的音频解码器。而AudioTrack仅仅能播放已经解码的PCM流,MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack。AudioTrack再传递给AudioFlinger进行混音,然后才传递给硬件播放,所以是MediaPlayer包括了AudioTrack

每个音频流相应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到 AudioFlinger中。由AudioFlinger把全部的AudioTrack进行混合(Mixer)。然后输送到AudioHardware中进行播放。眼下Android同一时候最多能够创建32个音频流,也就是说。Mixer最多会同一时候处理32个AudioTrack的数据流。

在4000到48000之间

AudioTrack有两种数据载入模式:
1.MODE_STREAM
在这样的模式下,应用程序持续地write音频数据流到AudioTrack中,而且write动作将堵塞直到数据流从java层传输到native层,同一时候增加到播放队列中。这样的模式适用于播放大音频数据,但该模式也造成了一定的延时;
2.MODE_STATIC
在播放之前,先把全部数据一次性write到AudioTrack的内部缓冲区中。适用于播放内存占用小、延时要求较高的音频数据。

‘叁’ Android 如何生成一个音频的正弦声音信号, 并通过AudioTrack连续不间断播放

参考答案: 女儿年几十五六,窈窕无双颜如玉。

‘肆’ android audiotrack 可以播放什么格式

播放mp3的总是噪音,不知道原因,后来播放wav的倒是可以,
wav是没有压缩的pcm
Java代码
package com.lp;
import java.io.IOException; import java.io.InputStream;
import android.app.Activity; import android.content.Context;
import android.media.AudioFormat; import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.AudioTrack.;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button play;
private Button stop;
private AudioTrack at;
private AudioManager am; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
play = (Button)findViewById(R.id.main_play);
stop = (Button)findViewById(R.id.main_stop);
play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(am.isSpeakerphoneOn()){
am.setSpeakerphoneOn(false);
}
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
am.setMode(AudioManager.MODE_IN_CALL); System.out.println(am.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL));
System.out.println("&&&&&&&&&&&&&"); System.out.println(am.getStreamVolume(AudioManager.STREAM_VOICE_CALL)); int bufferSizeInBytes = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); if(at==null){
at = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);
System.out.println("22222");
new AudioTrackThread().start();
}else{
if(at.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){
System.out.println("111111111");
}else{
System.out.println("33333");
at = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);
new AudioTrackThread().start();
}
} }
});
stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
at.stop();
at.release();
am.setMode(AudioManager.MODE_NORMAL);
}

});

}

class AudioTrackThread extends Thread{

@Override
public void run() {
byte[] out_bytes = new byte[44100];
InputStream is = getResources().openRawResource(R.raw.start);
int length ;
at.play();
try {
while((length = is.read(out_bytes))!=-1){
System.out.println(length);
at.write(out_bytes, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
if(at.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){
at.stop();
at.release();
am.setMode(AudioManager.MODE_NORMAL);
}

}
}
}

‘伍’ Android音频播放

最近需要在Android的客户端中使用PCM声音播放和录制,简单学习了一下。有不正确的地方还请指出。

首先有几个概念需要了解一下:采样频率、声道数、采样位数。

采样频率一般是sample rate, 代表的是数字化音频时每秒采样的次数。常见的有44.1KHz(CD品质)、48KHz等。

这个很好理解,单声道Mono就是声音从一个方向传出来;双声道Stereo也叫立体声,声音是从两个方向传来。通常的流行音乐中,仔细听能发现每个声道可能侧重不同的乐曲声部,比如左声道吉他,右声道钢琴,人声似乎两个声道都有,听起来就像站在中间一样。(这里没有考证,随便举例)

每一个采样都是一个数据点,采样位数是指这个数据点使用了几位来记录。AudioTrack类只支持8位和16位的PCM音频。8位就是2的8次方,即256个值;而16位则是2的16次方,有65536个值。

这个在音频的编解码中还是比较常用的。在PCM格式中,1秒钟音频的数据大小是SampleRate×Channel×Bit/8,单位是byte字节。由于PCM本身没有音频帧的概念,所以通过这个公式就能计算出任意时长音频的大小,或者得到任意大小音频的时长。如果规定1个音频帧是“每个声道256个采样”,双声道下就是512个采样,那么1帧的数据量就是256×Channel×Bit/8,同理可以推断出1秒钟有多少音频帧等等。音频帧的概念在各种编解码中各有不同,但计算公式大同小异,这里不展开。

Android中音频的播放使用的是AudioTrack类,具体用法非常简单。
首先设置buffer大小。AudioTrack播放时需要先写入buffer,如果这个buffer没有写满,那么这部分是不会播放的。所以buffer不能设置太小,这样会导致播放不连贯;而buffer也不能设置太小,这样不间断写入会消耗许多CPU资源。AudioTrack自带了getMinBufferSize方法可以给出一个最小buffer,一般用这个值就可以。getMinBufferSize方法三个参数分别是sample rate、channel和bit。

设置完buffer size就可以实例化一个AudioTrack。其中第一个参数streamType是指不同的音频流类型,包括STREAM_MUSIC、STREAM_ALARM、STREAM_VOICE_CALL、STREAM_RING等,是Android对不同音频的分类。中间三个参数很好理解,第四个是buffer size,刚刚计算出来了。最后一个参数mode有两种:MODE_STREAM和MODE_STATIC。前者是以流形式播放,后者则是一次性全部写入然后播放。

调用实例的play()方法就可以开始播放了。不过播放得要有数据吧?要填写数据就要用到write()方法。write方法中第一个参数是一个byte[]类型,是要写入的数据源,可以是从文件流中读取出来的;第二个参数offset是初始位移,即从source的哪个位置开始;第三个参数则是输入长度。

当write方法写满一个AudioTrack的buffer时,就会有声音播放出来了。
当播放完成后记得要把AudioTrack停止并释放。

‘陆’ Android音视频【十二】使用OpenSLES和AudioTrack进行播放PCM

本节我们学习下如何播放pcm数据,在Android中有两种方法:一种是使用java层的 AudioTrack 方法,一种是使用底层的 OpenSLES 直接在 jni 层调用系统的 OpenSLES的c方法 实现。

两种使用场景不一样:
AudioTrack 一般用于 比如本地播放一个pcm文件/流,又或者播放解码后的音频的pcm流,API较简单。
OpenSLES 一般用于一些播放器中开发中,比如音频/视频播放器,声音/音频的播放采用的OpenSLES,一是播放器一般是c/c++实现,便于直接在c层调用OpenSLES的API,二也是如果用AudioTrack进行播放,务必会带来java和jni层的反射调用的开销,API较复杂。

可以根据业务自行决定来进行选择。

AudioTrack的方式使用较简单,直接在java层。

指定采样率,采样位数,声道数进行创建。

其中44100是采样率, AudioFormat.CHANNEL_OUT_STEREO 为双声道,还有 CHANNEL_OUT_MONO 单声道。 AudioFormat.ENCODING_PCM_16BIT 为采样位数16位,还有 ENCODING_PCM_8BIT 8位。 minBufferSize 是播放器缓冲的大小,也是根据采样率和采样位数,声道数 进行获取,只有满足最小的buffer才去操作底层进程播放。

最后一个参数mode。可以指定的值有 AudioTrack.MODE_STREAM 和 AudioTrack.MODE_STATIC 。

MODE_STREAM 适用于大多数的场景,比如动态的处理audio buffer,或者播放很长的音频文件,它是将audio buffers从java层传递到native层。音频播放时音频数据从Java流式传输到native层的创建模式。

MODE_STATIC 适用场景,比如播放很短的音频,它是一次性将全部的音频资源从java传递到native层。音频数据在音频开始播放前仅从Java传输到native层的创建模式。

是的,就这么一个方法。注意此方法是同步方法,是个耗时方法,一般是开启一个线程循环调用 write 方法进行写入。
注意在调用 write 方法前需要调用 audioTrack.play() 方法开始播放。

因为是pcm裸数据,无法像mediaplayer一样提供了API。所以需要自己处理下。可以利用 getPlaybackHeadPosition 方法。

getPlaybackHeadPosition() 的意思是返回以帧为单位表示的播放头位置
getPlaybackRate() 的意思是返回以Hz为单位返回当前播放采样率。

所以当前播放时间可以通过如下方式获取

OpenSLES:(Open Sound Library for Embedded Systems).
OpenSLES是跨平台是针对嵌入式系统精心优化的硬件音频加速API。使用OpenSLES进行音频播放的好处是可以不依赖第三方。比如一些音频或者视频播放器中都是用OpenSLES进行播放解码后的pcm的,这样免去了和java层的交互。

在Android中使用OpenSLES首先需要把Android 系统提供的so链接到外面自己的so。在CMakeLists.txt脚本中添加链接库OpenSLES。库的名字可以在 类似如下目录中

需要去掉lib

然后导入头文件即可使用了OpenSLES提供的底层方法了。

创建&使用的步骤大致分为:

一个 SLObjectItf 里面可能包含了多个Interface,获取Interface通过 GetInterface 方法,而 GetInterface 方法的地2个参数 SLInterfaceID 参数来指定到的需要获取Object里面的那个Interface。比如通过指定 SL_IID_ENGINE 的类型来获取 SLEngineItf 。我们可以通过 SLEngineItf 去创建各种Object,例如播放器、录音器、混音器的Object,然后在用这些Object去获取各种Interface去实现各种功能。

如上所说,SLEngineItf可以创建混音器的Object。

在创建播放器前需要创建音频的配置信息(比如采样率,声道数,每个采样的位数等)

开始播放后会不断的回调这个 pcmBufferCallBack 函数将音频数据压入队列
(*pcmBufferQueue)->RegisterCallback(pcmBufferQueue, pcmBufferCallBack, this);

如果想要暂停播放参数直接设置为SL_PLAYSTATE_PAUSED,若暂停后继续播放设置参数为SL_PLAYSTATE_PLAYING即可。若想要停止播放参数设置为SL_PLAYSTATE_STOPPED即可。

首先获取播放器的用于控制音量的接口SLVolumeItf pcmVolumePlay

然后动态设置

首先也是获取播放器的用于控制音量的接口SLMuteSoloItf pcmMutePlay

然后动态设置

看起来控制还是蛮简单的哈。先熟悉这么多,OpenSLES还是蛮强大的。

https://github.com/ta893115871/PCMPlay

‘柒’ android AudioTrack.play怎么判断播放完成

根据你的描述:

audioTrack.getPlayState() == AudioTrack.PLAYSTATE_STOPPED;

希望能帮助到你。

‘捌’ android点击播放为什么出现Error creating AudioTrack

android soundpool 没有声音可能是系统故障,解决方法为:
1、备份重要数据,对手机进行恢复出厂设置。
2、在专业人士指导下刷机,具体步骤为:
a、打开“刷机助手”官方网站,在页面中下载刷机助手。下载完成后安装并启动刷机助手。
b、用手机原装数据线将手机与电脑相连接,然后等待刷机助手完成初始化工作。待刷机助手成功识别手机后,可以点击“一键刷机”按钮开始刷机。
c、点击“浏览”按钮选择之前下载的刷机包,若没有下载可以使用刷机助手市场下载ROM包。选择手机对应的型号开始下载ROM。
d、选择刷机包后点击“下一步”按钮备份手机数据,以免数据丢失。备份开始前,在手机中允许刷机助手读取短信、联系人等记录。然后点击“刷机”按钮开始备份并刷机,慢慢等待刷机完成。
3、到手机维修店维修。

‘玖’ Android MediaCodec 编码后解码播放出来声音变了。

也遇到了,还没找到解决方法

‘拾’ android audiotrack同时播放

把他写到service里面,开启两次service就好了,mediaPlayer底层代码也是用service管理的

热点内容
scratch少儿编程课程 发布:2025-04-16 17:11:44 浏览:628
荣耀x10从哪里设置密码 发布:2025-04-16 17:11:43 浏览:357
java从入门到精通视频 发布:2025-04-16 17:11:43 浏览:75
php微信接口教程 发布:2025-04-16 17:07:30 浏览:300
android实现阴影 发布:2025-04-16 16:50:08 浏览:788
粉笔直播课缓存 发布:2025-04-16 16:31:21 浏览:338
机顶盒都有什么配置 发布:2025-04-16 16:24:37 浏览:204
编写手游反编译都需要学习什么 发布:2025-04-16 16:19:36 浏览:801
proteus编译文件位置 发布:2025-04-16 16:18:44 浏览:357
土压缩的本质 发布:2025-04-16 16:13:21 浏览:583