마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

카메라 전면과, 녹화 화면 돌리는 방법좀...

0 추천
public class MainActivity extends Activity {
 
        public static final String TAG = "SampleVideoRecoder";  

        //외부 저장 장치 경로를 저장할 변수
        private static String EXTERNAL_STORAGE_PATH = "";
        
        //파일명을 저장하기 위한 변수
        private static String RECORDED_FILE = "video_recorded";
        private static String filename = "";
        
        //오디오나 비디오를 재생하기 위한 클래스의 변수
        MediaPlayer player;
        
        //오디오나 비디오를 녹화하기 위한 클래스의 변수
        MediaRecorder recorder;
        
        //카메라 클래스의 변수
        private Camera camera = null;  //하드웨어로 끝나는거 import해라.

        
        //비디오 재생할 때 사용할 뷰 변수
        //비디오를 재생하는 화면을 VideoView를 사용하지 않고 만들 때는 반드시
        //SurfaceHolder 객체를 생성해서 재생해야 한다.
        //VideoView 객체를 이용해서 Video를 재생할 때는 없어도 된다.
        SurfaceHolder holder;
        
        
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            

            //외부 저장장치 연결 여부를 확인.
            String state = Environment.getExternalStorageState();
            
            //외부 저장장치가 마운트 되지 않았다면.(연결되지 않았다면)
            if(!state.equals(Environment.MEDIA_MOUNTED)){
                Log.d(TAG, "SD Card not connected"); //로그 찍고 나가.
            }
            else{
                //외부 저장 장치 경로 설정.
                this.EXTERNAL_STORAGE_PATH =
                                        Environment.getExternalStorageDirectory().getAbsolutePath();
            }
                          
            
            //비디오를 일반 뷰에서 재생하기 위해서 SurfaceHolder 생성
            SurfaceView surface = new SurfaceView(this);
            holder = surface.getHolder();
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            
            
            //비디오를 재생할 영역에 SurfaceVuew 배치.
            FrameLayout frame = (FrameLayout)findViewById(R.id.videoLayout);
            frame.addView(surface);
            
            
            //4개의 버튼 가져오기.
            Button recordBtn = (Button)findViewById(R.id.recordBtn);
            Button recordStopBtn = (Button)findViewById(R.id.recordStopBtn);
            Button playBtn  = (Button)findViewById(R.id.playBtn);
            Button playStopBtn = (Button)findViewById(R.id.playStopBtn);
            
            //recordBtn의 클릭 이벤트 처리
            //비디오 녹화를 시작
            

