如何从onPreviewFrame()接收的字节数组制作视频

时间:2014-09-29 10:54:59

标签: android android-camera android-mediarecorder

我能够从onPreviewFrame()以字节数组的形式获取视频帧数据。我需要从这个字节数组中制作一个视频。 以下是我的代码段:

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

    try {
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "MyCameraApp");

        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d("MyCameraApp", "failed to create directory");
            }
        }

        FileOutputStream out = new FileOutputStream(mediaStorageDir.getAbsolutePath() + "video.mp4");
        out.write(data);
        out.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

结果文件" video.mp4"是不可玩的。

我们将非常感谢您解决问题的任何帮助或指导。

注意 我的应用程序将支持Android 4+版本。

1 个答案:

答案 0 :(得分:-1)

这里是拍照和拍摄的代码。视频

    // Add listener to video capture button
    VideoCapture = (Button)findViewById(R.id.buttonVideo);
    VideoCapture.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
                captureButton.setVisibility(View.GONE);
            if(isRecording){
                VideoCapture.setBackgroundResource(R.drawable.ic_action_videoplay); 
                   // stop recording and release camera
                mMediaRecorder.stop();  // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object
                mCamera.lock();         // take camera access back from MediaRecorder

                // inform the user that recording has stopped

                isRecording = false;
            }
            else{
                releaseCamera();
                 // initialize video camera
                if (prepareVideoRecorder()) {
                    // Camera is available and unlocked, MediaRecorder is prepared,
                    // now you can start recording
                    mMediaRecorder.start();

                    // inform the user that recording has started

                    isRecording = true;
                } else {
                    // prepare didn't work, release the camera
                    releaseMediaRecorder();
                    // inform user
                }

                VideoCapture.setBackgroundResource(R.drawable.ic_launcher_videopause);
                isRecording = true;
            }

        }

    });

    private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: ");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();

            /* set image preview in imageview */
            previewImage = (ImageView)findViewById(R.id.imageViewPrieview);
            previewImage.setImageURI(Uri.fromFile(pictureFile));

            /* release camera & removeallview from preview */
            relaese();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};



/** Create a file Uri for saving an image or video */
private Uri getOutputMediaFileUri(int type){
    return Uri.fromFile(getOutputMediaFile(type));
}

/** Create a File for saving an image or video */
private File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), "MyCameraApp");
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

    if (type == MEDIA_TYPE_IMAGE){
        //                  mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        //                  "IMG_"+ timeStamp + ".jpg");
        mediaFile = new File("/sdcard/"+ "IMG_"+ timeStamp + ".jpg");
        Log.i("Image","Image is captured");

    } else if(type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "VID_"+ timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}

这些准备录像机的代码

 private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();


    // step 1: Unlock camera & Set camera to MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // step 2: set Audio & Video Source
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // step 3: set camcorder profile , it required Api Level 8
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // step 4: set output file
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // step 5: set preview output
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // step 6: prepare Configured Media recorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d("TAG","IllegalStateException preparing MediaRecorder" + e.getMessage());
        return false;
    }catch (IOException e) {
        Log.d("TAG","IO Exception preparing MediaRecorde" + e.getMessage());
        return false;

    }
    return true;
}
private void releaseMediaRecorder(){
    if (mMediaRecorder != null) {
        mMediaRecorder.reset();   // clear recorder configuration
        mMediaRecorder.release(); // release the recorder object
        mMediaRecorder = null;
        mCamera.lock();           // lock camera for later use
    }

我认为这会对你有所帮助。因为它适合我。

Android API目前不提供暂停方法

这有点技术性,但是在评论中征求了意见。

从API级别1开始使用的public class MediaRecorder无法暂停,正如可以从MediaRecorder状态图中看到的那样:

MediaRecorder State Diagram

录制时,API允许我们使用reset()stop()公开方法:

  

reset() - >将MediaRecorder重新启动到空闲状态。

     

stop() - >停止录制。