<强> Android EasyPlayer声音自动停止,恢复,一键静音等功能强>
我们在开发播放器时,可能会需要静音或者降低音量的功能,比如说某款音乐播放器,当在后台播放时,如果此时有另外的系统通知声音发的出,可能播放器会把音量降低,系统声音结束后,再调高,如果有来电了,播放器可能会把音乐暂停,等通话结束后再继续播放。还有,比方说我们在某个场合放个视频,不料音量很大,会引来很多目光(很尴尬),这时候可能我们需要一键静音的功能。那这些功能我们应该如何实现呢?
Android播放声音的类为AudioTrack,播放器会先把音频流多路分配器出来,再解码,之后,把音频PCM数据通过AudioTrack类编写到音频设备中,从而通过话筒或者扬声器发出声音。
为了方便地实现声音控制,我们需要从应用的最上层进行操作(因为底层可能已经被抽象成库了),也就是要从AudioTrack来入手。让我们看看AudioTrack的一些API吧。
int getPlayState () 返回播放AudioTrack实例的状态。 获取当前的播放状态。这个接口会返回PLAYSTATE_STOPPED, PLAYSTATE_PAUSED PLAYSTATE_PLAYING 三种状态,分别表示未播放,暂停中,正在播放 >之前空白暂停() 暂停播放的音频数据。没有回放的数据不会被丢弃。后续调用玩()将这个数据。看到平()丢弃这些数据。 暂停播放音频数据。已经在缓冲区中的未播放数据将不会被丢弃,在下次玩的时候继续播放。调用冲水则会丢弃缓冲数据。 >之前空打() 发挥着AudioTrack开始。 开始播放 >之前int setStereoVolume (leftGain浮动, 浮动rightGain) 设置指定的左和右输出增益值> mAudioEnable=mAudioTrack !=零,,mAudioTrack.getPlayState ()==PLAYSTATE_PLAYING; 公共空间setAudioEnable(布尔使){ mAudioEnable=启用; 在=mAudioTrack AudioTrack; 如果(在!=null) { 同步(){ 如果(使){ at.pause (); at.flush (); 其他}{ at.flush (); at.play (); } } } } >之前注意这里在暂停之后,玩之前都调用了冲接口。这样可以确保在由暂停到播放切换时,不会把暂停时未播放的“旧数据“播放出来。
接下来我们实现音频资源被其它进程占用(失去焦点)时,自动降低声音或者停止声音;在音频资源又被释放(重新获取到焦点)时再恢复播放的功能。
我们需要通过AudioManager来判断当前音频资源的状态,并且在音频焦点更改时得到回调。其关键API接口有:
int requestAudioFocus (AudioManager。OnAudioFocusChangeListener l, int streamType, int durationHint) 请求音频的焦点。发送一个请求来获取音频的焦点 请求获取音频焦点。 第一个参数为音频焦点更改时的回调; 第二个参数为音频类型,在我们调节音量时可以看到有若干种音量,就对应的这里的streamType,这里我们基本用音乐,表示“媒体”。 第三个参数表示获取焦点的“时”长,有如下几种情况: AUDIOFOCUS_GAIN_TRANSIENT 表示仅仅为临时获取焦点。比如播放导航语音,通知声音等,属于时间很短暂的情况; AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 表示为鸭模式,表示当获取焦点后,允许先前获取过焦点的程序在降低输出音量的前提下继续播放。 AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE 痛第一种情况类似,只是不允许系统再播放其他声音。通常应用在语音备忘,语音识别等情况; AUDIOFOCUS_GAIN 表示要获取焦点的时长未知。比如播放音乐等等。 当获取到焦点时,函数放回AUDIOFOCUS_REQUEST_GRANTED,当获取失败时,返回AUDIOFOCUS_REQUEST_FAILED >之前结合上面的API说明,参考如下代码以及解释:
//获取AudioManager实例 最后AudioManager我=(AudioManager) mContext.getSystemService (Context.AUDIO_SERVICE); AudioManager。OnAudioFocusChangeListener l=new AudioManager.OnAudioFocusChangeListener () { @Override 公共空间onAudioFocusChange (int focusChange) { 如果(focusChange==AudioManager.AUDIOFOCUS_GAIN){//焦点获取到了,那继续播放,并恢复音量。 AudioTrack AudioTrack=mAudioTrack; 如果(audioTrack !=null) { audioTrack.setStereoVolume (1.0, 1.0); 如果(audioTrack.getPlayState ()==AudioTrack.PLAYSTATE_PAUSED) { audioTrack.flush (); audioTrack.play (); } } }else if (focusChange==AudioManager.AUDIOFOCUS_LOSS){//焦点丢失了,暂停播放。 AudioTrack AudioTrack=mAudioTrack; 如果(audioTrack !=null) { 如果(audioTrack.getPlayState ()==AudioTrack.PLAYSTATE_PLAYING) { audioTrack.pause (); } } }else if (focusChange==AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK){//焦点丢失了,但是允许在降低音量的前提下继续播放,那么降低声音。 AudioTrack AudioTrack=mAudioTrack; 如果(audioTrack !=null) { audioTrack.setStereoVolume (0.5, 0.5); } } } };//因为这里要获得的焦点无法预知时长,因此用AUDIOFOCUS_GAIN模式。 int requestCode=udioManager requestAudioFocus (l。STREAM_MUSIC AudioManager.AUDIOFOCUS_GAIN); 如果(requestCode==AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {//成功获取到了焦点。那启动播放 AudioTrack AudioTrack=mAudioTrack; 如果(audioTrack !=null) { audioTrack.setStereoVolume (1.0, 1.0); 如果(audioTrack.getPlayState ()==AudioTrack.PLAYSTATE_PAUSED) { audioTrack.flush (); audioTrack.play (); } } 其他}{//没有获取到音频焦点。那不播放声音 AudioTrack AudioTrack=mAudioTrack; 如果(audioTrack !=null) { 如果(audioTrack.getPlayState ()==AudioTrack.PLAYSTATE_PLAYING) { audioTrack.pause (); } } }Android EasyPlayer声音自动停止,恢复,一键静音等功能