Android平台RTMP推流或轻量级RTSP服务(摄像头或同屏)编码前数据接入类型总结
生活随笔
收集整理的這篇文章主要介紹了
Android平台RTMP推流或轻量级RTSP服务(摄像头或同屏)编码前数据接入类型总结
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
很多開發(fā)者在做Android平臺RTMP推流或輕量級RTSP服務(攝像頭或同屏)時,總感覺接口不夠用,以大牛直播SDK為例 (Github) 我們來總結下,我們常規(guī)需要支持的編碼前音視頻數(shù)據(jù)有哪些類型:
1. Android攝像頭前后camera通過OnPreviewFrame()回調的數(shù)據(jù)接口:
@Overridepublic 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的數(shù)據(jù):
????/*** YV12數(shù)據(jù)接口** @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數(shù)據(jù)接口:
nv21數(shù)據(jù)接口,除了用于常規(guī)的camera數(shù)據(jù)接入外,部分定制攝像頭出來的數(shù)據(jù)發(fā)生翻轉,這個接口也支持。
????/*** NV21數(shù)據(jù)接口** @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數(shù)據(jù)接口** @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數(shù)據(jù)接入:
????/*** 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數(shù)據(jù)接入(支持裁剪后數(shù)據(jù)接入,主要用于同屏場景):
????/*** 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數(shù)據(jù)** @param data: RGBA data** @param rowStride: stride information** @param width: width** @param height: height** @param clipedLeft: 左; ?clipedTop: 上; clipedwidth: 裁剪后的寬; clipedHeight: 裁剪后的高; 確保傳下去裁剪后的寬、高均為偶數(shù)** @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數(shù)據(jù)接入(主要用于同屏場景):
????/*** 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數(shù)據(jù)接入(主要用于camera2接口對接):
????
/** ?專門為android.media.Image的android.graphics.ImageFormat.YUV_420_888格式提供的接口** @param ?width: 必須是8的倍數(shù)** @param ?height: 必須是8的倍數(shù)** @param ?crop_left: 剪切左上角水平坐標, 一般根據(jù)android.media.Image.getCropRect() 填充** @param ?crop_top: 剪切左上角垂直坐標, 一般根據(jù)android.media.Image.getCropRect() 填充** @param ?crop_width: 必須是8的倍數(shù), 填0將忽略這個參數(shù), 一般根據(jù)android.media.Image.getCropRect() 填充** @param ?crop_height: 必須是8的倍數(shù), 填0將忽略這個參數(shù),一般根據(jù)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的倍數(shù), 0不縮放** @param ?scale_height: 縮放高, 必須是8的倍數(shù), 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);
8.?支持PCM數(shù)據(jù)接入:
?
????/*** 傳遞PCM音頻數(shù)據(jù)給SDK, 每10ms音頻數(shù)據(jù)傳入一次*?* ?@param pcmdata: pcm數(shù)據(jù), 需要使用ByteBuffer.allocateDirect分配, ByteBuffer.isDirect()是true的才行.* ?@param size: pcm數(shù)據(jù)大小* ?@param sample_rate: 采樣率,當前只支持{44100, 8000, 16000, 24000, 32000, 48000}, 推薦44100* ?@param channel: 通道, 當前通道支持單通道(1)和雙通道(2),推薦單通道(1)* ?@param per_channel_sample_number: 這個請傳入的是 sample_rate/100*/public native int SmartPublisherOnPCMData(long handle, ByteBuffer pcmdata, int size, int sample_rate, int channel, int per_channel_sample_number);/*** 傳遞PCM音頻數(shù)據(jù)給SDK, 每10ms音頻數(shù)據(jù)傳入一次** ?@param pcmdata: pcm數(shù)據(jù), 需要使用ByteBuffer.allocateDirect分配, ByteBuffer.isDirect()是true的才行.* ?@param offset: pcmdata的偏移* ?@param size: pcm數(shù)據(jù)大小* ?@param sample_rate: 采樣率,當前只支持{44100, 8000, 16000, 24000, 32000, 48000}, 推薦44100* ?@param channel: 通道, 當前通道支持單通道(1)和雙通道(2),推薦單通道(1)* ?@param per_channel_sample_number: 這個請傳入的是 sample_rate/100*/public native int SmartPublisherOnPCMDataV2(long handle, ByteBuffer pcmdata, int offset, int size, int sample_rate, int channel, int per_channel_sample_number);/*** 傳遞PCM音頻數(shù)據(jù)給SDK, 每10ms音頻數(shù)據(jù)傳入一次** ?@param pcm_short_array: pcm數(shù)據(jù), short是native endian order* ?@param offset: 數(shù)組偏移* ?@param len: 數(shù)組項數(shù)* ?@param sample_rate: 采樣率,當前只支持{44100, 8000, 16000, 24000, 32000, 48000}, 推薦44100* ?@param channel: 通道, 當前通道支持單通道(1)和雙通道(2),推薦單通道(1)* ?@param per_channel_sample_number: 這個請傳入的是 sample_rate/100*/public native int SmartPublisherOnPCMShortArray(long handle, short[] pcm_short_array, int offset, int len, int sample_rate, int channel, int per_channel_sample_number);
9.?支持遠端PCM數(shù)據(jù)接入和混音后PCM數(shù)據(jù)接入(主要用于一對一互動):? ??
/*** Set far end pcm data*?* @param pcmdata : 16bit pcm data* @param sampleRate: audio sample rate* @param channel: auido channel* @param per_channel_sample_number: per channel sample numbers* @param is_low_latency: if with 0, it is not low_latency, if with 1, it is low_latency* @return {0} if successful*/public native int SmartPublisherOnFarEndPCMData(long handle, ?ByteBuffer pcmdata, int sampleRate, int channel, int per_channel_sample_number, int is_low_latency);/*** 傳遞PCM混音音頻數(shù)據(jù)給SDK, 每10ms音頻數(shù)據(jù)傳入一次** ?@param stream_index: 當前只能傳1, 傳其他返回錯誤* ?@param pcm_data: pcm數(shù)據(jù), 需要使用ByteBuffer.allocateDirect分配, ByteBuffer.isDirect()是true的才行.* ?@param offset: pcmdata的偏移* ?@param size: pcm數(shù)據(jù)大小* ?@param sample_rate: 采樣率,當前只支持{44100, 8000, 16000, 24000, 32000, 48000}* ?@param channels: 通道, 當前通道支持單通道(1)和雙通道(2)* ?@param per_channel_sample_number: 這個請傳入的是 sample_rate/100*/public native int SmartPublisherOnMixPCMData(long handle, int stream_index, ByteBuffer pcm_data, int offset, int size, int sample_rate, int channels, int per_channel_sample_number);/*** 傳遞PCM混音音頻數(shù)據(jù)給SDK, 每10ms音頻數(shù)據(jù)傳入一次** ?@param stream_index: 當前只能傳1, 傳其他返回錯誤* ?@param pcm_short_array: pcm數(shù)據(jù), short是native endian order* ?@param offset: 數(shù)組偏移* ?@param len: 數(shù)組項數(shù)* ?@param sample_rate: 采樣率,當前只支持{44100, 8000, 16000, 24000, 32000, 48000}* ?@param channels: 通道, 當前通道支持單通道(1)和雙通道(2)* ?@param per_channel_sample_number: 這個請傳入的是 sample_rate/100*/public native int SmartPublisherOnMixPCMShortArray(long handle, int stream_index, short[] pcm_short_array, int offset, int len, int sample_rate, int channels, int per_channel_sample_number);總結:
以上只是編碼前數(shù)據(jù)接口,一個產品如果想做的足夠通用,需要對接的太多了,你覺得呢?
總結
以上是生活随笔為你收集整理的Android平台RTMP推流或轻量级RTSP服务(摄像头或同屏)编码前数据接入类型总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 少儿故事:小乌鸦智斗老鹰
- 下一篇: 【机器学习】机器学习模型解释神器:Sha