媒体logging器与谷歌视觉API

我正在使用Android视觉API的FaceTracker样本。 但是,在叠加画面时,我正在录制video时遇到困难。

一种方法是将位图存储为图像,并使用FFmpeg或Xuggler将它们合并为video,但是我想知道是否有更好的解决scheme,如果我们可以在运行时loggingvideo预览的投影。

更新1:我使用媒体录像机更新了以下课程,但录制内容仍然无法正常工作。 当我调用triggerRecording()函数时抛出以下错误:

MediaRecorder:启动时处于无效状态:4

并且在清单文件中有外部存储权限。

更新2:

我已经解决了代码中的上述问题,并在onSurfaceCreatedcallback中移动了setupMediaRecorder()。 但是,当我停止录制时,会引发运行时exception。 根据文档,如果没有video/audio数据运行时exception将被抛出。

那么,我在这里错过了什么?

public class CameraSourcePreview extends ViewGroup { private static final String TAG = "CameraSourcePreview"; private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } private MediaRecorder mMediaRecorder; /** * Whether the app is recording video now */ private boolean mIsRecordingVideo; private Context mContext; private SurfaceView mSurfaceView; private boolean mStartRequested; private boolean mSurfaceAvailable; private CameraSource mCameraSource; private GraphicOverlay mOverlay; public CameraSourcePreview(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mStartRequested = false; mSurfaceAvailable = false; mSurfaceView = new SurfaceView(context); mSurfaceView.getHolder().addCallback(new SurfaceCallback()); addView(mSurfaceView); mMediaRecorder = new MediaRecorder(); } private void setUpMediaRecorder() throws IOException { mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface()); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setOutputFile(Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_DCIM + File.separator + System.currentTimeMillis() + ".mp4"); mMediaRecorder.setVideoEncodingBitRate(10000000); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(480, 640); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //int rotation = mContext.getWindowManager().getDefaultDisplay().getRotation(); //int orientation = ORIENTATIONS.get(rotation); mMediaRecorder.setOrientationHint(ORIENTATIONS.get(0)); mMediaRecorder.prepare(); mMediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() { @Override public void onError(MediaRecorder mr, int what, int extra) { Timber.d(mr.toString() + " : what[" + what + "]" + " Extras[" + extra + "]"); } }); } public void start(CameraSource cameraSource) throws IOException { if (cameraSource == null) { stop(); } mCameraSource = cameraSource; if (mCameraSource != null) { mStartRequested = true; startIfReady(); } } public void start(CameraSource cameraSource, GraphicOverlay overlay) throws IOException { mOverlay = overlay; start(cameraSource); } public void stop() { if (mCameraSource != null) { mCameraSource.stop(); } } public void release() { if (mCameraSource != null) { mCameraSource.release(); mCameraSource = null; } } private void startIfReady() throws IOException { if (mStartRequested && mSurfaceAvailable) { mCameraSource.start(mSurfaceView.getHolder()); if (mOverlay != null) { Size size = mCameraSource.getPreviewSize(); int min = Math.min(size.getWidth(), size.getHeight()); int max = Math.max(size.getWidth(), size.getHeight()); if (isPortraitMode()) { // Swap width and height sizes when in portrait, since it will be rotated by // 90 degrees mOverlay.setCameraInfo(min, max, mCameraSource.getCameraFacing()); } else { mOverlay.setCameraInfo(max, min, mCameraSource.getCameraFacing()); } mOverlay.clear(); } mStartRequested = false; } } private class SurfaceCallback implements SurfaceHolder.Callback { @Override public void surfaceCreated(SurfaceHolder surface) { mSurfaceAvailable = true; surface.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // setup the media recorder try { setUpMediaRecorder(); } catch (IOException e) { e.printStackTrace(); } try { startIfReady(); } catch (IOException e) { Timber.e(TAG, "Could not start camera source.", e); } } @Override public void surfaceDestroyed(SurfaceHolder surface) { mSurfaceAvailable = false; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int width = 320; int height = 240; if (mCameraSource != null) { Size size = mCameraSource.getPreviewSize(); if (size != null) { width = size.getWidth(); height = size.getHeight(); } } // Swap width and height sizes when in portrait, since it will be rotated 90 degrees if (isPortraitMode()) { int tmp = width; width = height; height = tmp; } final int layoutWidth = right - left; final int layoutHeight = bottom - top; // Computes height and width for potentially doing fit width. int childWidth = layoutWidth; int childHeight = (int) (((float) layoutWidth / (float) width) * height); // If height is too tall using fit width, does fit height instead. if (childHeight > layoutHeight) { childHeight = layoutHeight; childWidth = (int) (((float) layoutHeight / (float) height) * width); } for (int i = 0; i < getChildCount(); ++i) { getChildAt(i).layout(0, 0, childWidth, childHeight); } try { startIfReady(); } catch (IOException e) { Timber.e(TAG, "Could not start camera source.", e); } } private boolean isPortraitMode() { int orientation = mContext.getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_LANDSCAPE) { return false; } if (orientation == Configuration.ORIENTATION_PORTRAIT) { return true; } Timber.d(TAG, "isPortraitMode returning false by default"); return false; } private void startRecordingVideo() { try { // Start recording mMediaRecorder.start(); mIsRecordingVideo = true; } catch (IllegalStateException e) { e.printStackTrace(); } } private void stopRecordingVideo() { // UI mIsRecordingVideo = false; // Stop recording mMediaRecorder.stop(); mMediaRecorder.reset(); } public void triggerRecording() { if (mIsRecordingVideo) { stopRecordingVideo(); Timber.d("Recording stopped"); } else { startRecordingVideo(); Timber.d("Recording starting"); } } } 

Solutions Collecting From Web of "媒体logging器与谷歌视觉API"