Android Audio Play Out Channel

1: 7嘴8舌

 

扬声器, 耳机, 和听筒

就是通过: audiomanager.setmode(AudioManager.MODE_IN_COMMUNICATION)
audiomanager.setSpeakerhponeOn(boolean value).这两个来设置.不过有的好像不支持的.

米手机上切换 扬声器和听筒不能切换

 

Android AudioTrack音频播放分析  
音频资源在播放时,会经常出现冲突的情况,如在进行音乐播放时有电话呼入、
有新消息的提示音需要播放等,此类的并发处理就需要有一个统一的处理策略。在 Android系统开发中,通过为不同的场景配置不同的播放接口,在底层执行统一的并发策略,使得开发者可以将精力更集中在应用本身。
A udioTrack、MediaPlayer、SoundPool、Ringtone、JetPlayer等都是Android音频处理中常用接口,本文将针对AudioTrack接口进行详细说明。
AudioTrack AudioTrack用于管理单个的音频资源。 在构造AudioTrack实例时,会涉及到流类型、采样率、通道配置、音频格式、缓冲大小、播放模式等因素。
AudioTrack支持STREAM_VOICE_CALL、STREAM_SYSTEM、STREAM_RING、STREAM_MUSIC和STREAM_ALARM等流类型。
AudioTrack支持44100Hz、22050Hz、11025Hz等采样率。 AudioTrack支持单声道(CHANNEL_OUT_MONO)、立体声(CHANNEL_OUT_STEREO)等两种通道。
AudioTrack支持ENCODING_PCM_16BIT、ENCODING_PCM_8BIT等两种编码格式。
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) 而最小帧数则受制于采样率和音频设备的延迟等因素。
另外,在Android 2.3中,还引入了会话的概念,便于对单曲的音效进行处理。相应的方法包括:attachAuxEffect()、getAudioSessionId()、setAuxEffectSendLevel()等。
通过AudioTrack.OnPlaybackPositionUpdateListener监听器可以监听播放进度。
下面是一个背景音频的播放过程:
代码10-3 AudioTrack播放音频文件


public class BackgroundAudio extends Thread { public static final int SAMPLE_RATE = 16000public static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; public static final int BYTES_PER_SAMPLE = 2public static final int PLAYBACK_STREAM = AudioManager.STREAM_MUSIC; …… 
public BackgroundAudio(byte[] data) { //计算缓冲大小  final int minBufferSize = (BUFFER_TIME *SAMPLE_RATE*BYTES_PER_SAMPLE) / 1000; //计算硬件的最小缓冲 final int minHardwareBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE,AudioFormat.CHANNEL_OUT_MONO,AUDIO_FORMAT); mBufferSize = Math.max(minHardwareBufferSize, minBufferSize);        
     mAudioTrack = new AudioTrack(PLAYBACK_STREAM, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO,  AUDIO_FORMAT, mBufferSize, AudioTrack.MODE_STREAM);         

     if (mAudioTrack.getState() == AudioTrack.STATE_INITIALIZED) {             
     writeAudio(); start(); 
// 启动背景线程去推送音频数据             mAudioTrack.play();         } else { Log.e(TAG, "Error initializing audio track.");         
  } } …… 
private void writeAudio() {    
  int len = mData.length;    
  int count; int maxBytes = Math.min(mBufferSize, len - mPos);  count = mAudioTrack.write(mData, mPos, maxBytes);    
  if (count < 0) { Log.e(TAG, "Error writing looped audio data");        
  halt();        

  return;     
  } mPos 
+= count;    

if (mPos == len) { mPos = 0; // Wraparound    
 }  } }

