2012-07-24 193 views
0

我正在研究需要音頻/視頻聊天的應用程序......我的問題是當我開始捕獲視頻時,音頻播放完全停止。在Android中啓用相機時音頻播放停止?

技術說明 我已經使用AudioTrack Class和AudioTrack.OnPlaybackPositionUpdateListener進行音頻播放。 我已經使用Camera和Camera.PreviewCallBack進行視頻錄製。

現在只要照相機啓動,AudioTrack類的回調就停止工作。我能做些什麼來解決這個問題?我有HTC的Android2.2設備。

編輯 因爲我不能在這裏發佈完整的代碼...(我沒有獲得視頻模塊的代碼), 我在這裏列出的場景: -

  1. 語音聊天已經開始和音頻播放,這意味着onPeriodicNotification()正確稱爲..

公共無效的start(){

bufferSize = AudioTrack.getMinBufferSize(sampleRateInHz, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 

    if (bufferSize != AudioTrack.ERROR_BAD_VALUE && bufferSize != AudioTrack.ERROR) { 
     audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, this.sampleRateInHz, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 
       this.bufferSize, AudioTrack.MODE_STREAM); 
     if (audioTrack != null && audioTrack.getState() == AudioTrack.STATE_INITIALIZED) { 
      Log.i(LOG_TAG, "Audio Track instance created buffer Size : " + this.bufferSize); 

      audioTrack.setPositionNotificationPeriod(320); 
      audioTrack.setPlaybackPositionUpdateListener(this); 

      // init All the jitter variables 
      initVariables(); 
      // short[] tempBuf = shortBuffer;//new short[bufferSize/2]; 
      audioTrack.write(shortBuffer, 0, shortBuffer.length); 
      audioTrack.write(shortBuffer, 0, shortBuffer.length); 
      audioTrack.write(shortBuffer, 0, shortBuffer.length); 
      audioTrack.write(shortBuffer, 0, shortBuffer.length); 
      audioTrack.write(shortBuffer, 0, shortBuffer.length); 
      audioTrack.write(shortBuffer, 0, shortBuffer.length); 
      // start playback of the audioTrack 
      audioTrack.play(); 

     } else { 
      Log.e(LOG_TAG, "Unble to create AudioTrack instance"); 
     } 
    } else { 
     Log.e(LOG_TAG, "Unable to get the minimum buffer size"); 
    } 
} 

@Override 
    public void onPeriodicNotification(AudioTrack track) { 
     try { 
      fillAudio(shortBuffer); 
      track.write(shortBuffer, 0, Constants.FRAME_SIZE/2); 
     } catch (NullPointerException nex) { 
      nex.printStackTrace(); 
      Log.e(LOG_TAG, "Null Pointer inside periodic notification"); 
     }} 

fillAudio()是填充緩衝功能......

  1. 用戶點擊視頻聊天按鈕,獲取使用Camera.open()相機,設置參數,回調以後用camera.startPreview()開始回調。 。

OnTouchListener cameraSurfaceOnTouch =新OnTouchListener(){ INT X = 0; int y = 0; int dx = 0; int dy = 0; boolean moving = false;

@Override 
    public boolean onTouch(View v, MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      x = (int) event.getX(); 
      y = (int) event.getY(); 
      dx = (int) event.getX() - v.getLeft(); 
      dy = (int) event.getY() - v.getTop(); 
      moving = true; 

      return true; 
     case MotionEvent.ACTION_MOVE: 
      if (moving) { 
       x = (int) event.getX() - dx; 
       y = (int) event.getY() - dy; 

       x = Math.max(x, 0); 
       x = Math.min(x, getWindowManager().getDefaultDisplay().getWidth() - v.getWidth()); 

       y = Math.max(y, 0); 
       y = Math.min(y, getWindowManager().getDefaultDisplay().getHeight() - v.getHeight()); 

       v.layout(x, y, x + v.getWidth(), y + v.getHeight()); 
      } 
      return true; 
     case MotionEvent.ACTION_UP: 
      x = (int) event.getX() - dx; 
      y = (int) event.getY() - dy; 

      x = Math.max(x, 0); 
      x = Math.min(x, getWindowManager().getDefaultDisplay().getWidth() - v.getWidth()); 

      y = Math.max(y, 0); 
      y = Math.min(y, getWindowManager().getDefaultDisplay().getHeight() - v.getHeight()); 

      // v.layout(x ,y,x + v.getMeasuredWidth() , y 
      // +v.getMeasuredHeight()); 
      moving = false; 
      return true; 
     } 
     // v.invalidate(); 
     return false; 
    } 
}; 

