Android同屏、摄像头RTMP推送常用的数据接口设计探讨
前言
好多开发者在调用Android平台RTMP推送或轻量级RTSP服务接口时,采集到的video数据类型多样化,如420sp、I420、yv12、nv21、rgb的,还有的拿到的图像是倒置的,如果开发者在上层转换后,传到底层编码处理,无疑加大了上层处理负担,而且容易因为低效率影响体验,本文以大牛直播SDK的Android平台RTMP推送SDK编码前video数据对接接口为例,看看常用的数据格式有哪些,相关资料,可参考 Github:
1. Android摄像头前后camera通过OnPreviewFrame()回调的数据接口:
Android自带的camera摄像头数据对接是最基础的,需要考虑的是摄像头方向问题,比如横屏、竖屏、还有部分定制设备home键在左侧的情况,相对来说处理比较简单,直接上接口,不再赘述。
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
frameCount++;
if (frameCount % 3000 == 0) {
Log.i("OnPre", "gc+");
System.gc();
Log.i("OnPre", "gc-");
}
if (data == null) {
Parameters params = camera.getParameters();
Size size = params.getPreviewSize();
int bufferSize = (((size.width | 0x1f) + 1) * size.height * ImageFormat.getBitsPerPixel(params.getPreviewFormat())) / 8;
camera.addCallbackBuffer(new byte[bufferSize]);
} else {
if (isRTSPPublisherRunning || isPushingRtmp || isRecording || isPushingRtsp) {
libPublisher.SmartPublisherOnCaptureVideoData(publisherHandle, data, data.length, currentCameraType, currentOrigentation);
}
camera.addCallbackBuffer(data);
}
}
对应接口定义:
/**
* Set live video data(no encoded data).
*
* @param cameraType: CAMERA_FACING_BACK with 0, CAMERA_FACING_FRONT with 1
*
* @param curOrg:
* PORTRAIT = 1; //竖屏
* LANDSCAPE = 2; //横屏 home键在右边的情况
* LANDSCAPE_LEFT_HOME_KEY = 3; //横屏 home键在左边的情况
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoData(long handle, byte[] data, int len, int cameraType, int curOrg);
2. 部分定制设备,只支持YV12的数据:
一般用于第三方摄像头对接之用,第三方摄像头,以YV12和NV21居多,部分需要旋转。
/**
* YV12数据接口
*
* @param data: YV12 data
*
* @param width: 图像宽
*
* @param height: 图像高
*
* @param y_stride: y面步长
*
* @param v_stride: v面步长
*
* @param u_stride: u面步长
*
* rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
*
* @return {0} if successful
*/
public native int SmartPublisherOnYV12Data(long handle, byte[] data, int width, int height, int y_stride, int v_stride, int u_stride, int rotation_degree);
3. 支持NV21数据接口:
nv21数据接口,除了用于常规的camera数据接入外,部分定制摄像头出来的数据发生翻转,这个接口也支持。
/**
* NV21数据接口
*
* @param data: nv21 data
*
* @param len: data length
*
* @param width: 图像宽
*
* @param height: 图像高
*
* @param y_stride: y面步长
*
* @param uv_stride: uv面步长
*
* rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
*
* @return {0} if successful
*/
public native int SmartPublisherOnNV21Data(long handle, byte[] data, int len, int width, int height, int y_stride, int uv_stride, int rotation_degree);
/**
* NV21数据接口
*
* @param data: nv21 data
*
* @param len: data length
*
* @param width: 图像宽
*
* @param height: 图像高
*
* @param y_stride: y面步长
*
* @param uv_stride: uv面步长
*
* rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
*
* @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
*
* @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
*
* @return {0} if successful
*/
public native int SmartPublisherOnNV21DataV2(long handle, byte[] data, int len, int width, int height, int y_stride, int uv_stride, int rotation_degree,
int is_vertical_flip, int is_horizontal_flip);
4. 支持YUV数据接入:
支持标准的I420数据接口对接。
/**
* Set live video data(no encoded data).
*
* @param data: I420 data
*
* @param len: I420 data length
*
* @param yStride: y stride
*
* @param uStride: u stride
*
* @param vStride: v stride
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoI420Data(long handle, byte[] data, int len, int yStride, int uStride, int vStride);
5. 支持RGBA数据接入(支持裁剪后数据接入,主要用于同屏场景):
RGBA的主要用于屏幕共享场景下,为了便于推送屏幕部分区域,我们友好的加了裁剪参数。
/**
* Set live video data(no encoded data).
*
* @param data: RGBA data
*
* @param rowStride: stride information
*
* @param width: width
*
* @param height: height
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoRGBAData(long handle, ByteBuffer data, int rowStride, int width, int height);
/**
* 投递裁剪过的RGBA数据
*
* @param data: RGBA data
*
* @param rowStride: stride information
*
* @param width: width
*
* @param height: height
*
* @param clipedLeft: 左; clipedTop: 上; clipedwidth: 裁剪后的宽; clipedHeight: 裁剪后的高; 确保传下去裁剪后的宽、高均为偶数
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoClipedRGBAData(long handle, ByteBuffer data, int rowStride, int width, int height, int clipedLeft, int clipedTop, int clipedWidth, int clipedHeight);
/**
* Set live video data(no encoded data).
*
* @param data: ABGR flip vertical(垂直翻转) data
*
* @param rowStride: stride information
*
* @param width: width
*
* @param height: height
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoABGRFlipVerticalData(long handle, ByteBuffer data, int rowStride, int width, int height);
6. 支持RGB565数据接入(主要用于同屏场景):
同屏场景居多。
/**
* Set live video data(no encoded data).
*
* @param data: RGB565 data
*
* @param row_stride: stride information
*
* @param width: width
*
* @param height: height
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoRGB565Data(long handle,ByteBuffer data, int row_stride, int width, int height);
7. 支持camera数据接入(主要用于camera2接口对接):
为了更高效率的兼容camera2数据采集模式。
/*
* 专门为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);
总结:
以上仅是Android编码前video数据接口对接分享,感兴趣的开发者可酌情参考,由此可见,部分公司或开发者提到,一个Android平台的RTMP推送模块只要几个接口,化繁为简几乎是不可能的,除非。。
Android同屏、摄像头RTMP推送常用的数据接口设计探讨的更多相关文章
- EasyPusher进行Android UVC外接摄像头直播推送实现方法
最近EasyPusher针对UVC摄像头做了适配.我们结合了UVCCamera与EasyPusher,支持将UVC摄像头的视频推送到RTSP服务器上.在此特别感谢UVCCamera这个牛逼的项目! 来 ...
- Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述
好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...
- Windows平台摄像头或屏幕RTMP推送介绍:OBS VS SmartPublisher
好多开发者问道,既然有了OBS,你们为什么还要开发SmartPublisher? 的确,在我们进行Windows平台RTMP推送模块开发之前,市面上为数不多的Windows平台RTMP推流工具当属OB ...
- 最简单的基于Flash的流媒体示例:RTMP推送和接收(ActionScript)
===================================================== Flash流媒体文章列表: 最简单的基于Flash的流媒体示例:RTMP推送和接收(Acti ...
- 解决RTMP推送时间戳问题引起HLS切片不均匀导致手机浏览器播放卡顿的问题
本文转自EasyDarwin开源团队成员Kim的博客:http://blog.csdn.net/jinlong0603/article/details/74161115 引言 最近在测试EasyNVR ...
- EasyRTMP推送扩展支持HEVC(H265) RTMP推送之Metadata结构填写详解
我们在<EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案>中描述了关于EasyRTMP进行RTMP HEVC(H.265)推流的概括 ...
- Android 基于Netty的消息推送方案之对象的传递(四)
在上一篇文章中<Android 基于Netty的消息推送方案之字符串的接收和发送(三)>我们介绍了Netty的字符串传递,我们知道了Netty的消息传递都是基于流,通过ChannelBuf ...
- Android 基于Netty的消息推送方案之字符串的接收和发送(三)
在上一篇文章中<Android 基于Netty的消息推送方案之概念和工作原理(二)> ,我们介绍过一些关于Netty的概念和工作原理的内容,今天我们先来介绍一个叫做ChannelBuffe ...
- Android 基于Netty的消息推送方案之概念和工作原理(二)
上一篇文章中我讲述了关于消息推送的方案以及一个基于Netty实现的一个简单的Hello World,为了更好的理解Hello World中的代码,今天我来讲解一下关于Netty中一些概念和工作原理的内 ...
随机推荐
- Vue回炉重造之三次封装axios
源码目录 在src目录下建立一个request文件夹.里面建立两个文件: http.js api.js 源码内容 http.js import axios from 'axios' // 引入axio ...
- 用console画条龙?
相识 console一定是各位前端er最熟悉的小伙伴了,无论是console控制台,还是console对象,做前端做久了,打开一个网页总是莫名自然的顺手打开控制台,有些调皮的网站还会故意在控制台输出一 ...
- C#生成putty格式的ppk文件(支持passphrase)
背景 2022国家级护网行动即将开启,根据阿里云给出的安全建议,需要将登陆Linux的方式改为密钥对方式.我这里使用的远程工具是自己开发的,能够同时管理Windows和Linux,但是以前不支持密钥对 ...
- day11 - 多线程
1内容 进程.线程介绍 Java中 线程的实现方式 Thread 类 Runnable 接口 Callable 接口 线程相关的方法 线程安全问题 - 同步技术 线程等待唤醒机制 进程(Process ...
- SimpleDateFormat类介绍和 DateFormat类的format方法和parse方法
使用 SimpleDateFormat格式化日期 SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类.SimpleDateFormat 允许你选择任何用户自定义日期时间 ...
- 自动登录token过期问题
之前遇到的一个也不算棘手的问题,自动登录本地存储了token却无法登录到主页. 先说一下我自动登录的思路:在用户登录成功时,将 token 存入 cookie :当用户下次来到本网站,读取 cooki ...
- 未找到与名为“xxx”的控制器匹配的类型。
自己封装了一个BaseApiControllerr把他独立成一个项目出来在引用不行,而用默认自带的ApiControllerr可以. <Error> <Message> 未找到 ...
- ArrayDeque(JDK双端队列)源码深度剖析
ArrayDeque(JDK双端队列)源码深度剖析 前言 在本篇文章当中主要跟大家介绍JDK给我们提供的一种用数组实现的双端队列,在之前的文章LinkedList源码剖析当中我们已经介绍了一种双端队列 ...
- GFS分布式文件系统
一.文件系统简介1.文件系统的组成接口:文件系统接口功能模块(管理.存储的工具):对对象管理里的软件集合对象及属性:(使用此文件系统的消费者)2.文件系统的作用从系统角度来看,文件系统时对文件存储设备 ...
- 素数算法(Prime Num Algorithm)
素数算法(Prime Num Algorithm) 数学是科学的皇后,而素数可以说是数学的最为核心的概念之一.围绕素数产生了很多伟大的故事,最为著名莫过于哥德巴赫猜想.素数定理和黎曼猜想(有趣的是,自 ...