安卓preVIEW处理,而视频录制 [英] Android preview processing while video recording

查看:133
本文介绍了安卓preVIEW处理,而视频录制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始在Android DEVELOPPEMENT(SDK 2.2),我想使一个视频录制与mediaRecorder,并在同一时间,使每个preVIEW帧中的某些过程。

我纪录MediaRecorder视频中的一个项目,在其他的我用的是上previewFrame(byte []的数据,摄像机镜头)(由previewCallback)进行处理preVIEW图片。

我已经尝试创建一个摄像头,并使用它与mediaRecorder(setCamera功能),但它不工作,我无法找到例子有我想要的。

修改的是否有可能在同一时间一举两得? 修改的其实我不知道如何连接两件事情?

在此先感谢您的帮助,

鲍勃·

我的code:

 包ch.fraise;

进口java.io.IOException异常;
进口android.app.Activity;
进口android.hardware.Camera;
进口android.hardware.Camera previewCallback。
进口android.media.MediaRecorder;
进口android.os.Bundle;
进口android.util.Log;
进口android.view.Menu;
进口android.view.MenuInflater;
进口android.view.MenuItem;
进口android.view.SurfaceHolder;
进口android.view.SurfaceView;

公共类CameraActivity扩展活动实现SurfaceHolder.Callback,
    Camera.AutoFocusCallback {

私人SurfaceView preVIEW;
私人SurfaceHolder previewHolder;

私人MediaRecorder mRecorder;
私人相机mCamera;
私人布尔米previewRunning = FALSE;
私人布尔mCaptureFrame = FALSE;

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    Log.e(,开始的onCreate);
    的setContentView(R.layout.main);

    preVIEW =(SurfaceView)findViewById(R.id.surfaceView1);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(本);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    mRecorder =新MediaRecorder();
}

@覆盖
公共无效onResume(){
    super.onResume();
}

@覆盖
公共无效的onPause(){
    super.onPause();
}

@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    MenuInflater充气= getMenuInflater();
    inflater.inflate(R.menu.capture_menu,菜单);
    返回true;
}

公共无效的startRecording(){
    Log.e(,开始的StartRecording);
    mCaptureFrame =真;
    mRecorder.start();
}

公共无效STO precording(){
    Log.e(,开始StopChange);
    mRecorder.stop();
}

@覆盖
公共布尔onOptionsItemSelected(菜单项项){
    //处理项目选择
    开关(item.getItemId()){
    案例R.id.startRecording:
        的StartRecording();
        返回true;
    案例R.id.sto precording:
        STO precording();
        返回true;
    默认:
        返回super.onOptionsItemSelected(项目);
    }
}

@覆盖
公共无效surfaceCreated(SurfaceHolder持有者){
    Log.e(,开始surfaceDestroy);
    mCamera = Camera.open();
}

@覆盖
公共无效surfaceDestroyed(SurfaceHolder持有者){
    mCamera.stop preVIEW();
    米previewRunning = FALSE;
    mCamera.release();

    mRecorder.reset();
    mRecorder.release();
}

@覆盖
公共无效onAutoFocus(布尔成功,相机摄像头){
    // TODO自动生成方法存根

}

/ *
 * previewCallback()
 *
 *这个回调抓住了preVIEW在每一帧,并把它放在一个字节
 * 缓冲。我们会评估,如果这是我们要处理一个框架,
 *如果是这样,我们将其发送给一个异步线程,将它处理到
 *一个ARGB位图,并张贴到服务器
 * /
previewCallback previewCallback =新的previewCallback(){
    在previewFrame(byte []的数据,摄像头摄像头){公共无效
        (在previewFrame通,)Log.e;
        如果(mCaptureFrame){
            mCaptureFrame = FALSE;
            //新FrameHandler()执行(数据);
        }
    }
};

@覆盖
公共无效surfaceChanged(SurfaceHolder持有人,INT格式,诠释的宽度,
        INT高度){
    Log.e(,开始SurfaceChange);

    mRecorder.reset();
    mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mRecorder.setVideoEn codeR(MediaRecorder.VideoEn coder.MPEG_4_SP);
    mRecorder.setOutputFile(/ SD卡/ videotest2.mp4);
    mRecorder.setVideoFrameRate(30);

    mRecorder.set previewDisplay(previewHolder.getSurface());
    尝试 {
        mRecorder prepare()。
    }赶上(IllegalStateException异常E){
        e.printStackTrace();
    }赶上(IOException异常E){
        e.printStackTrace();
    }

    如果(M previewRunning)
        mCamera.stop preVIEW();

    Camera.Parameters p值= mCamera.getParameters();
    // P.SET previewSize(宽,高);
    mCamera.setParameters(对);

    尝试 {
        mCamera.set previewDisplay(保持器);
    }赶上(IOException异常E){
        e.printStackTrace();
    }

    mCamera.set previewCallback(previewCallback);

    mCamera.start preVIEW();
    米previewRunning = TRUE;

}

}
 