Callback videoPlayerCallBack = new Callback() { 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     stopCapturerVideo(); 
     if (converterID != -1 && x264Wrapper != null) { 
      x264Wrapper.destroyVideoFormate(converterID); 
      converterID = -1; 
     } 
    } 
private void startCapturerVideo() { 
     if (m_CameraStatus == false) { 
      this.m_CameraStatus = this.videoCapturer.startCamera(); 
     } 
     synchronized (this.m_videoCapturerBufferList) { 
      this.m_videoCapturerBufferList.clear(); 
     } 

     byte[] tmp = new byte[10]; 
     tmp[0] = Constants.VIDEO_SESSION_STARTED; 

     short width = 160; 
     short height = 120; 

     byte[] mIndex = CommonMethods.toByteArray(session.getSelfMeetingIndex()); 
     byte[] aWidth = CommonMethods.toByteArray(width); 
     byte[] aHeight = CommonMethods.toByteArray(height); 

     tmp[1] = mIndex[0]; 
     tmp[2] = mIndex[1]; 

     tmp[3] = aWidth[0]; 
     tmp[4] = aWidth[1]; 

     tmp[5] = aHeight[0]; 
     tmp[6] = aHeight[1]; 

     tmp[7] = 0; 
     session.add(tmp, 8, 3); 

     aWidth = null; 
     aHeight = null; 
     tmp = null; 

     this.stopThread = false; 
     this.encodeAndSendThread = new Thread(encodeAndSendRun); 
     this.encodeAndSendThread.start(); 
     this.videoCapturer.startCaptureringVideo(); 

    } 
    public boolean startCaptureringVideo() { 
     boolean cameraStatus = true; 
     Log.e(LOG_TAG,"startCaptureringVideo called "); 
     if(this.mCamera != null) 
     { 
      try { 
//    this.mCamera.setPreviewDisplay(this.videoCaptureViewHolder); 
       this.mCamera.startPreview(); 
       } 
      catch (Throwable e) { 
       cameraStatus = false; 
       mCamera.release(); 
       mCamera = null; 

       } 
     } 
     else 
     { 
      cameraStatus =false; 
     } 
     return cameraStatus; 
    } 
  1. onPeriodicNotification()從未第2步,即使我停止並釋放攝像頭後,再次調用。

可能是什麼可能的原因,

+1

我們需要在這裏看到一些代碼。 – Erol 2012-07-24 07:03:10

+0

請參閱編輯...如果這可能會有所幫助.. – aProgrammer 2012-07-24 07:34:38

+1

對不起,我需要看到的代碼,我可以給你一個適當的awnser .. – safari 2012-07-24 07:40:51

回答

1

我有攝像頭視頻錄製聲音類似的問題,2〜3秒後停止。 我意外地發現它是在Android手機HTC Desire Z/HTC G2 aka Vision中的Android手機中的選項在開發人員選項中的部分應用程序開啓了「不保留活動」的描述在用戶離開時立即銷燬所有活動。 當我禁用時,然後重新啓動視頻錄製所有音頻。 檢查你自己,也許你已經啓用了這個選項並禁用它,所以沒有應用程序正在關閉。無論如何,某些進程會關閉,因此它會得到一些狀態,這意味着它並不活躍,並且該選項可以殺死所有沒有活動的東西。

+0

謝謝你的答案。我正在測試GingerBread上的程序,並且您提到的開發人員選項在那裏不可用。然而,我使用了一個技巧(這是壞的,但沒有其他工作對我來說)我跟蹤AudioCallback調用,並且如果回調調用之間的差異超過1秒,則比我剛剛釋放錄音機並重新初始化它。這是現在工作。但我還沒有找到任何最佳解決方案。 – aProgrammer 2013-02-15 07:36:11

+0

但您需要啓用開發人員。 如何在Android 4.2上啓用開發人員設置 轉到設置菜單,然後向下滾動到「關於電話」。點擊它。 再次向下滾動到底部,您會看到「內部編號」。 (您的內部版本號可能與我們在此不同。) 點擊七(7)次。第三次點擊後,你會看到一個有趣的對話,說你離開一個開發者四個水龍頭。 (如果只是這麼簡單,呃?)繼續敲擊,* poof *,你已經重新設置了開發者設置。 – Kangarooo 2013-03-25 15:51:19

5

檢查AudioManager的onAudioFocusChange回調:

@Override 
public void onAudioFocusChange(int focusChange) { 
    if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { 
     //this audio focus change is made when you use the camera 
    } 
} 

也許你暫停音頻時將音頻改變時,檢查出來。