使用MediaRecorder录制视频文件
Android 模拟器无法录制音频。
生命周期
首先需要通过ActivityCompat.requestPermissions()来赋予赋予两个权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
使用MediaRecorder录制音频的步骤通常如下:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setOutputFile(PATH_NAME);
recorder.prepare();
recorder.start(); // Recording is now started
...
recorder.stop();
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release(); // Now the object cannot be reused
// 记得释放摄像头的资源
Code
Android MediaRecorder录制视频详细步骤_APDL_10的博客-CSDN博客
GitHub - android/media-samples at master
这个里面有很多demo例子
其中这些代码的书写方式真的很有意思,给人的感觉很好,值得学习。
点击录制按钮后,根据当前状态判断进入录制状态还是结束录制
因为录制需要先prepare,再start,所以提先去prepare子方法中进入相关的初始化配置,之后根据prepare的返回值来决定是否start(这两个步骤是通过async来执行)
如果进入结束就释放资源。
在设置音频和视频的编码器、输出格式、比特率等一系列参数其实可以采用setProfile的方法来设置,不用一个个来设置。
public class MediaRecorderActivity extends AppCompatActivity {
private static final String TAG = "MediaRecorderActivity";
private Camera mCamera;
private SurfaceView mPreview;
private MediaRecorder mMediaRecorder;
private File mOutputFile;
private boolean isRecording = false;
private Button captureButton;
public static Intent newIntent(Context packageContext) {
Intent intent = new Intent(packageContext, MediaRecorderActivity.class);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_recorder);
mPreview = findViewById(R.id.afv_media_recorder);
captureButton = findViewById(R.id.btn_media_recorder_capture);
}
/**
* The capture button controls all user interaction. When recording, the button click
* stops recording, releases {@link android.media.MediaRecorder} and
* {@link android.hardware.Camera}. When not recording, it prepares the
* {@link android.media.MediaRecorder} and starts recording.
*
* @param view the view generating the event.
*/
public void onCaptureClick(View view) {
if (isRecording) {
// BEGIN_INCLUDE(stop_release_media_recorder)
// stop recording and release camera
try {
mMediaRecorder.stop(); // stop the recording
} catch (RuntimeException e) {
// RuntimeException is thrown when stop() is called immediately after start().
// In this case the output file is not properly constructed ans should be deleted.
Log.d(TAG, "RuntimeException: stop() is called immediately after start()");
//noinspection ResultOfMethodCallIgnored
mOutputFile.delete();
}
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
setCaptureButtonText("Capture");
isRecording = false;
releaseCamera();
// END_INCLUDE(stop_release_media_recorder)
} else {
// BEGIN_INCLUDE(prepare_start_media_recorder)
new MediaPrepareTask().execute(null, null, null);
// END_INCLUDE(prepare_start_media_recorder)
}
}
private void setCaptureButtonText(String title) {
captureButton.setText(title);
}
@Override
protected void onPause() {
super.onPause();
// if we are using MediaRecorder, release it first
releaseMediaRecorder();
// release the camera immediately on pause event
releaseCamera();
}
private void releaseMediaRecorder() {
if (mMediaRecorder != null) {
// clear recorder configuration
mMediaRecorder.reset();
// release the recorder object
mMediaRecorder.release();
mMediaRecorder = null;
// Lock camera for later use i.e taking it back from MediaRecorder.
// MediaRecorder doesn't need it anymore and we will release it if the activity pauses.
mCamera.lock();
}
}
private void releaseCamera() {
if (mCamera != null) {
// release the camera for other applications
mCamera.release();
mCamera = null;
}
}
private boolean prepareVideoRecorder() {
//1.创建recorder对象
mMediaRecorder = new MediaRecorder();
//2.设置录制视频的方向
mCamera = Camera.open();//摄像头对象
mCamera.setDisplayOrientation(90);//将摄像头预览的角度进行调整
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
//3.设置音频源(MIC:麦克风采集音频)
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//4.设置视频源(CAMERA:摄像头采集视频)
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//5.设置视频输出格式(MP4)
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//6.设置音频编码格式
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//7.设置视频编码格式
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//8.设置视频播放的方向
mMediaRecorder.setOrientationHint(90);
//9.设置输出文件的位置
// Step 4: Set output file
mOutputFile = CameraHelper.getOutputMediaFile(CameraHelper.MEDIA_TYPE_VIDEO);
if (mOutputFile == null) {
return false;
}
mMediaRecorder.setOutputFile(mOutputFile.getPath());
// END_INCLUDE (configure_media_recorder)
//10.设置输出视频的大小
mMediaRecorder.setVideoSize(640,480);
//11.设置视频的帧率
mMediaRecorder.setVideoFrameRate(30);
//12.设置预览界面(设置一个Surface,也就是预览的页面,然后交给)
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 5: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
/**
* Asynchronous task for preparing the {@link android.media.MediaRecorder} since it's a long blocking
* operation.
*/
class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
MediaRecorderActivity.this.finish();
}
// inform the user that recording has started
setCaptureButtonText("Stop");
}
}
}