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