如何实现RTMP推送Android Camera2数据

如何实现RTMP推送Android Camera2数据,第1张

概述Camera2简介在Google推出Android5.0的时候,AndroidCameraAPI版本升级到了API2(android.hardware.camera2),之前使用的API1(android.hardware.camera)就被标为Deprecated了。CameraAPI2相较于API1有很大不同,并且API2是为了配合HAL3进行使用的,API2有很多API1不支 Camera2简介

在Google 推出AndroID 5.0的时候, AndroID Camera API 版本升级到了API2(androID.harDWare.camera2), 之前使用的API1(androID.harDWare.camera)就被标为 Deprecated 了。

Camera API2相较于API1有很大不同, 并且API2是为了配合HAL3进行使用的, API2有很多API1不支持的特性, 比如:

更先进的API架构;可以获取更多的帧(预览/拍照)信息以及手动控制每一帧的参数;对Camera的控制更加完全(比如支持调整focus distance, 剪裁预览/拍照图片);支持更多图片格式(yuv/raw)以及高速连拍等。

在API架构方面, Camera2和之前的Camera有很大区别, APP和底层Camera之前可以想象成用管道方式连接, 如下图:

这里引用了管道的概念将安卓设备和摄像头之间联通起来,系统向摄像头发送 Capture 请求,而摄像头会返回 CameraMetadata。这一切建立在一个叫作 CameraCaptureSession 的会话中。

下面是 camera2包中的主要类:

其中 CameraManager 是那个站在高处统管所有摄像投设备(CameraDevice)的管理者,而每个 CameraDevice 自己会负责建立 CameraCaptureSession 以及建立 CaptureRequest。

Cameracharacteristics 是 CameraDevice 的属性描述类,非要做个对比的话,那么它与原来的 CameraInfo 有相似性。

Camera2 API调用基础流程:通过context.getSystemService(Context.CAMERA_SERVICE) 获取CameraManager;调用CameraManager .open()方法在回调中得到CameraDevice;通过CameraDevice.createCaptureSession() 在回调中获取CameraCaptureSession;构建CaptureRequest, 有三种模式可选 预览/拍照/录像.;通过 CameraCaptureSession发送CaptureRequest, capture表示只发一次请求, setRepeatingRequest表示不断发送请求;拍照数据可以在ImageReader.OnImageAvailableListener回调中获取, CaptureCallback中则可获取拍照实际的参数和Camera当前状态。获取数据后对接RTMP推送

通过OnImageAvailableListenerImpl 获取到原始数据,推送端以大牛直播SDK https://github.com/daniulive/SmarterStreaming/ 的万能推送接口为例,获取数据后,调用SmartPublisheronImageYUV420888() 完成数据传送,底层进行二次处理后,编码后传输即可。

接口描述:

	/*	*  专门为androID.media.Image的androID.graphics.ImageFormat.YUV_420_888格式提供的接口	*    * @param  wIDth: 必须是8的倍数	*    * @param  height: 必须是8的倍数	*	* @param  crop_left: 剪切左上角水平坐标, 一般根据androID.media.Image.getCropRect() 填充	*	* @param  crop_top: 剪切左上角垂直坐标, 一般根据androID.media.Image.getCropRect() 填充	*    * @param  crop_wIDth: 必须是8的倍数, 填0将忽略这个参数, 一般根据androID.media.Image.getCropRect() 填充	*    * @param  crop_height: 必须是8的倍数, 填0将忽略这个参数,一般根据androID.media.Image.getCropRect() 填充    *    * @param y_plane 对应androID.media.Image.Plane[0].getBuffer()    *    * @param y_row_strIDe 对应androID.media.Image.Plane[0].getRowStrIDe()	*	* @param u_plane 对应androID.media.Image.Plane[1].getBuffer()	*	* @param v_plane 对应androID.media.Image.Plane[2].getBuffer()	*	* @param uv_row_strIDe 对应androID.media.Image.Plane[1].getRowStrIDe()	*	* @param uv_pixel_strIDe 对应androID.media.Image.Plane[1].getPixelStrIDe()	*    * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270	*    * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转	*    * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转	*    * @param  scale_wIDth: 缩放宽,必须是8的倍数, 0不缩放	*    * @param  scale_height: 缩放高, 必须是8的倍数, 0不缩放	*	* @param  scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认速度	*	* @return {0} if successful    */	public native int SmartPublisheronImageYUV420888(long handle, int wIDth, int height,													 int crop_left, int crop_top, int crop_wIDth, int crop_height,													 ByteBuffer y_plane, int y_row_strIDe,													 ByteBuffer u_plane, ByteBuffer v_plane, int uv_row_strIDe, int uv_pixel_strIDe,													 int rotation_degree, int is_vertical_flip, int is_horizontal_flip,													 int scale_wIDth, int scale_height, int scale_filter_mode);
    private class OnImageAvailableListenerImpl implements ImageReader.OnImageAvailableListener {        @OverrIDe        public voID onImageAvailable(ImageReader reader) {            Image image = reader.acquireLatestimage();            if ( image != null )            {                if ( camera2Listener != null )                {                    camera2Listener.onCameraimageData(image);                }                image.close();            }        }    }
    @OverrIDe    public voID onCameraimageData(Image image) {        synchronized(this)        {            Rect crop_rect = image.getCropRect();            if(isPushingRtmp || isRTSPPublisherRunning) {                if(libPublisher != null)                {                    Image.Plane[] planes = image.getPlanes();                    //  crop_rect.left, crop_rect.top, crop_rect.wIDth(), crop_rect.height(),                    //  这里缩放宽高可以填0,使用原视视频宽高都可以的                    libPublisher. SmartPublisheronImageYUV420888(publisherHandle, image.getWIDth(), image.getHeight(),                            crop_rect.left, crop_rect.top, crop_rect.wIDth(), crop_rect.height(),                            planes[0].getBuffer(), planes[0].getRowStrIDe(),                            planes[1].getBuffer(), planes[2].getBuffer(), planes[1].getRowStrIDe(), planes[1].getPixelStrIDe(),                            displayOrIEntation, 0, 0,                            vIDeoWIDth, vIDeoHeight, 1);                }            }        }    }

以上就是基础的AndroID Camera2介绍,和RTMP调用流程,感兴趣的可以自行学习。

总结

以上是内存溢出为你收集整理的如何实现RTMP推送Android Camera2数据全部内容,希望文章能够帮你解决如何实现RTMP推送Android Camera2数据所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1065238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存