Media playback  
Supported Media Formats  
Audio Capture  
JetPlayer  
Camera  这次我先分享下Media Playback的中一些内容以及我学习中的感悟。  首先需要我们接触到的最主要的两个类分别是MediaPlayer、MediaManager。MediaPlayer是用来控制音频/视频流或者文件的播放的,需要我们注意的是MediaPlayer对象加上其支持的一些播放操作会形成一个状态机,在不合适的状态执行不合适的操作就会抛出异常,如果开发者不清楚自己创建的MediaPlayer对象当前处于哪个状态,就很有可能调用错误的方法造成程序的异常,而且这些错误很难被察觉,所以错误处理在这个部分就显得尤为重要。  下面要说的就是Audio Focus,举个例子,当你在听歌的时候,突然来了一条短信,如果不加处理,短信的声音很可能被音乐的声音湮没,你就会察觉不到。我们希望发生什么事情呢?我们希望这个时候音乐的声音较之前稍微降低些使得我们能够听到短信提示音,在短信提示音结束后音乐的声音再次回到正常。这个过程就是获取和释放audio focus的过程。  在写代码的时候,我忽略了一点:Audio Focus is cooperative in nature.  申请audio focus  [java] view plaincopyprint?AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);   
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,    AudioManager.AUDIOFOCUS_GAIN);    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);  
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,  AudioManager.AUDIOFOCUS_GAIN);  
处理focus change事件  [java] view plaincopyprint?class MyService extends Service    implements AudioManager.OnAudioFocusChangeListener {    // ....     public void onAudioFocusChange(int focusChange) {    // Do something based on focus change...     
    }    
}    class MyService extends Service  implements AudioManager.OnAudioFocusChangeListener {  // ....  public void onAudioFocusChange(int focusChange) {  // Do something based on focus change...  
    }  
}  申请audio focus和处理focus change一定是互相配合实现的,我一开始写了个service用来播放音乐,在start函数调用前并没有申请audio focus,但是我实现了onAudioFocusChange函数。我期待这个service在focus change时停止播放,但是我发现,当另外一个service申请到audio focus时,之前的service不会出现音乐停止播放的情况。 
android培训,就选成都达内,最好的成都软件培训机构,如果你有“达内培训需要多少钱”、“达内培训怎么样”等问题,详情请咨询达内客服(http://www.sctarena.com),我们会给你详细的讲解。

 

 

android 听筒播放音乐


AudioManager.setMode(AudioManager.MODE_IN_CALL) //设定为通话中即可 还是这一句代码的事,不过记得要加上权限android.permission.MODIFY_AUDIO_SETTINGS还有一点需要注意的事,在播放完毕后需要AudioManager.setMode(AudioManager.MODE_NORMAL);不然其他软件播放都听筒发声了

实际操作中,仅仅上述代码并不能是实现需求:

荣耀:4..2.2

内核3.4.5


audiomanager.setMode(AudioManager.MODE_IN_CALL);

Nexus 5   5.0.1

内核2.4.0

audiomanager.setMode(AudioManager.MODE_IN_CALL);不能生效,即便添加该行仍然从扬声器播出

 

 

  
  
  
 
设备audio pathmedia paly new 
    
    
    
    

 

Actually you don't need audioManager.setSpeakerphoneOn(false); . And also, you need to create MediaPlayer not with static method MediaPlayer.create(), but you need to create it with new MediaPlayer()... –  Andranik Jun 12 '14 at 18:40 up vote
16
down vote
accepted
Audio handling on Android is going to be pretty horrible for a while. The APIs are pretty weird, poorly documented, and keep changing/deprecating/breaking between versions. Even the AudioManager code has FIXMEs in it.Anyway, there are several stream types in Android (music, notifications, phone calls, etc.) and applications are meant to choose the appropriate one for playback. I imagine the majority of Android apps should use the music/media type (STREAM_TYPE_MUSIC). You set this on your MediaPlayer using the setAudioStreamType method.The SDK does allow you to set a single stream type as solo — causing all other streams to be muted — but I don't believe you can identify the audio being played back by particular applications and somehow pause/unpause it. Music applications in general will use the PhoneStateListener to pause themselves when a call comes in.

So in your case, you could "borrow" the phone call stream for your MediaPlayer and use the method call AudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true) when playback begins, then un-solo the stream with false when playback or your Activity is done.I can tell you that this works, but I can't remember offhand whether you need to also set the audio mode to MODE_IN_CALL when using the voice call stream (like this: AudioManager.setMode(AudioManager.MODE_IN_CALL)). If you find that is required, then you need to make sure you return the mode to MODE_NORMAL once playback completes, otherwise whenever you press the volume hard keys, it'll say "In-call volume"! However, if and when you do want to change back to MODE_NORMAL, you must check that a genuine phone call isn't happening at that time...

Maybe you could use another stream type rather than the voice call one, but I'm just speaking from experience working on an app that could use either the speakerphone or the earpiece for audio playback, which requires the use of the voice call stream.

