0

オーディオ/ビデオチャットを必要とするアプリに取り組んでいます...ビデオのキャプチャを開始すると、オーディオの再生が完全に停止するという問題があります。

技術的な説明 オーディオ再生にAudioTrackクラスとAudioTrack.OnPlaybackPositionUpdateListenerを使用しました。私はビデオ録画にCameraとCamera.PreviewCallBackを使用しました。

これで、カメラが起動するとすぐに、AudioTrackクラスのコールバックが機能しなくなります。この問題を処理するにはどうすればよいですか?Android2.2を搭載したHTCのデバイスを持っています。

編集 私はここに完全なコードを投稿することができないので...(私はビデオモジュールのコードにアクセスできません)、私はここにシナリオをリストしています:-

  1. オーディオチャットが開始され、オーディオが再生されています。これは、onPeriodicNotification()が正しく呼び出されていることを意味します。

public void 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 = new OnTouchListener(){int x = 0; int y = 0; int dx = 0; int dy = 0; ブール移動=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の後で再び呼び出されることはありません。

これの考えられる理由は何でしょうか、

4

2 に答える 2

1

カメラのビデオ録画の音が2〜3秒後に停止するという同様の問題がありました。私は偶然、それが Android phone HTC Desire Z / HTC G2 aka Vision の開発者向けオプションのセクション APPS ive で「ユーザーが離れるとすぐにすべてのアクティビティを破棄する」という説明で「アクティビティを保持しない」をオンにしたことを発見しました。それを無効にすると、再起動後にビデオがすべてのオーディオを録音しました。そのオプションを有効にして無効にして、アプリが閉じられないようにしてください。いずれにせよ、一部のプロセスがシャットダウンするだけで、何らかのステータスウィッチがアクティブではないことを意味し、そのオプションにより、アクティブではないすべてのものを強制終了します。

于 2013-02-14T11:44:12.277 に答える