和在XML文件的权限:

 <使用-权限的Andr​​oid:名称=android.permission.CAMERA/>
<使用-权限的Andr​​oid:名称=android.permission.RECORD_AUDIO/>
<使用-权限的Andr​​oid:名称=android.permission.RECORD_VIDEO/>
<使用-权限的Andr​​oid:名称=android.permission.WRITE_EXTERNAL_STORAG​​E/>
 

解决方案

尤里卡!关键是要附上你的 previewCallback surfaceChanged(...) SurfaceHolder.Callback !这样做了以后,你会不断地得到MediaRecorder后preVIEW帧数据运行!

例如:

 公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
    mCamera.set previewCallback(新previewCallback(){
            在previewFrame(byte []的_data,摄像机_camera){公共无效
                Log.d(关于previewFrame-surfaceChanged的String.Format(GOT%d字节摄像头的数据,_data.length));
            }
        });

}
 

I begin on android developpement (SDK 2.2) and i would like to make a video recording with mediaRecorder and, in the same time, make some process on each preview frame.

I record video with MediaRecorder in a project, in an other i use the onPreviewFrame(byte[] data, Camera camera) (from PreviewCallback) for processing preview pictures.

i've try to create a Camera and use it with mediaRecorder (setCamera function) but it doesn't work and i can't find example with what i want.

edit Is it possible to do both in the same time? edit Actually i don't understand how to link two things?

Thanks in advance for your help,

Bob

My code :

package ch.fraise;

import java.io.IOException;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraActivity extends Activity implements SurfaceHolder.Callback,
    Camera.AutoFocusCallback {

private SurfaceView preview;
private SurfaceHolder previewHolder;

private MediaRecorder mRecorder;
private Camera mCamera;
private boolean mPreviewRunning = false;
private boolean mCaptureFrame = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.e("", "Begin onCreate");
    setContentView(R.layout.main);

    preview = (SurfaceView) findViewById(R.id.surfaceView1);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(this);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    mRecorder = new MediaRecorder();
}

@Override
public void onResume() {
    super.onResume();
}

@Override
public void onPause() {
    super.onPause();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.capture_menu, menu);
    return true;
}

public void startRecording() {
    Log.e("", "Begin StartRecording");
    mCaptureFrame = true;
    mRecorder.start();
}

public void stopRecording() {
    Log.e("", "Begin StopChange");
    mRecorder.stop();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
    case R.id.startRecording:
        startRecording();
        return true;
    case R.id.stopRecording:
        stopRecording();
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    Log.e("", "Begin surfaceDestroy");
    mCamera = Camera.open();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    mCamera.stopPreview();
    mPreviewRunning = false;
    mCamera.release();

    mRecorder.reset();
    mRecorder.release();
}

@Override
public void onAutoFocus(boolean success, Camera camera) {
    // TODO Auto-generated method stub

}

/*
 * PreviewCallback()
 * 
 * this callback captures the preview at every frame and puts it in a byte
 * buffer. we will evaluate if this is a frame that we want to process, and
 * if so, we will send it to an asynchronous thread that will process it to
 * an ARGB Bitmap and POST it to the server
 */
PreviewCallback previewCallback = new PreviewCallback() {
    public void onPreviewFrame(byte[] data, Camera camera) {
        Log.e("", "onPreviewFrame pass");
        if (mCaptureFrame) {
            mCaptureFrame = false;
            // new FrameHandler().execute(data);
        }
    }
};

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    Log.e("", "Begin SurfaceChange");

    mRecorder.reset();
    mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    mRecorder.setOutputFile("/sdcard/videotest2.mp4");
    mRecorder.setVideoFrameRate(30);

    mRecorder.setPreviewDisplay(previewHolder.getSurface());
    try {
        mRecorder.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (mPreviewRunning)
        mCamera.stopPreview();

    Camera.Parameters p = mCamera.getParameters();
    // p.setPreviewSize(width, height);
    mCamera.setParameters(p);

    try {
        mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {
        e.printStackTrace();
    }

    mCamera.setPreviewCallback(previewCallback);

    mCamera.startPreview();
    mPreviewRunning = true;

}

}

and the permissions in the xml file :

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

解决方案

Eureka! The trick is to attach your PreviewCallback in the surfaceChanged(...) SurfaceHolder.Callback! After doing this, you'll continue to get preview frame data after a MediaRecorder is running!

For example:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    mCamera.setPreviewCallback(new PreviewCallback() {
            public void onPreviewFrame(byte[] _data, Camera _camera) {
                Log.d("onPreviewFrame-surfaceChanged",String.format("Got %d bytes of camera data", _data.length));
            }
        });

}

这篇关于安卓preVIEW处理,而视频录制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