2012-07-24 40 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 
    } 
} 

也许你暂停音频时将音频改变时,检查出来。