1. 程式人生 > >【bug整理】Android聲音併發問題:播放視訊的時候,用第三方應用播放音樂,存在音視訊聲音併發問題

【bug整理】Android聲音併發問題:播放視訊的時候,用第三方應用播放音樂,存在音視訊聲音併發問題

問題描述:應用播放視訊的時候,開啟第三方音樂應用(如酷狗)隨機播放一首音樂;結果:同時存在視訊聲音和音樂聲音;

這種情況顯然是糟糕的體驗,究其問題原因是播放視訊時沒有對音訊焦點做處理導致(Android 2.2開始有音訊焦點機制);播放視訊前需要先請求音訊焦點,暫停視訊、播放完成或者應用退到後臺時需要釋放音訊焦點,以便於其他應用使用音訊焦點;音視訊應用一般都會遵守音訊焦點機制;

解決音視訊併發問題,可以在自定義的xxxVideoView中或視訊播放的xxxActivity中新增如下程式碼;

	/**用AudioManager獲取音訊焦點避免音視訊聲音併發問題 */
	private AudioManager mAudioManager;
	private OnAudioFocusChangeListener mAudioFocusChangeListener;

在播放視訊的時候請求音訊焦點,第三方應用在失去音訊焦點後會暫停播放(音視訊應用一般都會遵守音訊焦點機制,在失去焦點的回撥中做暫停等處理);

    @Override
	public void start() {
    	if (requestTheAudioFocus() == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
			//焦點獲取成功,播放操作
		}else {
			//提示使用者關閉其他音訊再播放,不然使用者以為是bug呢...
		}
    }

在暫停視訊、播放完成或退到後臺時釋放音訊焦點;

	@Override
	public void pause() {
		releaseTheAudioFocus(mAudioFocusChangeListener);
		//暫停邏輯
	}

請求音訊焦點,並設定監聽器

    //zxzhong 請求音訊焦點 設定監聽
    private int requestTheAudioFocus() {
    	if (Build.VERSION.SDK_INT < 8) {//Android 2.2開始(API8)才有音訊焦點機制
			return 0;
		}
    	if (mAudioManager == null) {
    		mAudioManager  = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
		}
    	if (mAudioFocusChangeListener == null) {
    		mAudioFocusChangeListener = new OnAudioFocusChangeListener() {//監聽器
        		@Override
        		public void onAudioFocusChange(int focusChange) {
        			switch (focusChange) {
        			case AudioManager.AUDIOFOCUS_GAIN:
        			case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
					case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
						//播放操作
        				break;
        				
        			case AudioManager.AUDIOFOCUS_LOSS:
        			case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
        			case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
        				//暫停操作
        				break;
        			default:
        				break;
        			}
        		}
        	};
		}
    	//下面兩個常量引數試過很多 都無效,最終反編譯了其他app才搞定,汗~
    	int requestFocusResult = mAudioManager.requestAudioFocus(mAudioFocusChangeListener,
    			AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
    			AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
    	
    	return requestFocusResult;
	}

暫停、播放完成或退到後臺釋放音訊焦點

    //zxzhong 暫停、播放完成或退到後臺釋放音訊焦點
    private void releaseTheAudioFocus(OnAudioFocusChangeListener mAudioFocusChangeListener) {
		if (mAudioManager != null && mAudioFocusChangeListener != null) {
			mAudioManager.abandonAudioFocus(mAudioFocusChangeListener);
		}
	}

如果應用涉及到音視訊播放的話,建議把播放頁面的來電監聽加上,提升下體驗;聲音併發問題可能會讓使用者在嘈雜的環境下解除安裝應用;