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