안드로이드 앱 만들기
Media Recorder
khon98
2020. 8. 22. 20:21
SurfaceView - 카메라 관련 기능들은 SurfaceView로 구현 함
--------------------------------------------------
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="녹화시작"/>
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
--------------------------------------------------
--------------------------------------------------
MainActivity.java
package com.example.videorecord;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.gun0912.tedpermission.PermissionListener;
import com.gun0912.tedpermission.TedPermission;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private Camera camera;
private MediaRecorder mediaRecorder;
private Button btn_record;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private boolean recording = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TedPermission.with(this)
.setPermissionListener(permissionListener)
.setRationaleMessage("녹화를 위하여 권한을 혀용해주세요")
.setDeniedMessage("권한이 거부되었습니다. 설정 > 권한에서 허용해주세요")
.setPermissions(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO)
.check();
btn_record = (Button)findViewById(R.id.btn_record);
btn_record.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (recording) {
mediaRecorder.stop();
mediaRecorder.release();
camera.lock();
recording = false;
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "녹화가 시작되었습니다", Toast.LENGTH_SHORT).show();
try {
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
mediaRecorder.setOrientationHint(90); // 촬영 각도
mediaRecorder.setOutputFile("/sdcard/test.mp4");
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.prepare();
mediaRecorder.start();
recording = true;
} catch (Exception e) {
e.printStackTrace();
mediaRecorder.release();
}
}
});
}
}
});
}
PermissionListener permissionListener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "권한 허가", Toast.LENGTH_SHORT).show();
camera = Camera.open();
camera.setDisplayOrientation(90);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(MainActivity.this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "권한 거부", Toast.LENGTH_SHORT).show();
}
};
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
}
private void refreshCamera(Camera camera) {
if (surfaceHolder.getSurface() == null) {
return;
}
try {
camera.stopPreview();
}catch (Exception e) {
e.printStackTrace();
}
setCamera(camera);
}
private void setCamera(Camera cam) {
camera = cam;
}
// surfaceView를 선언했을때 surfaceView 처음으로 생성 됐을때 생명주기
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
refreshCamera(camera);
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
}
--------------------------------------------------
--------------------------------------------------
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.videorecord">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
android:requestLegacyExternalStorage="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
--------------------------------------------------
--------------------------------------------------
build.gradle (:app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "30.0.1"
defaultConfig {
applicationId "com.example.videorecord"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'gun0912.ted:tedpermission:2.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}