- WRITE_EXTERNAL_STORAGE, RECORD_AUDIO 권한 필요.
1. 기본코드
- MediaRecorder
MediaRecorder mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(videoFile);
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
mediaRecorder.setVideoSize(displayMetrics.widthPixels, displayMetrics.heightPixels);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setVideoEncodingBitRate(512 * 1000);
mediaRecorder.setVideoFrameRate(30);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
- MediaProjection
final MediaRecorder screenRecorder = createRecorder();
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
MediaProjection.Callback callback = new MediaProjection.Callback() {
@Override
public void onStop() {
super.onStop();
if (screenRecorder != null) {
screenRecorder.stop();
screenRecorder.reset();
screenRecorder.release();
}
mediaProjection.unregisterCallback(this);
mediaProjection = null;
}
};
mediaProjection.registerCallback(callback, null);
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
mediaProjection.createVirtualDisplay(
"sample",
displayMetrics.widthPixels, displayMetrics.heightPixels, displayMetrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
screenRecorder.getSurface(), null, null);
screenRecorder.start();
> createVirtualDisplay 과정에서 MediaRecorder의 Surface를 가져와 버추얼 디스플레이로 녹화를 한다.
> 녹화를 위해서 오디오와 저장소 사용 권한을 허용해야 한다.
- 전체코드
public class MainActivity extends AppCompatActivity {
private static final String videoFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/MediaProjection.mp4";
private static final int REQUEST_CODE_PERMISSIONS = 100;
private static final int REQUEST_CODE_MediaProjection = 101;
private MediaProjection mediaProjection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 퍼미션 확인
checkSelfPermission();
}
@Override
protected void onDestroy() {
// 녹화중이면 종료하기
if (mediaProjection != null) {
mediaProjection.stop();
}
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, final int resultCode, @Nullable final Intent data) {
// 미디어 프로젝션 응답
if (requestCode == REQUEST_CODE_MediaProjection && resultCode == RESULT_OK) {
screenRecorder(resultCode, data);
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 음성녹음, 저장소 퍼미션
*
* @return
*/
public boolean checkSelfPermission() {
String temp = "";
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
temp += Manifest.permission.RECORD_AUDIO + " ";
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
temp += Manifest.permission.WRITE_EXTERNAL_STORAGE + " ";
}
if (TextUtils.isEmpty(temp) == false) {
ActivityCompat.requestPermissions(this, temp.trim().split(" "), REQUEST_CODE_PERMISSIONS);
return false;
} else {
initView();
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_PERMISSIONS: {
int length = permissions.length;
for (int i = 0; i < length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
// 퍼미션 동의가 1개라도 부족하면 화면을 초기화 하지 않음
return;
}
initView();
}
return;
}
default:
return;
}
}
/**
* 뷰 초기화
*/
private void initView() {
findViewById(R.id.actionRec).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 미디어 프로젝션 요청
startMediaProjection();
}
});
}
/**
* 화면녹화
*
* @param resultCode
* @param data
*/
private void screenRecorder(int resultCode, @Nullable Intent data) {
final MediaRecorder screenRecorder = createRecorder();
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
MediaProjection.Callback callback = new MediaProjection.Callback() {
@Override
public void onStop() {
super.onStop();
if (screenRecorder != null) {
screenRecorder.stop();
screenRecorder.reset();
screenRecorder.release();
}
mediaProjection.unregisterCallback(this);
mediaProjection = null;
}
};
mediaProjection.registerCallback(callback, null);
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
mediaProjection.createVirtualDisplay(
"sample",
displayMetrics.widthPixels, displayMetrics.heightPixels, displayMetrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
screenRecorder.getSurface(), null, null);
final Button actionRec = findViewById(R.id.actionRec);
actionRec.setText("STOP REC");
actionRec.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
actionRec.setText("START REC");
if (mediaProjection != null) {
mediaProjection.stop();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(videoFile), "video/mp4");
startActivity(intent);
}
}
});
screenRecorder.start();
}
/**
* 미디어 프로젝션 요청
*/
private void startMediaProjection() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE_MediaProjection);
}
}
/**
* 미디어 레코더
*
* @return
*/
private MediaRecorder createRecorder() {
MediaRecorder mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(videoFile);
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
mediaRecorder.setVideoSize(displayMetrics.widthPixels, displayMetrics.heightPixels);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setVideoEncodingBitRate(512 * 1000);
mediaRecorder.setVideoFrameRate(30);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
return mediaRecorder;
}
}
2. 샘플코드
소스코드
APK
작성자가 댓글을 삭제했습니다.
답글삭제작성자가 댓글을 삭제했습니다.
삭제안녕하세요? 좋은 자료 감사합니다. 혹시 ,파일을 재생할 수 없습니다. Windows Media Player에서 해당 파일 형식을 지원하지 않거나 파일을 압축하는 데 사용된 코덱을 지원하지 않을 수 있습니다. 이런 에러가 나오는데 도움을 주실수있을까요?
답글삭제핸드폰에서도 영상이 실행되지않습니다