Как записать отфильтрованные видеокадры с помощью MediaRecorder и OpenGL ES - PullRequest
1 голос
/ 06 октября 2019

Я пытаюсь создать приложение для камеры, которое сможет фильтровать кадры с применением какого-либо фильтра (только для учебных целей). Для этого я использовал Camera2 API и OpenGL ES . Мне удалось применить фильтр градаций серого к кадрам, чтобы предварительный просмотр был в градациях серого. Теперь я хотел записать этот отфильтрованный предварительный просмотр, используя MediaRecorder , и я посмотрел следующий образец , чтобы увидеть, как MediaRecorder работает с Camera2 API (я только что добавил OpenGL ES часть). Но когда я записываю, он записывает нефильтрованный предварительный просмотр, а не отфильтрованный предварительный просмотр. Здесь демонстрация. Вот как выглядит предварительный просмотр камеры при включенном фильтре оттенков серого:

enter image description here

И вот как это выглядит, когда я воспроизводю записанное видео послеон хранится в каталоге:

enter image description here

Мне кажется, что MediaRecorder просто берет нефильтрованные / необработанные кадры и сохраняетих.

Вот соответствующие части моего кода:

// basically the same code from the link above
// here: mSurfaceTexture is the surface texture I created via glGenTextures()
public void startRecordingVideo() {
        if (null == mCameraDevice || null == mCameraSize) {
            return;
        }


        try {
            closePreviewSession();
            setUpMediaRecorder();
            SurfaceTexture texture = mSurfaceTexture;
            assert texture != null;
            texture.setDefaultBufferSize(mCameraSize.getWidth(), mCameraSize.getHeight());
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            List<Surface> surfaces = new ArrayList<>();

            // Set up Surface for the camera preview
            Surface previewSurface = new Surface(texture);
            surfaces.add(previewSurface);
            mCaptureRequestBuilder.addTarget(previewSurface);

            // Set up Surface for the MediaRecorder
            Surface recorderSurface = mMediaRecorder.getSurface();
            surfaces.add(recorderSurface);
            mCaptureRequestBuilder.addTarget(recorderSurface);

            // Start a capture session
            // Once the session starts, we can update the UI and start recording
            mCameraDevice.createCaptureSession(surfaces, mCameraCaptureSessionCallbackForTemplateRecord , mBackgroundHandler);
        } catch (CameraAccessException | IOException e) {
            e.printStackTrace();
        }

    }

MediaRecorder часть также из образца выше:

private void setUpMediaRecorder() throws IOException {
        final Activity activity = mActivity;
        if (null == activity) {
            return;
        }

        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
            mNextVideoAbsolutePath = getVideoFilePath(mActivity);
        }
        mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
        mMediaRecorder.setVideoEncodingBitRate(10000000);
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        switch (mSensorOrientation) {
            case SENSOR_ORIENTATION_DEFAULT_DEGREES:
                mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
                break;
            case SENSOR_ORIENTATION_INVERSE_DEGREES:
                mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
                break;
        }
        mMediaRecorder.prepare();
    }

ТакКак я могу сказать MediaRecorder использовать отфильтрованные / обработанные кадры? Возможно ли это?

Я пытался вызвать setInputSurface () в экземпляре MediaRecorder , передав ему переменную previewSurface (до этогоРазумеется, я преобразовал эту переменную в глобальную переменную, чтобы использовать ее в методе setUpMediaRecorder () ). Но я получил ошибку, указывающую, что это не была постоянная поверхность. В документе для setInputSurface () указано, что следует использовать постоянную поверхность (что бы это ни значило)

Надеюсь, кто-то может помочь?

...