Like I said, audio handling isn't particularly fun... ;)

 

2:应用场景

 

Audio 输出通道有很多,Speaker、headset、bluetooth A2DP等。

通话或播放音乐等使用Audio输出过程中,可能发生Audio输出通道的切换。比如,插入有线耳机播放音乐时,声音是从耳机发出的;而此时拔出耳机,Audio输出通道会发生切换。如果音乐播放器不做处理,Audio输出是被切换到扬声器的,声音直接从Speaker发出。

Android中可以通过android.media.AudioManager查询当前Audio输出的情况,并且在Audio输出发生变化时,捕获并处理这种变化。

AudioNoisy AudioManager

一、Audio输出状态查询与控制

android.media.AudioManager提供的下列方法可以用来查询当前Audio输出的状态:

 

  •  isBluetoothA2dpOn():检查A2DPAudio是否通过蓝牙耳机;
  •  isSpeakerphoneOn():检查扬声器是否打开;
  •  isWiredHeadsetOn():检查线控耳机是否连着;注意这个方法只是用来判断耳机是否是插入状态,并不能用它的结果来判定当前的Audio是通过耳机输出的,这还依赖于其他条件。

 

另外还有一些设置这些Audio输出的setXYZ()方法,这些方法在一般使用Audio输出的应用程序不要直接调用,他们由系统来管理,实现Audio输出通道的自动切换。除非,界面提供给用户切换的菜单或按钮,而用户选择了却换,比如要直接选择扬声器发声,可直接调用setSpeakerphoneOn()。

 

二、Audio输出通道切换的事件的捕获与处理

因为耳机插拔、蓝牙耳机的断开,Audio输出通路会自动切换。此时正在播放Audio的程序要获得通知,知道这一事件的发生。Android中是通过广播ACTION_AUDIO_BECOMING_NOISY这个Intent通知的。

处理广播的较好的方式,是动态注册/注销自己所关心的广播。下面代码演示了,开始播放时注册广播的Receiver;停止播放时注销广播的Receiver。对Audio输出通道切换的处理是暂停当前的播放,不直接从新的通道里发出声来。

private class NoisyAudioStreamReceiver extends BroadcastReceiver {@Overridepublic 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);
}

三、Audio输出通道切换的典型场景—— 用耳机听音乐时,拔出耳机

听耳机听音乐时,耳机别拔出的时序图如下:

AudioNoisy_Sequence.jpg

