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

surface view 화면 캡처 질문입니다.

0 추천

검색을 해보니 많은 분들이 겪어본 문제이고 많이 어려운 문제인 것 같습니다... 

 

<span style="font-size:12px">public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
 
    private static String EXTERNAL_STORAGE_PATH = "";
    private static String RECORDED_FILE = "video_recorded";
    private static int fileIndex = 0;
    private static String filename = "";
    MediaPlayer player;
    MediaRecorder recorder;
    private Camera camera;
    SurfaceHolder holder;
    Handler handler;             // 영상 캡쳐 핸들러
    boolean bRecord = false;   // 영상 녹화 상태 확인
    SurfaceView surface;
 
    @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, "External Storage Media is not mounted.");
        } else {
            EXTERNAL_STORAGE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
        }
 
        camera = Camera.open();
        // create a SurfaceView instance and add it to the layout
        surface = new SurfaceView(this);
 
        holder = surface.getHolder();
        holder.addCallback((SurfaceHolder.Callback) this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 
 
 
        frame = (FrameLayout) findViewById(R.id.videoLayout);
        frame.addView(surface);
 
        // Button ID
        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.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                try {
                    if (recorder == null) {
                        recorder = new MediaRecorder();
                    }
                    bRecord = true;
                     
                    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                    recorder.setVideoFrameRate(25);
                    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
                  
 
                    filename = createFilename();
                    recorder.setOutputFile(filename);
 
                    recorder.setPreviewDisplay(holder.getSurface());
 
                    handler = new Handler();
                    handler.postDelayed(new RunnableCapture(), 5000);
 
                    recorder.prepare();
                    recorder.start();
 
                } catch (Exception ex) {
                    Log.e(TAG, "Exception : ", ex);
                    recorder.release();
                    recorder = null;
                }
            }
        });
 
        // 녹화 중지
        recordStopBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (recorder == null)
                    return;
                bRecord = false;
                recorder.stop();
                recorder.reset();
                recorder.release();
                recorder = null;
 
                ContentValues values = new ContentValues(10);
 
                values.put(MediaStore.MediaColumns.TITLE, "RecordedVideo");
                values.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
                values.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
 
                Uri videoUri = getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
                if (videoUri == null) {
                    Log.d("SampleVideoRecorder", "Video insert failed.");
                    return;
                }
 
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, videoUri));
 
            }
        });
 
    // 파일 이름.
    private String createFilename() {
        fileIndex++;
 
        String newFilename = "";
        if (EXTERNAL_STORAGE_PATH == null || EXTERNAL_STORAGE_PATH.equals("")) {
            // use internal memory
            newFilename = RECORDED_FILE + fileIndex + ".mp4";
        } else {
            newFilename = EXTERNAL_STORAGE_PATH + "/" + RECORDED_FILE + fileIndex + ".mp4";
        }
 
        return newFilename;
    }
 
 
    protected void onPause() {
        if (camera != null) {
            camera.release();
            camera = null;
        }
 
        if (recorder != null) {
            recorder.release();
            recorder = null;
        }
 
        if (player != null) {
            player.release();
            player = null;
        }
 
        super.onPause();
    }
 
    // 이미지 캡쳐 핸들러 함수.
    private class RunnableCapture implements Runnable {
        @Override
        public void run() {
            int width_frame = surface.getWidth();     // 캡쳐 당할 레이아웃 크기
            int height_frame = surface.getHeight();
 
            surface.setDrawingCacheEnabled(true);
            surface.buildDrawingCache(true);
            /************핵심 *************/
            Bitmap captureView = Bitmap.createBitmap(surface.getMeasuredWidth(), surface.getMeasuredHeight(), Bitmap.Config.ARGB_8888 );
            Canvas screenShootCanvas = new Canvas(captureView);
 
            surface.draw(screenShootCanvas);
  
            FileOutputStream fos;
            // 현재 날짜로 파일 저장하기
            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
            //년월일시분초
            Date currentTime_1 = new Date();
            String filename = formatter.format(currentTime_1);
 
            File fileRoute = null;
            fileRoute = Environment.getExternalStorageDirectory();
 
            try{
                File path = new File(fileRoute, "temp");
                if(!path.exists()){
                    path.mkdirs();
                }
                fos = new FileOutputStream(fileRoute+"/temp/"+filename+".jpeg");
                captureView.compress(Bitmap.CompressFormat.JPEG, 100, fos);
 
                surface.setDrawingCacheEnabled(false);
 
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            Toast.makeText(MainActivity.this, "save image", Toast.LENGTH_SHORT).show();
            if (bRecord) { // 아직도 녹화중이라면 캡쳐를 진행한다.
                handler.postDelayed(this, 5000);
            }
        }
    }
}</span>

동영상이 녹화되는 동안 5초 간격으로 화면 캡처를 하고 싶습니다. 

surface view를 강제로 canvas로 바꾼 다음 실행하면 된다고 하는데.. .

다른 분들 소스랑 너무 달라서 어떻게 바꿔야 하는지 도통 감이 안 오네요 ㅠㅠ

제발 살려주세요 ㅠㅠ

khseob0715 (140 포인트) 님이 2017년 10월 29일 질문

1개의 답변

0 추천
녹화중이라. SurfaceView 속성을 바꾸는건 위험할 듯 합니다.

Camera API에서 사용하는 preview Callback을 사용해서 구하시는게 좋을 듯 합니다.

https://stackoverflow.com/questions/6743768/android-camera-preview-callback-and-mediarecorder-record-video

https://stackoverflow.com/questions/6743768/android-camera-preview-callback-and-mediarecorder-record-video
익명사용자 님이 2017년 10월 30일 답변
...