EasyCamera Android视频推送过程中随时保存快照

来源:互联网 发布:微分几何 知乎 编辑:程序博客网 时间:2024/06/05 16:38

EasyCamera

EasyCamera是EasyDarwin云平台的视频推送端组件,详细介绍参见http://blog.csdn.net/jinlong0603/article/details/60886234。
EasyCamera启动后,就向EasyCMS服务器发起注册请求,注册成功后,定时发送心跳和快照。等待接收EasyClient发起的,由EasyCMS转发过来的指令(推送直播视频、云台控制、语音喊话 …)。EasyClient端会显示EasyCamera上传的快照。当然如果不需要快照,可以在EasyCamera代码中将生成快照的地方注释掉就好。

快照生成

现在主要介绍下如果在摄像头打开后,在SurefaceView中取出一张jpeg图片。在Camera PreviewCallback中,首先将实时NV21数据旋转90度(在某些Android设备上可能不需要旋转)。

mCamera.setPreviewCallbackWithBuffer(previewCallback);Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {        @Override        public void onPreviewFrame(byte[] data, Camera camera) {            if (data == null){                return;            }            Camera.Size previewSize = mCamera.getParameters().getPreviewSize();            if (data.length != previewSize.width * previewSize.height * 3 / 2) {                mCamera.addCallbackBuffer(data);                return;            }            if (mRequestSnapshot){                mRequestSnapshot = false;                final String path = new File(mApplicationContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "snap.jpeg").getPath();                try {                    if (mDgree == 0) {                        int cameraRotationOffset = camInfo.orientation;                        byte[]buffer = new byte[data.length];                        int y_stride = previewSize.width * previewSize.height;                        if (cameraRotationOffset == 90) {                            if (mSWCodec) {                                System.arraycopy(data, 0, buffer, 0, y_stride);                                for (int i =0;i< y_stride /4;){                                    buffer[y_stride + i*2] = data[y_stride + i];                                    buffer[y_stride + i*2+1] = data[y_stride +y_stride/4 + i];                                    ++i;                                }                                yuvRotate(buffer, 1, previewSize.width, previewSize.height, 90);                            }else{                                System.arraycopy(data, 0, buffer, 0, data.length);                                yuvRotate(buffer, 1, previewSize.width, previewSize.height, 90);                            }                            yuvToJpeg(buffer, previewSize.height, previewSize.width, 50, path);                        } else if (cameraRotationOffset == 270) {                            if (mSWCodec) {                                System.arraycopy(data, 0, buffer, 0, y_stride);                                for (int i =0;i< y_stride /4;){                                    buffer[y_stride + i*2] = data[y_stride + i];                                    buffer[y_stride + i*2+1] = data[y_stride +y_stride/4 + i];                                    ++i;                                }                                yuvRotate(buffer, 1, previewSize.width, previewSize.height, 270);                            }else{                                System.arraycopy(data, 0, buffer, 0, data.length);                                yuvRotate(buffer, 1, previewSize.width, previewSize.height, 270);                            }                            yuvToJpeg(buffer, previewSize.height, previewSize.width, 50, path);                        }else{                            yuvToJpeg(buffer, previewSize.width, previewSize.height, 50, path);                        }                    } else {                        yuvToJpeg(data, previewSize.width, previewSize.height, 50, path);                    }                    LocalBroadcastManager.getInstance(mApplicationContext).sendBroadcast(new Intent(ACTION_SNAPSHOT_GOT));                } catch (IOException e) {                    e.printStackTrace();                }            }            if (data == null || !pushStream || !codecAvailable || mConsumer == null) {                mCamera.addCallbackBuffer(data);                return;            }            byte []buffer = yuv_caches.poll();            if (buffer == null || buffer.length != data.length) {                buffer = new byte[data.length];            }            System.arraycopy(data, 0, buffer, 0, data.length);            yuvs.offer(new TimedBuffer(buffer));            mCamera.addCallbackBuffer(data);        }    };

旋转之后的数据调用了yuvToJpeg方法将yuv数据转成jpeg图片,这个功能使用了Android自带的YuvImage类的compressToJpeg方法。

private void yuvToJpeg(byte[] data, int width, int height, int quality, String path) throws IOException {        YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, width, height, null);        FileOutputStream fos = null;        try {            fos = new FileOutputStream(path);            yuvimage.compressToJpeg(new Rect(0, 0, width, height), quality, fos);        } finally {            if (fos != null) {                fos.close();            }        }    }

下载

本人搭建的EasyDarwin云平台:http://pan.baidu.com/s/1sluDEPn(内含文档)
EasyDarwin云平台服务器代码下载:https://github.com/EasyDarwin/EasyDarwin或者国内镜像http://git.oschina.net/easydarwin/EasyDarwin
EasyCamera Android app下载:https://fir.im/EasyCamera
EasyCamera 代码:https://github.com/EasyDarwin/EasyCamera
EasyClient Android app下载:https://fir.im/EasyClient
EasyClient 代码:https://github.com/EasyDarwin/EasyClient
EasyNVR 下载:https://github.com/EasyDarwin/EasyNVR

获取更多信息

邮件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2017

EasyDarwin

0 0
原创粉丝点击