一、android audio play out channel
扬声器、耳机、听筒,通过这两个来设置,不过有的好像不支持的
/frameworks/base/media/java/android/media/audiomanager.javaaudiomanager.setmode(audiomanager.mode_in_communication)audiomanager.setspeakerhponeon(boolean value)
android audiotrack音频播放分析
音频资源在播放时,会经常出现冲突的情况,如在进行音乐播放时有电话呼入、有新消息的提示音需要播放等,此类的并发处理就需要有一个统一的处理策略。
在android系统开发中,通过为不同的场景配置不同的播放接口,在底层执行统一的并发策略,使得开发者可以将精力更集中在应用本身。
audiotrack、mediaplayer、soundpool、ringtone、jetplayer等都是android音频处理中常用接口
针对audiotrack接口进行详细说明
(1).audiotrack、audiotrack用于管理单个的音频资源。在构造audiotrack实例时,会涉及到流类型、采样率、通道配置、音频格式、缓冲大小、播放模式等因素。
(2).audiotrack支持stream_voice_call、stream_system、stream_ring、stream_music和stream_alarm等流类型。
(3).audiotrack支持44100hz、22050hz、11025hz等采样率。
(4).audiotrack支持单声道(channel_out_mono)、
立体声(channel_out_stereo)等两种通道。
(5).audiotrack支持encoding_pcm_16bit、encoding_pcm_8bit等两种编码格式。
(6).audiotrack支持两种播放模式
静态模式(static mode)
流模式(streaming mode)
其中静态模式由于没有从java层向原生层传递数据造成的延迟,时延很小,当然受限于音频缓冲的大小,通常在游戏场景中用于播放时长很短的音频资源。
当音频流较大不足以在音频缓冲中一次写入时,可采用流模式。
audiotrack的播放状态包括
playstate_stopped
playstate_paused
playstate_playing等
audiotrack实例的状态包括
state_initialized
state_no_static_data
state_uninitialized等
向音频缓冲中添加数据的方法为write()
在设置音频缓冲时,其大小与采样率、通道和音频格式有关,其计算公式为:
缓冲大小 = 最小帧数 × (通道==channel_out_stereo?2:1) × (音频格式== pcm16?2:1)
而最小帧数则受制于采样率和音频设备的延迟等因素
另外,在android2.3中,还引入了会话的概念,便于对单曲的音效进行处理。相应的方法包括:
attachauxeffect()
getaudiosessionid()
setauxeffectsendlevel()等
通过audiotrack.onplaybackpositionupdatelistener监听器可以监听播放进度
当在听歌的时候,突然来了一条短信,如果不加处理,短信的声音很可能被音乐的声音湮没,就会察觉不到。
获取和释放audio focus的过程
(1).申请audio focus
audiomanager audiomanager = (audiomanager)getsystemservice(context.audio_service);int result = audiomanager.requestaudiofocus(this, audiomanager.stream_music, audiomanager.audiofocus_gain);
(2).处理focus change事件
class myservice extends service implements audiomanager.onaudiofocuschangelistener { // .... public void onaudiofocuschange(int focuschange) { // do something based on focus change... }}
申请audio focus和处理focus change一定是互相配合实现的
android听筒播放音乐
audiomanager.setmode(audiomanager.mode_in_call) //设定为通话中即可添加权限android.permission.modify_audio_settings播放完毕后需要audiomanager.setmode(audiomanager.mode_normal);
不然其他软件播放都听筒发声,实际操作中,仅仅上述代码并不能是实现需求
android 5.0.1audiomanager.setmode(audiomanager.mode_in_call); //不能生效,即便添加该行仍然从扬声器播出
应用场景
audio输出通道有很多,speaker、headset、bluetooth a2dp等
android中的audio播放(控制audio输出通道切换)
通话或播放音乐等使用audio输出过程中,可能发生audio输出通道的切换
例如:
插入有线耳机播放音乐时,声音是从耳机发出的;而此时拔出耳机,audio输出通道会发生切换。如果音乐播放器不做处理,audio输出是被切换到扬声器的,声音直接从speaker发出。
android中可以通过android.media.audiomanager查询当前audio输出的情况,并且在audio输出发生变化时,捕获并处理这种变化。
(1).audio输出状态查询与控制
android.media.audiomanager提供的下列方法可以用来查询当前audio输出的状态
isbluetootha2dpon() //检查a2dpaudio是否通过蓝牙耳机
isspeakerphoneon() //检查扬声器是否打开
iswiredheadseton() //检查线控耳机是否连着,注意这个方法只是用来判断耳机是否是插入状态,并不能用它的结果来判定当前的audio是通过耳机输出的,这还依赖于其他条件。
另外还有一些设置这些audio输出的setxyz()方法,这些方法在一般使用audio输出的应用程序不要直接调用,他们由系统来管理,实现audio输出通道的自动切换。除非,界面提供给用户切换的菜单或按钮,而用户选择了却换
例如:
要直接选择扬声器发声,可直接调用setspeakerphoneon()
(2).audio输出通道切换的事件的捕获与处理
因为耳机插拔、蓝牙耳机的断开,audio输出通路会自动切换。此时正在播放audio的程序要获得通知,知道这一事件的发生。
android中是通过广播action_audio_becoming_noisy这个intent通知的。
处理广播的较好的方式,是动态注册/注销自己所关心的广播。
开始播放时注册广播的receiver,停止播放时注销广播的receiver。对audio输出通道切换的处理是暂停当前的播放,不直接从新的通道里发出声来
private class noisyaudiostreamreceiver extends broadcastreceiver { @override public void onreceive(context context, intent intent) { if (audiomanager.action_audio_becoming_noisy.equals(intent.getaction())) { // pause the playback } }}private intentfilter intentfilter = new intentfilter(audiomanager.action_audio_becoming_noisy);private void startplayback() { registerreceiver(mynoisyaudiostreamreceiver(), intentfilter);}private void stopplayback() { unregisterreceiver(mynoisyaudiostreamreceiver);}
(3).audio输出通道切换的典型场景——用耳机听音乐时,拔出耳机
audionoisy client注册了侦听广播
audiomanager.action_audio_becoming_noisy
用耳机一直在听音乐
headsetobserver一直在监视耳机状态的变化。检测到耳机被拔出之后,发出广播audiomanager.action_audio_becoming_noisy
frameworks/base/services/java/com/android/server/headsetobserver.java
audionoisy client收到了广播,发送暂停命令给mediapaybackservice去暂停当前的播放
managing audio playback
提供便捷的音频状态控制
可以构建响应物理音频按键,获取音频播放焦点,以及适时的响应由于系统或其他应用引起的音频焦点变化
三个audiocommandthread线程分别是apmtone、apmaudio、apmoutput
apmtone用于播放tone音
apmaudio用于执行audio命令
apmoutput用于执行输出命令
在audiopolicymanager创建过程中会通过加载audio_policy.conf配置文件来加载音频设备,android为每种音频接口定义了对应的硬件抽象层。硬件抽象层代码
hardware/libhardware/modules/audioexternal/bluetooth/bluedroid/audio_a2dp_hw/audio.a2dp.default.sohardware/libhardware/modules/audio/audio.primary.default.sohardware/libhardware/modules/usbaudio/audio.usb.default.so
原文链接:https://www.shuzhiduo.com/a/1o5edokgj7/https://blog.csdn.net/thl789/article/details/7423523https://www.shuzhiduo.com/a/gkz1lj3gdr/
二、android上播放视频时没有声音的问题
(1).如果在android上播放视频时遇到没有声音的问题,要么是android手机上有问题,要么就是视频本身有问题。无论那种情况,都有相对应的解决方案。
(2).在android audio相关开发过程中,可能会遇到播放ringtone时无声,但播放music可以听到声音,关于无声问题的分析。
三、android设备上播放有声视频的技巧
(1).始终保持扬声器清洁
(2).未经验证的应用程序不应安装在设备上
(3).手机的音频端口。这是因为一旦拔出耳机,某些设备就会卡在耳机模式
(4).还应检查听筒
四、android audio遇到播放无声时的分析思路
(1).在音量控制面板中确认该音频流对应的volume_index大小是否等于0
(2).若volume_index != 0时,看user space的logcat与kernel log中有无明显的audio fail项,比如设备是否选择正确以及对应的路径是否有配通
(3).在hardware层,在audio_hw.cpp文件中的out_write函数中添加log,判断是否有数据写入(qcom msm8939)
/hardware/libhardware/modules/audio_remote_submix/audio_hw.cpp785 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,786 size_t bytes)
(4).通过dumpsys media.audio_policy命令来查看对应音频流是否被mute住,若被mute,需要分析audiopolicymanager.cpp文件
/frameworks/av/services/audiopolicy/managerdefault/audiopolicymanager.cpp
(5).看当前音源档本身的音量是否为0
其中1与5之间的区别在于:
在播放某音源档时,在audiotrack::set()函数里,先将音源数据的左右声道的volume设置为1.0,即为最大声。而通过音量按键或则在volumepanel中调节音量则是在最大音量基础上做衰减操作
/frameworks/av/media/libaudioclient/audiotrack.cpp326 status_t audiotrack::set(327 audio_stream_type_t streamtype,328 uint32_t samplerate,329 audio_format_t format,330 audio_channel_mask_t channelmask,331 size_t framecount,332 audio_output_flags_t flags,333 callback_t cbf,334 void* user,335 int32_t notificationframes,336 const sp& sharedbuffer,337 bool threadcancalljava,338 audio_session_t sessionid,339 transfer_type transfertype,340 const audio_offload_info_t *offloadinfo,341 uid_t uid,342 pid_t pid,343 const audio_attributes_t* pattributes,344 bool donotreconnect,345 float maxrequiredspeed,346 audio_port_handle_t selecteddeviceid)
/frameworks/base/services/core/java/com/android/server/audio/audioservice.javamvolumecontrolstream volumepanel/frameworks/base/media/java/android/media/audiomanager.javavolumepanel
(6).在android开发中可以通过audiomanager来判断是否有声音在播放
/frameworks/base/services/core/java/com/android/server/policy/phonewindowmanager.java/frameworks/base/media/java/android/media/audiomanager.java2046 public boolean ismusicactive() {2047 return audiosystem.isstreamactive(stream_music, 0);2048 }
(7).android中的audio播放(分析控制audio输出通道切换设置)
检查android audio音频setmode()的默认设置audiomanager.setmode(audiomanager.mode_normal);
android各版本系统源码在线阅读地址
http://aospxref.com/http://androidxref.comhttps://aosp.opersys.comhttps://wiki.lineageos.org/devices/https://wiki.pixelexperience.org/devices/
无人机空中移动性管理分布式控制框架
芯片通信的革命:世界最小纳米激光发射器问世
5G的商用价值主要体现在哪里
全新的力帆鹏飞SUV新车实车曝光:外观不输哈弗,直接叫板宝骏510!
外媒:iPhone7将迎压力传感技术、双摄像头+双扬声器
Android AudioTrack音频播放分析
搭载MagicOS 7.0新系统的荣耀Magic V评测
未来城市可能靠机器人来建
常州恐龙园文旅集团主题酒店融入AR\VR科技,为游客带来个性化的旅游体验
汽车电子的汽车底盘结构及特点介绍
东风科技成功配股募资12.57亿认配率97.68%
“联合甄选,专注科学”系列 新品分享—磁光克尔综合测试平台
NAS下搭建linux命令搜索引擎教程
22000字长文传感器发展简史
陕西泾河东庄水利枢纽工程全面开工
帮助用户打造全新的数字化体验,加速企业实现降本增效目标
索达LED灯 营销全球
你懂精通STM32的含金量吗?
医疗刺激装置如何通过外部存储器来实现高性能
Windows 10曝出十月更新部分严重bug:发布19042.608 版本 修复