            recordBtn.setOnClickListener(new View.OnClickListener() {
                
                @Override
                public void onClick(View v) {
                        try{
                            //녹화할 수 있는 객체가 없으면 생성.
                                if(recorder == null){
                                    recorder = new MediaRecorder();

                                }
                                
                                
                                camera = Camera.open();      // 카메라 오픈
                                  Camera.Parameters parameters =
                                           camera.getParameters();  // 카메라 파라미터 변수 가져오기
                                   parameters.set("camera-id", 2);     // 전방 카메라 사용하기 설정
                                //녹화 옵션 설정
                                recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                                recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                                //출력 포맷 설정.
                                recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                                
                                //인코딩 방식 설정.
                                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
                                
                                recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
                        
                            
                                //출력할 파일 이름을 설정하기 위한 메서드를 호출해서 파일 이름 결정
                                filename = createFilename();
                                
                                
                                
                                //출력 파일 이름 설정
                                recorder.setOutputFile(filename);
                                
                                //미리보기 화면을 생성하고 준비한 후 녹화 시작
                                recorder.setPreviewDisplay(holder.getSurface());
                                recorder.prepare();
                                recorder.start();
                                
                                
                                
                        }
                        catch(Exception e){
                            Log.d("TAG", "Recorder Exception :" + e.getMessage());
                            
                        }
                    
                    
                }

        
                    
            });
         
                      
            //녹화 중지 버튼을 누를 때의 이벤트 처리
            //실제 파일로 저장
            recordStopBtn.setOnClickListener(new View.OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    //녹화 중이 아니라면 리턴
                        if(recorder == null)
                            return;
                        //녹화를 중지하고 자원 회수
                        recorder.stop();
                        recorder.reset();
                        recorder.release();
                        recorder = null;
                        
                        //비디오 파일 저장에 사용할 정보를 저장할 맵을 생성.
                        //안드로이드에서는 일반 해시 맵을 사용하는 것이 아니고 맵을 이용해서
                        //만든 ContentValues를 맵으로 사용한다.   상식.
                        ContentValues values = new ContentValues();
                        values.put(MediaStore.MediaColumns.TITLE, "RecordedVideo");
                        values.put(MediaStore.Audio.Media.ALBUM, "Video Album");
                        values.put(MediaStore.Audio.Media.ARTIST, "Park");
                        values.put(MediaStore.Audio.Media.DISPLAY_NAME, "RecordedVideo");
                        values.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis()/1000);
                        //파일의 특성 저장 - 이 특성으로 인해 파일을 재생할 때 사용하는 프로그램이나
                        //출력할 때의 형식이 설정된다.
                        //웹에서 출력할 때 사용하는 content-type과 유사.
                        values.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
                        //저장할 파일 설정.
                        values.put(MediaStore.Audio.Media.DATA, filename);
                        
                        
                        //실제 저장하고 저장한 곳의 주소를 videoUri에 저장.
                        Uri videoUri = getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
                        
                        
                }
            });
             

여러가지 검색해보면서 고쳐보고 해봤지만. 잘안되네요.. 화면도 돌려야되는데 몇가지 찾아서 적용해보니깐. . 녹화할땐 회전되어있고, 녹화된 파일을 재생해보니깐. 제대로 나오더군요..ㅠㅠ 녹화할때도... 제대로 됬으면 좋겠는데 잘안되네요..

또 전면으로 녹화해야되는데... api를 찾고 공부도 해보고있는데 적용도 잘안되고... 적용이되도 검은 화면만 보이네요... 3일째 헤메고있습니다.... 조언좀 해주시면 감사하겠습니다.
익명사용자 님이 2016년 4월 15일 질문

1개의 답변

0 추천
 
채택된 답변

1. 카메라 변경 

public static Camera open (int cameraId) 에 들어가는 int cameraId를 통해 카메라를 선택할 수 있습니다.

cameraId 는 다음과 같이 설명 되어 있습니다.

   int: the hardware camera to access, between 0 and getNumberOfCameras()-1.

즉 아래 코드에서 cameraCount가 2일 경우 Camera.open(1); 같은걸 주면 다른 카메라를 사용할  수 있습니다.

        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras(); 

2. 안드로이드에서 녹화하면 rotate 정보가 container에 추가로 들어갈 뿐, 영상 자체가 회전되서 녹화 되는 것은 아니라서 변경이 불가능한 사항입니다. 

정 회전된 영상을 녹화 하려면 

카메라데이터를 구해(onPreviewCallback) -> 회전-> H264로 인코딩-> 파일 생성의 과정을 별도로 해 주어야하는데,

구현도 어렵고, 연산속도도 맞춰주기가 쉽지 않으니. 무리해서 개발하실 필요가 있는지는 의문이며,

회전 정보를 주는 법은

A. 하나의 모드로 고정.
http://blog.naver.com/PostView.nhn?blogId=visualc98&logNo=68166910

B. setDisplayOrientation 사용 
http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)

(단, 여기서 view 를 생성할 때 activity 객체를 받아와야 합니다)


int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result  = (90 - degrees + 360) % 360;
camera.setDisplayOrientation(result);

 

 

  

사악미소 (65,330 포인트) 님이 2016년 4월 15일 답변
사악미소님이 2016년 4월 15일 수정
...