图中:

 

  •  AudioNoisy Client注册了侦听广播AudioManager.ACTION_AUDIO_BECOMING_NOISY[Step#1 ~ #2];
  •  用耳机一直在听音乐;
  •  HeadsetObserver一直在监视耳机状态的变化。检测到耳机被拔出之后,发出广播AudioManager.ACTION_AUDIO_BECOMING_NOISY[Step#3~4];
  •  AudioNoisy Client收到了广播,发送暂停命令给MediaPaybackService去暂停当前的播放 [Step#5~6]。

 

 3:Android 文档

Building Apps with Multimedia

These classes teach you how to create rich multimedia apps that behave the way users expect.

  1. Managing Audio Playback

    If your app plays audio, it’s important that your users can control the audio in a predictable manner. To ensure a great user experience, it’s also important that your app manages the audio focus to ensure multiple apps aren’t playing audio at the same time.After this class, you will be able to build apps that respond to hardware audio key presses, which request audio focus when playing audio, and which respond appropriately to changes in audio focus caused by the system or other applications.
    为用户提供便捷的音频状态控制对良好的用户体验是非常重要的。你可以构建响应物理音频按键,获取音频播放焦点,以及适时的响应由于系统or其他应用引起的音频焦点变化。

     

  2.  


    How to respond to hardware audio key presses, request audio focus when playing audio, and respond appropriately to changes in audio focus.

    1. Controlling Your App's Volume and Playback
    2. Managing Audio Focus
    3. Dealing with Audio Output Hardware

 

引用:

http://blog.csdn.net/thl789/article/details/7423523

转载于:https://www.cnblogs.com/conncui/p/4303795.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis 缓存 @class: 会有 $hibernateproxy_微信亿级在线点赞系统,用Redis如何实现?

点赞功能大家都不会陌生&#xff0c;像微信这样的社交产品中都有&#xff0c;但别看功能小&#xff0c;想要做好需要考虑的东西还挺多的&#xff0c;如海量数据的分布式存储、分布式缓存、多 IDC 的数据一致性、访问路由到机房的算法等等。图片来 Pexels本文介绍大型社交平台点…

查询hive表_大数据中Hive与HBase的区别与联系

二者区别Hive&#xff1a;Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供简单的sql查询功能。Hive本身不存储和计算数据&#xff0c;它完全依赖于HDFS和MapReduce&#xff0c;Hive中的表纯逻辑。hive需要用到hdfs…

查询使用NoLock

当我们在操作数据库的时候&#xff0c;无论是查询还是修改数据库的操作我们都习惯使用using(var dbnew XXXDB()){}&#xff0c;但是如果仅仅是做查询&#xff0c;最好是使用NoLock&#xff0c;因为NoLock使用的是共享锁&#xff0c;可以减少死锁发生的机率。 从上图中代码可以看…

端午粽香html5游戏,《快乐端午粽飘香》亲子活动教案

《快乐端午粽飘香》亲子活动教案过端午节是我国两千多年来的习惯&#xff0c;为了让幼儿更好地了解端午节&#xff0c;感受端午节丰富的文化内涵&#xff0c;激发初步的爱国主义情感&#xff0c;丰富生活经验&#xff0c;应届毕业生考试网小编特意为大家整理了《快乐端午粽飘香…

d3js绘制y坐标轴_【ggplot2】 设置坐标轴

基本箱线图library(ggplot2)bp ggplot(PlantGrowth, aes(xgroup, yweight)) geom_boxplot()bp反转 x轴 与 y轴bp coord_flip()离散型数据的坐标轴改变坐标轴中各项目的顺序 > 特别注意, 离散数据的坐标轴中数据做为 factor 变量处理,他的位置取决于 level的顺序# 手动设置…

html页面判断是否登录,egg(103)--egg之定义公共的中间件判断用户是否登录以及去结算页面制作...

判断用户是否登录中间件app/middleware/userauth.jsmodule.exports (options, app) > {return async function init(ctx, next) {//判断前台用户是否登录 如果登录可以进入 ( 去结算 用户中心) 如果没有登录直接跳转到登录var userinfo ctx.service.cookies.get(userinfo)…

计算机应用的时间地点意义,计算机应用在教学中的作用

计算机应用在教学中的作用微课已成为当前我国教育信息化发展的重点和热点。在如今的数字化“微”时代&#xff0c;微课将成为一种新的教学模式和学习方式。下面是小编搜集整理的相关内容的论文&#xff0c;欢迎大家阅读参考。摘要&#xff1a;随着我国科技和技术的不断发展&…

启继承父位在什么时候_为什么少儿口才现在越来越受到家长们的重视

情商口才是个人素养、能力和智慧的一种综合反映&#xff0c;随着社会的发展&#xff0c;少年儿童的早期教育越来越受到家长的重视&#xff0c;特别是在培养孩子的语言表达能力中&#xff0c;更多的家长开始寻求各种方法来锻炼孩子的语言表达能力。源自于美国教育演说家卡耐基的…

x光肺部分割数据集_吴恩达发布了大型X光数据集,斯坦福AI诊断部分超越人类 | AAAI 2019...

数栗子 发自 凹非寺量子位 报道 | 公众号 QbitAI最近&#xff0c;吴恩达的斯坦福团队发布了一个叫做CheXpert的大型数据集&#xff0c;论文中选了AAAI 2019。它包含了224,316张标注好的胸部X光片&#xff0c;以及放射科医师为每张胸片写的病理报告。虽然&#xff0c;像从前NIH发…

【Qt之Quick模块】6. QML语法详解_1 基础语法与三种导入语句

前言 通过以上1-5文档的介绍&#xff0c;Quick与QML的概念及QML语法、类型、文件作用等已叙述个大概&#xff0c;接下来是对QML语法进行展开来说。 其实&#xff0c;学习任何一门语言或者做任何一件事情&#xff0c;并不用一开始就要求尽善尽美&#xff0c;做个无懈可击&…

datagrip将一个数据库中的数据_跨平台数据库管理神器DataGrip,用上就爱不释手...

原文链接&#xff1a;https://www.ffeeii.com/2041.htmlDataGrip是Jetbrains旗下众多优秀的效率生产工具之一。下载地址&#xff1a;https://www.jetbrains.com/datagrip/DataGrip是多引擎数据库环境&#xff0c;支持几乎常见的数据库类型&#xff1a;PostgreSQL、MySQL、Oracl…

idea下拉项目_推荐几款非常好用的IDEA插件(香)

每天进步一点点&#xff0c;坚持下去&#xff0c;你总是会不一样的。加油&#xff01;最近在整理Java常用的一些基础、ZooKeeper、Spring全家桶、源码、Dubbo、Elasticsearch、Redis、MySql、RabbitMQ、Kafka、Linux 、微服务等技术栈。持续更新中&#xff0c;欢迎点上面后端架…

ora 00900 已编译但有错误_技术分享|万万没想到!编译错误竟然还没灭绝???

CodeWisdom-技术分享万万没想到&#xff01;编译错误竟然还没灭绝&#xff1f;&#xff1f;&#xff1f;复旦大学CodeWisdom团队的代码分析和挖掘小组针对开源软件项目持续集成过程中出现的编译错误&#xff0c;进行了大规模的经验研究。该研究分析了常见的编译错误类型、修复代…

用计算机心如止水,计算机网络数据链路层

1、数据链路层使用的信道类型&#xff1a;点对点信道(1对1)广播信道(1对多)&#xff0c;如&#xff1a;集线器、交换机2、链路与数据链路&#xff1a;链路&#xff1a;点对点的物理线路段&#xff0c;中间无任何其他交换结点数据链路&#xff1a;通信协议 软件 硬件(一般用适…

easyui tree动态加载_动态路由:Gin vs SpringMVC

这两天在接触Gin&#xff0c;对它的动态路由功能比较感兴趣&#xff0c;特意做了笔记&#xff0c;顺便跟SpringMVC作下对比。1.简介Gin是使用Go/golang语言实现的HTTP Web框架。接口简洁,性能极高。截止1.4.0版本,包含测试代码,仅14K,其中测试代码9K左右,也就是说框架源码仅5K左…

伍德里奇---计量经济学第6章部分计算机习题详解(stata),伍德里奇---计量经济学第6章部分计算机习题详解(STATA)...

所以&#xff0c;log bwg t7.5840.0180npvis?0.00041npvis20.0254mage?0.00041mage20.1370.00370.000120.0093 (0.00015)n1764&#xff0c;R20.0256&#xff0c;R20.0234。当孩子的出生体重最大时&#xff0c;对应的年龄为mage? β12β20.0254[2?0.00041] 30.96&#xff0c…

vue菜单点击html,基于vue.js实现侧边菜单栏

侧边菜单栏应该是很多项目里必不可少的 自己手写了一个下面是效果图下面就说一下实现的过程 还是比较简单的首先导入一下需要的文件接下来就是我的html主页系统用户管理权限设置操作日志设备运行日志防区 防区管理警报 历史报警曲线报表统计警情处理设备然后是css* {margin: 0;…

centos7 mysql启动失败_Mysql主从复制

​好在&#xff0c;别人如何分析我&#xff0c;跟我本身是一点关系也没有的。(by 三毛)主从复制的常见用途1.数据备份对备份来说,复制是一项很有意义的技术补充,但复制既不是备份也不能取代备份2.负载均衡(读写分离)通过MySQL主从复制,可以把写操作放在主库(master)&#xff0c…

计算机应用基础知道,谁知道计算机应用基础练习题的答案?

谁知道计算机应用基础练习题的答案&#xff1f;46&#xff0e;简述美籍匈牙利数学家冯诺依曼(Von Neumann)在1946年提出的关于计算机的体系结构和“程序存储”的设计思想。47&#xff0e;简要说明Windows98中安装存放在CD—ROM上的应用程序的操作过程。48&#xff0e;简述Windo…

计算机程序编辑器中文版,小说编辑器(Atomic Scribbler)

AtomicScribbler是一款功能强大的电脑小说编辑器&#xff0c;快速编辑、创作你的小说&#xff0c;也可以直接导入文本二次编辑&#xff0c;内置了丰富的文字编辑工具&#xff0c;完全能够满足日常创作小说、编辑文字使用需求。。相关软件软件大小版本说明下载地址AtomicScribbl…