MediaRecorder 保存与 SurfaceView 大小相同的视频
Posted
技术标签:
【中文标题】MediaRecorder 保存与 SurfaceView 大小相同的视频【英文标题】:MediaRecorder saving video the same size as the SurfaceView 【发布时间】:2017-02-03 01:03:21 【问题描述】:您好,我正在尝试在我的应用中实现录制。我可以录制视频并保存,但宽高比和分辨率完全搞砸了。我怎样才能知道以可用的最高质量注册?
这是我的代码
public class VideoFragment extends Fragment implements SurfaceHolder.Callback
private ToggleButton mToggleButton;
private SurfaceHolder mHolder;
private SurfaceView mSurfaceView;
private MediaRecorder mMediaRecorder;
private Camera mCamera;
private boolean mInitSuccesful;
public static VideoFragment newInstance()
Bundle args = new Bundle();
VideoFragment fragment = new VideoFragment();
fragment.setArguments(args);
return fragment;
public VideoFragment()
@Override
public void onStart()
super.onStart();
getActivity().setTitle(R.string.video);
@Override
public void onResume()
super.onResume();
@Override
public void onPause()
super.onPause();
shutdown();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_content, container, false);
Button yo = (Button) rootView.findViewById(R.id.pic);
yo.setVisibility(View.GONE);
mSurfaceView = (SurfaceView) rootView.findViewById(R.id.cameraView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mToggleButton = (ToggleButton) rootView.findViewById(R.id.toggleRecordingButton);
mToggleButton.setOnClickListener(new View.OnClickListener()
@Override
// toggle video recording
public void onClick(View v)
if (((ToggleButton)v).isChecked())
if(mMediaRecorder == null)
try
initRecorder(mHolder.getSurface());
catch (IOException e)
e.printStackTrace();
else
try
mMediaRecorder.start();
catch (NullPointerException e)
e.printStackTrace();
try
initRecorder(mHolder.getSurface());
catch (IOException ex)
ex.printStackTrace();
else
mMediaRecorder.stop();
mMediaRecorder.reset();
try
initRecorder(mHolder.getSurface());
catch (IOException e)
e.printStackTrace();
);
return rootView;
/* Init the MediaRecorder, the order the methods are called is vital to
* its correct functioning.
*/
private void initRecorder(Surface surface) throws IOException
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if(mCamera == null)
mCamera = Camera.open();
mCamera.unlock();
if(mMediaRecorder == null)
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setPreviewDisplay(surface);
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
File file = new File(Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Utils.getVideoFilename());
// "touch" the file
if(!file.exists())
File parent = file.getParentFile();
if(parent != null)
if(!parent.exists())
if(!parent.mkdirs())
throw new IOException("Cannot create " +
"parent directories for file: " + file);
file.createNewFile();
mMediaRecorder.setOutputFile(file.getAbsolutePath());
// No limit. Don't forget to check the space on disk.
mMediaRecorder.setMaxDuration(-1);
mMediaRecorder.setVideoFrameRate(15);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
try
mMediaRecorder.prepare();
catch (IllegalStateException e)
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
mInitSuccesful = true;
@Override
public void surfaceCreated(SurfaceHolder holder)
try
if(!mInitSuccesful)
initRecorder(mHolder.getSurface());
catch (IOException e)
e.printStackTrace();
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2)
@Override
public void surfaceDestroyed(SurfaceHolder holder)
shutdown();
private void shutdown()
// Release MediaRecorder and especially the Camera as it's a shared
// object that can be used by other applications
mMediaRecorder.reset();
mMediaRecorder.release();
mCamera.release();
// once the objects have been released they can't be reused
mMediaRecorder = null;
mCamera = null;
谢谢
编辑: 解决方案感谢接受的答案
CamcorderProfile cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mMediaRecorder.setProfile(cpHigh);
【问题讨论】:
【参考方案1】:先尝试使用CamcorderProfile 设置所有MediaRecorder 分辨率和质量设置;您当前没有设置许多值,例如大小。一方面,MediaRecorder 不会关注 SurfaceView 的尺寸。
【讨论】:
以上是关于MediaRecorder 保存与 SurfaceView 大小相同的视频的主要内容,如果未能解决你的问题,请参考以下文章
Android 10 源码MediaRecorder 录像流程:MediaRecorder 配置
将Surface保存到位图并在C#中优化DirectX屏幕捕获