Closed anonym24 closed 6 years ago
Is something like this would be possible for MediaCodec/GLES stuff?
这个项目暂时不适用 . 需要后台录制的话, 如果不需要加水印可以考虑在AudioVideoRecordingSample 的基础上修改 ,
如果需要加水印 , 那么也可以在这个项目的基础上修改 , 通过 OffscreenSurface.java 这个理论上是可以的
@anonym24 我本地最新的代码似乎可以支持离屏录制 , 我下午将尝试一下 .
@anonym24 我试了试 , 可以的 , 待会我将更新代码
@anonym24 MultiPartRecorderFragment.java
private void initRecorder() {
// ICameraPreview cameraPreview = new DefaultCameraPreview(mTextureView);
ICameraPreview cameraPreview = new OffscreenCameraPreview(getContext(), 1920, 1920);
Camera.CameraBuilder cameraBuilder = new Camera.CameraBuilder(getActivity())
.useDefaultConfig()
.setPreviewSize(new Size(2048, 1536))
.setRecordingHint(true)
.setFocusMode(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
VideoRecorder.Builder builder = new VideoRecorder.Builder(cameraPreview)
.setCallbackHandler(new CallbackHandler())
.setLogFPSEnable(false)
.setCameraBuilder(cameraBuilder)
.setOutPutPath(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), File.separator + "VideoRecorder").getAbsolutePath())
.setFrameRate(30)
.setChannelCount(1);
MultiPartRecorder.Builder multiBuilder = new MultiPartRecorder.Builder(builder);
mRecorder = multiBuilder
.addPartListener(new MultiPartRecorder.VideoPartListener() {
@Override
public void onRecordVideoPartStarted(MultiPartRecorder.Part part) {
// LogUtil.logd("onRecordVideoPartStarted \t" + part.toString());
}
@Override
public void onRecordVideoPartSuccess(MultiPartRecorder.Part part) {
// LogUtil.logd("onRecordVideoPartSuccess \t" + part.toString());
}
@Override
public void onRecordVideoPartFailure(MultiPartRecorder.Part part) {
LogUtil.loge("onRecordVideoPartFailure \t" + part.file);
mRecorderIndicator.removePart(part.file.getAbsolutePath());
mRecorder.removePart(part.file.getAbsolutePath());
}
})
.setMergeListener(new MultiPartRecorder.VideoMergeListener() {
@Override
public void onStart() {
LogUtil.logd("merge onStart");
}
@Override
public void onSuccess(File outFile) {
LogUtil.logd("merge Success \t" + outFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(getContext().getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", outFile), "video/*");
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
intent.setDataAndType(Uri.fromFile(outFile), "video/*");
}
startActivity(intent);
}
@Override
public void onError(Exception e) {
LogUtil.logd("merge Error \t" + e.toString());
}
/**
* 合并进度
*
* @param value 0 - 1
*/
@Override
public void onProgress(float value) {
LogUtil.logd("merge onProgress \t" + value);
}
})
.setFileFilter(new MultiPartRecorder.FileFilter() {
@Override
public boolean filter(MultiPartRecorder.Part part) {
return part.duration > 1500;
}
})
.build();
mCameraController = mRecorder.getCameraController();
}
你可以尝试放到service里面 , 应该是可以的
I guess we need to use two SurfaceTexture at the same time one is used for preview (to show unchanged frames on user's display) another is used for recording which can be used in service (background recording)
when activity becomes invisible we should stop to draw unchanged frames on the first SurfaceTexture for preview but we should continue to draw frames on the second SurfaceTexture for video recording
@anonym24 你或许可以尝试一下 android.view.TextureView#setSurfaceTexture , 自己创建SurfaceTexture , 然后设置到TextureView 我不确定可不可以
I also want to try with Camera2 API, it has great feature - addTarget: https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java#L689
Legacy Camera doesn't allow to use setPreviewTexture and setPreviewDisplay at the same time, but it seems Camera2 allows something like this, you can set many targets, but I'm not sure, need to test it
你试试修改OffscreenCameraPreview getSurface 方法 , 让他返回自己创建的SurfaceTexture 参考 ,com.erlei.videorecorder.recorder.CameraGLRenderer#initSurfaceTexture
然后在 onSurfaceTextureDestroyed retrun false , 让活动销毁时不销毁SurfaceTexture , 一直保存这个 SurfaceTexture
Seems Camera2 isn't good (many phone manufactures didn't care about this API) - https://stackoverflow.com/questions/52374888/camera2-1440x1080-is-maximum
Though it was good to set two SurfaceTexture
for preview targets, I set one from your RenderThread
and another from TextureView
and it was working ok but this issue with bad resolution spoiled everything
So I will try to use what we have with Legacy Camera...
yes onSurfaceTextureDestroyed return false
worked nice, thanks
to draw frame without effects on preview and with effects on mediacodec surface (during video recording) I modified CameraGLRenderer's onDrawFrame
method, now it takes one boolean to set if draw with effects or not
We can do it with FFmpeg and just encode bytes from onPreviewFrame With FFmpeg it's easy because we don't work with SurfaceView and other stuff which works only for Activity So we can easily set onPreviewFrame for Camera in service (of course initially we create Camera in Activity but when we go background we start Service and pass object of Camera to that Service and just continue using onPreviewFrame callback for recording bytes in Service)