当前位置: 代码迷 >> Android >> 关于android视频采集的有关问题,求解
  详细解决方案

关于android视频采集的有关问题,求解

热度:34   发布时间:2016-05-01 21:40:27.0
关于android视频采集的问题,急求解
最近在有个项目是关于android的视频采集,要求是捕捉某个事件发生前后30秒的视频片段。以前从没有做过android或多媒体开发,很多概念和技术不是很清楚,在网上各论坛转了很久,大致有个思路(MediaRecorder类不知道能不能满足上面的要求),就是利用Camera的PreviewCallback接口,通过实现onPreviewFrame(byte[] data, Camera camera)来捕捉每一帧数据,然后将data保存到文件里,问题是直接保存的数据无法播放,网上有人提供过decodeYUV420SP方法来将默认的YUV格式转码为RGB格式,问题是无论转码前还是转码后我都不知道应该保存为什么文件,是不是直接保存为后缀名为".3gp"或".mp4"就可以了?
我一直是在模拟器上调试的,不知道是不是一定需要在真机上运行才行。
跪求各达人显显灵,谢啦!

以下是我的代码,请各位达人斧正

Java code
import java.io.File;import java.io.RandomAccessFile;import android.app.Activity;import android.graphics.PixelFormat;import android.hardware.Camera;import android.os.Bundle;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.Window;import android.view.WindowManager;public class AndroidCamera extends Activity implements SurfaceHolder.Callback {        private SurfaceView mSurfaceView = null;    private SurfaceHolder mSurfaceHolder = null;    private Camera mCamera = null;        private boolean mPreviewRunning = false;        /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                getWindow().setFormat(PixelFormat.TRANSLUCENT);        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);                        setContentView(R.layout.main);                mSurfaceView = (SurfaceView)findViewById(R.id.surface_camera);        mSurfaceHolder = mSurfaceView.getHolder();        mSurfaceHolder.addCallback(this);        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        if(mPreviewRunning) {            mCamera.stopPreview();        }                Camera.Parameters p = mCamera.getParameters();                p.setPreviewSize(width, height);        mCamera.setPreviewCallback(new VideoData(width, height));        mCamera.setParameters(p);                try {            mCamera.setPreviewDisplay(holder);        } catch(Exception e) {            e.printStackTrace();        }                mCamera.startPreview();        mPreviewRunning = true;            }    @Override    public void surfaceCreated(SurfaceHolder holder) {        mCamera = Camera.open();    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        Log.v("AndroidCamera", "surfaceDestroyed");        if(mCamera != null) {            mCamera.setPreviewCallback(null);            mCamera.stopPreview();            mPreviewRunning =false;            mCamera.release();            mCamera = null;        }            }}class VideoData implements Camera.PreviewCallback {    RandomAccessFile raf=null;    byte[] h264Buff =null;        public VideoData(int width, int height) {        Log.v("androidCamera", "new VideoData");        h264Buff = new byte[width * height *8];                try {            Log.v("androidCamera", "Create File: /sdcard/camera.dat start");            File file = new File("/sdcard/camera.3gp");            Log.v("androidCamera", "Create File: /sdcard/camera.dat end");            raf = new RandomAccessFile(file, "rw");        } catch (Exception ex) {            ex.printStackTrace();        }    }        @Override    public void onPreviewFrame(byte[] data, Camera camera) {        if(data == null) {            return;        }        int previewWidth = camera.getParameters().getPreviewSize().width;        int previewHeight = camera.getParameters().getPreviewSize().height;                byte[] rgbBuffer = new byte[previewWidth * previewHeight * 3];                decodeYUV420SP(rgbBuffer, data, previewWidth, previewHeight);                try {            raf.write(rgbBuffer, 0, data.length);        } catch(Exception ex) {            ex.printStackTrace();        }    }        protected void finalize() {        if (null != raf) {            try {                raf.close();            } catch (Exception ex) {                ex.printStackTrace();            }        }                try {            super.finalize();        } catch (Throwable e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }        private void decodeYUV420SP(byte[] rgbBuf, byte[] yuv420sp, int width, int height) {            final int frameSize = width * height;            if (rgbBuf == null)                throw new NullPointerException("buffer 'rgbBuf' is null");            if (rgbBuf.length < frameSize * 3)                throw new IllegalArgumentException("buffer 'rgbBuf' size "                        + rgbBuf.length + " < minimum " + frameSize * 3);                       if (yuv420sp == null)                throw new NullPointerException("buffer 'yuv420sp' is null");                       if (yuv420sp.length < frameSize * 3 / 2)                throw new IllegalArgumentException("buffer 'yuv420sp' size " + yuv420sp.length                         + " < minimum " + frameSize * 3 / 2);                            int i = 0, y = 0;            int uvp = 0, u = 0, v = 0;            int y1192 = 0, r = 0, g = 0, b = 0;                        for (int j = 0, yp = 0; j < height; j++) {                 uvp = frameSize + (j >> 1) * width;                 u = 0;                 v = 0;                for (i = 0; i < width; i++, yp++) {                     y = (0xff & ((int) yuv420sp[yp])) - 16;                    if (y < 0) y = 0;                    if ((i & 1) == 0) {                         v = (0xff & yuv420sp[uvp++]) - 128;                         u = (0xff & yuv420sp[uvp++]) - 128;                     }                                         y1192 = 1192 * y;                     r = (y1192 + 1634 * v);                     g = (y1192 - 833 * v - 400 * u);                     b = (y1192 + 2066 * u);                                        if (r < 0) r = 0; else if (r > 262143) r = 262143;                    if (g < 0) g = 0; else if (g > 262143) g = 262143;                    if (b < 0) b = 0; else if (b > 262143) b = 262143;                                         rgbBuf[yp * 3] = (byte)(r >> 10);                     rgbBuf[yp * 3 + 1] = (byte)(g >> 10);                     rgbBuf[yp * 3 + 2] = (byte)(b >> 10);                }            }    }}
  相关解决方案