Android直播推流SDK开发集成

1 概述

1.1 SDK简介

1.1.1 SDK业务简介

网易云通信直播源自网易多年视频技术沉淀,基于专业的跨平台视频编解码技术和大规模视频内容分发网络,提供稳定流畅、低延时、高并发的直播服务。

网易云直播推流SDK,用于支持在直播流程中,采集摄像头或自定义音视频数据,进行视频前处理,并进行编码推流到服务器。具有稳定、高效、功能全面的特点。

1.1.2 SDK技术简介

直播推流 SDK 由如下图所示的结构组成。 其中,实线框是直播的主要模块,包括音视频采集、处理、编码和打包发送。虚线框是辅助模块,关闭后不影响直播功能。

pic

网络信息统计功能帮助开发者实现网络状况的实时监测,尤其在弱网络环境下,能够快速准确的探知网络可用带宽等信息,帮助开发者调整产品策略,改善产品的用户体验。

1.2 设备和系统要求:

1.3 功能特性

2 开发准备

2.1 准备工作

2.2 集成SDK

本文是根据官网的直播推流 Demo 来介绍 SDK 的集成,可在网易云官网下载最新的直播推流 Android Demo,来查看更多的实现细节。

2.2.1 组件及资源

开发者需要将直播推流 SDK 集成到应用中,包括静态库文件和相关的头文件。如下图所示:

pic

直播推流 SDK 包含 demo、libs、docs 三个部分,在网易云视频官网可以下载 Demo 和 SDK 包

libs
├── armeabi-v7a
│   ├── liblivestreaming.so
│   ├── libvideoeffect.so
├── arm64-v8a
│   ├── liblivestreaming.so
│   ├── libvideoeffect.so
│
├── VideoEffect-x.x.x.jar (采集以及滤镜Java层代码)
└── Livestreaming-x.x.x.jar (编码推流Java层代码)

将这些文件拷贝到你的工程的对应目录下,同时将 Livestreaming-x.x.x.jar、VideoEffect-x.x.x.jar 加入工程,即可完成配置。

库文件介绍

说明
Livestreaming-x.x.x.jar 直播API封装综合jar库
liblivestreaming.so 编码以及发送相关的so库
VideoEffect-x.x.x.jar 视频融合模块库(视频采集 、视频前处理 )
libvideoeffect.so 滤镜等前处理so库
assets/filter 滤镜依赖资源图片

2.2.2 快速集成

<!-- 权限声明 -->   
<!-- 允许挂载和反挂载文件系统 -->   
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />   
<!-- 允许程序向外部存储设备写数据 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许程序打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序获取网络相关信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允许程序向外部存储设备写数据 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许程序写音频数据 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 允许程序使用PowerManager WakeLocks以防止处理器休眠或者屏幕锁屏 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 允许程序获取Wifi网络状态信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许程序使用设备的camera -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 允许程序使用闪光灯 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />
<!-- 允许程序获得设备信息 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-feature android:name="android.hardware.camera.autofocus"/>

<!-- 声明程序使用camera和自动对焦功能 -->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>

3 API概览

类别 API名称 功能
创建推流实例 - lsMediaCapture(LsMediaCapturePara lsMediaCapturePara) 根据LsMediaCapturePara设置SDK上下文Context以及消息回调
销毁推流实例 - (void)uninitLsMediaCapture(boolean uninitNow) 反初始化:释放资源;true:马上释放,false:等待推流结束后释放。(如推流已开始必须设置为false)
打开视频预览 - (void)startVideoPreview 打开摄像头进行预览,采用SDK提供的超清、高清、标清等模式进行预览
打开视频预览(扩展) - (void)startVideoPreviewEx 预览扩展接口,如果SDK提供的模板不满足,用户可以自定义设置预览的分辨率以及帧率等参数
切换分辨率 - (void)changeCaptureFormat 切换SDK支持的模板分辨率
切换分辨率(扩展) - (void)changeCaptureFormatEx 切换用户自定义分辨率
关闭视频预览 - (void)stopVideoPreview 关闭摄像头
销毁视频预览 - (void)destroyVideoPreview 释放摄像头以及预览显示View等资源
初始化推流 - (boolean)initLiveStream 设置推流地址以及推流类型等参数
开始推流 - (void)startLiveStreaming 开始推流,若失败,会在创建实例中的消息回调中返回具体错误码
结束推流 - (void)stopLiveStreaming 结束推流
暂停视频推流 - (void)pauseVideoLiveStream 暂停视频推流,不发送视频数据
恢复视频推流 - (void)resumeVideoLiveStream 恢复视频推流
暂停音频推流 - (void)pauseAudioLiveStream 暂停音频推流,发送静音数据
恢复音频推流 - (void)resumeAudioLiveStream 恢复音频推流
视频切后台 - (void)backgroundVideoEncode 视频推流切换到后台的处理,关闭相机,发送最后一帧画面
视频恢复前台 - (void)resumeVideoEncode 重新打开相机并推送视频数据
音频切后台 - (void)backgroundAudioEncode 发送静音帧
音频恢复前台 - (void)resumeAudioEncode 重新发送音频
开始伴音 - (boolean)startPlayMusic 支持是否循环播放
暂停伴音 - (boolean)pausePlayMusic 暂停伴音
恢复播放 - (boolean)resumePlayMusic 恢复伴音
结束伴音 - (boolean)stopPlayMusic 结束伴音
摄像头切换 - (void)switchCamera 前后摄像头动态切换
闪光灯开关 - (void)setCameraFlashPara 开关闪光灯(若支持)
摄像头缩放 - (void)setCameraZoomPara 设置摄像头缩放比例
摄像头曝光度 - (void)setExposureCompensation 设置摄像头曝光强度
摄像头对焦 - (void)setCameraFocus 设置摄像头全屏对焦
摄像头自动对焦 - (void) setCameraAutoFocus true:自动对焦,false:手动对焦,默认自动对焦
横竖屏切换 - (void)onConfigurationChanged 通知SDK发送了横竖屏切换,SDK重新计算宽高
设置水印 - (void)setWaterMarkPara 设置水印,一般用作视频版权logo显示
水印是否本地显示 - (void)setWaterPreview 设置水印是否本地显示(主播端),默认显示
动态水印 - (void)setDynamicWaterMarkPara 动态水印,一般用作视频中广告显示
动态水印是否本地显示 - (void)setDynamicWaterPreview 设置动态水印是否本地显示(主播端),默认显示
设置涂鸦 - (void)setGraffitiPara 涂鸦,可以中推流过程中实时变化
涂鸦是否本地显示 - (void)setGraffitiPreview 设置涂鸦是否本地显示(主播端),默认显示
摄像头采集数据回调 - (void)setCaptureRawDataCB 用于用户集成第三方美颜滤镜使用,SDK已在该接口上创建了openGLContext
post到openGL线程 - (void)postOnGLThread 用于第三方滤镜的部分必须在openGL线程上调用的接口使用
麦克风采集数据回调 - (void)setAudioRawDataCB 用于用户进行降噪等音频处理
设置数据源类型 - (void)setSourceType SDK:SDK负责采集 CustomMode:用户自定义采集
自定义YUV数据 - (void)sendCustomYUVData SDK支持用户自行采集摄像头等设备的YUV输入给SDK进行发送
自定义PCM数据 - (void)sendCustomPCMData SDK支持用户自行采集麦克风等设备的PCM输入给SDK进行发送
设置观众端镜像 - (void)setVideoMirror 直播过程中,开关观众端镜像效果(只对前置摄像头有效)
设置主播端镜像 - (void)setPreviewMirror 直播过程中,开关主播端镜像效果(只对前置摄像头有效)
设置滤镜类型 - (void)setFilterType 干净、自然、健康、复古等滤镜
设置滤镜强度 - (void)setFilterStrength (0 - 1)
设置磨皮强度 - (void)setBeautyLevel (0 - 5)
截图 - (void)enableScreenShot 对当前预览画面进行截图
开始测速 - (void)startSpeedCalc 支持直播开始前测速,选择最优链路推流
结束测速 - (void)stopSpeedCalc 结束此次测速
发送自定义数据 - (int)sendCustomData 数据随视频画面一起发送

总体参数介绍

SDK实例参数介绍

SDK实例参数说明LsMediaCapturePara

参数 类型 说明
setContext Context 设置SDK上下文,建议使用ApplicationContext
setMessageHandler lsMessageHandler 设置SDK消息回调接口
setLogLevel lsLogUtil.LogLevel 设置日志级别(info、warn、error)
setUploadLog boolean 设置是否上传日志

初始化推流参数说明LiveStreamingPara

参数 类型 说明
setStreamType StreamType AUDIO:但音频,VIDEO:单视频,AV:音视频双流
setFormatType FormatType MP4:MP4纯录制,RTMP:RTMP 推流,RTMP_AND_MP4:边推RTMP 边录制MP4
setRecordPath String 设置本地录制地址,FormatType为MP4或RTMP_AND_MP4有效
setQosOn boolean true:开启 false:关闭,默认开启Qos
setAutoRecord boolean 当formatType为MP4或RTMP_AND_MP4是否推流开始就自动开始录制,默认自动在上述两种模式下推流一开始就录制,只有需要推流与录制不同时进行的用户才需要关心,正常情况下,用户无需关心
setSyncTimestamp(syncTimestamp,absoluteTime) boolean syncTimestamp true:发送同步时间戳 false:不发送,默认不发送。 absoluteTime true:绝对时间(unix时间),false:相对于推流的时间(从0开始)
setStreamTimestampPassthrough boolean true:网易云透传时间戳 false:不透传,默认不透传

预览频参数说明

参数 类型 说明
videoView NeteaseView SDK提供的预览显示View,用户可以布局到自己的APP中
frontCamera boolean 是否默认前置摄像头
filter boolean 是否使用SDK内置滤镜
quality VideoQuality MEDIUM:标清 480360,HIGH:高清 640480,SUPER:超清 960540,SUPER_HIGH:超高清 1280720
scale_16x9 boolean 是否按16:9宽高比例

统计信息参数说明Statistics

参数 类型 说明
videoRealSendBitRate int 视频发送码率
audioRealSendBitRate int 音频发送码率
videoEncodeFrameRate int 视频编码帧率
videoEncodeBitRate int 视频编码码率
videoEncodeWidth int 视频编码宽
videoEncodeHeight int 视频编码码高
videoEncodeTime int 视频编码一帧的时间
audioEncodeBitRate int 音频编码码率
videoSetBitRate int 设置的视频码率
videoSetWidth int 设置的分辨率宽
videoSetHeight int 设置的分辨率高
networkLevel int 网络状况 1: 好,2:一般,3:差,4:未知
videoSendBufferQueueCount int 视频发送缓存队列当前大小

枚举值参数介绍

推流类型StreamType参数说明

参数 说明
AUDIO 单音频
VIDEO 单视频
AV 音视频双流

推流模式FormatType参数说明

参数 说明
MP4 MP4纯录制
RTMP RTMP 推流
RTMP_AND_MP4 边推RTMP 边录制MP4

输入源SourceType参数说明

参数 说明
SDK SDK负责采集
CustomAV 自定义采集音视频
CustomAudio 自定义采集音频
CustomVideo 自定义采集视频

视频分辨率VideoQuality参数说明

参数 说明
MEDIUM 标清 480*360
HIGH 高清 640*480
SUPER 超清 960*540
SUPER_HIGH 超高清 1280*720

水印位置VideoEffect.Rect参数说明

参数 说明
leftTop 左上角
leftBottom 左下角
rightTop 右上角
rightBottom 右下角
center 中间

滤镜类型VideoEffect.FilterType参数说明

参数 说明
none 无滤镜
clean 干净
fairytale 童话
nature 自然
healthy 健康
tender 温柔
whiten 美白

SDK消息回调具体状态码

public static final int MSG_INIT_LIVESTREAMING_ERROR = 0;//初始化直播出错
public static final int MSG_INIT_LIVESTREAMING_VIDEO_ERROR = 1; //初始化视频直播出错
public static final int MSG_INIT_LIVESTREAMING_AUDIO_ERROR = 2; //初始化音频直播出错
public static final int MSG_START_LIVESTREAMING_ERROR = 3;//开始直播出错
public static final int MSG_STOP_LIVESTREAMING_ERROR = 4;//停止直播出错
public static final int MSG_AUDIO_PROCESS_ERROR = 5;//音频编码打包出错
public static final int MSG_VIDEO_PROCESS_ERROR = 6; //视频编码打包出错
public static final int MSG_START_PREVIEW_ERROR = 7//打开视频预览失败
public static final int MSG_RTMP_URL_ERROR = 8; //RTMP URL连接出错,会进一步调用网络信息报警service,弹出悬浮窗
public static final int MSG_URL_NOT_AUTH = 9; //RTMP URL非法
public static final int MSG_SEND_STATICS_LOG_ERROR = 10; //发送统计日志出错
public static final int MSG_SEND_HEARTBEAT_LOG_ERROR = 11;//发送心跳日志出错
public static final int MSG_AUDIO_RECORD_ERROR = 12;//音频录制权限打开失败
public static final int MSG_AUDIO_SAMPLE_RATE_NOT_SUPPORT_ERROR = 13;//设置的音频采样率不支持
public static final int MSG_AUDIO_PARAMETER_NOT_SUPPORT_BY_HARDWARE_ERROR = 14;//设置的音频硬件编码参数不支持
public static final int MSG_NEW_AUDIORECORD_INSTANCE_ERROR = 15;//音频采集实例创建失败
public static final int MSG_AUDIO_START_RECORDING_ERROR = 16;//音频采集失败
public static final int MSG_QOS_TO_STOP_LIVESTREAMING = 17;//网络QoS较差   
public static final int MSG_HW_VIDEO_PACKET_ERROR = 18; //视频硬件编码出错
public static final int MSG_WATERMARK_INIT_ERROR = 19; //视频水印初始化出错
public static final int MSG_WATERMARK_PIC_OUT_OF_VIDEO_ERROR = 20; //视频水印超出原始视频
public static final int MSG_WATERMARK_PARA_ERROR = 21; //视频水印参数出错
public static final int MSG_CAMERA_PREVIEW_SIZE_NOT_SUPPORT_ERROR = 22; //摄像头不支持设置的preview size
public static final int MSG_START_PREVIEW_FINISHED = 23; //开始preview完成
public static final int MSG_START_LIVESTREAMING_FINISHED = 24; //开始直播完成
public static final int MSG_STOP_LIVESTREAMING_FINISHED = 25; //停止直播完成
public static final int MSG_STOP_VIDEO_CAPTURE_FINISHED = 26; //停止视频采集完成
public static final int MSG_STOP_AUDIO_CAPTURE_FINISHED = 28; //停止音频采集完成
public static final int MSG_SWITCH_CAMERA_FINISHED = 30; //切换摄像头完毕
public static final int MSG_SEND_STATICS_LOG_FINISHED = 31; //发送统计信息完毕
public static final int MSG_SERVER_COMMAND_STOP_LIVESTREAMING = 32; //服务器下发停止直播的命令
public static final int MSG_SEND_HEARTBEAT_LOG_FINISHED = 33; //发送心跳信息完毕
public static final int MSG_CAMERA_NOT_SUPPORT_FLASH = 34; //用户所设置的采集分辨率,摄像头并不支持
public static final int MSG_GET_STATICS_INFO = 35; //获得统计信息完毕
public static final int MSG_BAD_NETWORK_DETECT = 36; //连续一分钟视频帧率和码率都是0的消息
public static final int MSG_SCREENSHOT_FINISHED = 37; //直播中视频截图完成消息
public static final int MSG_SET_CAMERA_ID_ERROR = 38; //设置camera id出错(单摄像头设备常见)
public static final int MSG_SET_GRAFFITI_ERROR = 39; //设置视频涂鸦出错
public static final int MSG_MIX_AUDIO_FINISHED = 40: //伴音一首MP3文件结束
public static final int MSG_URL_FORMAT_NOT_RIGHT = 41: //推流URL格式不正确(例如使用拉流url进行推流)
public static final int MSG_URL_IS_EMPTY = 42: //推流URL为空
public static final int MSG_VIDEO_CROP_ERROR = 43;  //视频剪裁失败
public static final int MSG_SPEED_CALC_SUCCESS = 44; //测速成功
public static final int MSG_SPEED_CALC_FAIL = 45; //测速失败

同时,需要开发者继承如下接口,处理SDK抛出的事件。

handleMessage(int msg, Object object);

4 如何使用SDK API接口

特别说明:如要断线重连,需先调用stopLiveStreaming,等待接受到SDK回调消息 MSG_STOP_LIVESTREAMING_FINISHED之后才能继续调用initLiveStream、startLiveStreaming重新开始推流

4.1 创建推流实例

4.1.1 API介绍

SDK在初始化推流阶段,设置推流地址,配置推流参数,创建推流session,您可以根据是否需要定制直播参数而选择

4.1.2 API原型

/**
*  初始化推流实例
*  @param  lsMediaCapturePara  {@link LsMediaCapturePara }初始化参数类型
*/
public lsMediaCapture(LsMediaCapturePara lsMediaCapturePara)

4.1.3 LsMediaCapturePara参数说明

参数 类型 说明
setContext Context 设置SDK上下文,建议使用ApplicationContext
setMessageHandler lsMessageHandler 设置SDK消息回调接口
setLogLevel lsLogUtil.LogLevel 设置日志级别(info、warn、error)
setUploadLog boolean 设置是否上传日志

4.1.4 示例


lsMediaCapture.LsMediaCapturePara lsMediaCapturePara = new lsMediaCapture.LsMediaCapturePara();
lsMediaCapturePara.setContext(getApplicationContext()); //设置SDK上下文(建议使用ApplicationContext)
lsMediaCapturePara.setMessageHandler(this); //设置SDK消息回调
lsMediaCapturePara.setLogLevel(lsLogUtil.LogLevel.INFO); //日志级别
lsMediaCapturePara.setUploadLog(publishParam.uploadLog);//是否上传SDK日志
mLSMediaCapture = new lsMediaCapture(lsMediaCapturePara);

4.2 打开预览画面

4.2.1 API介绍

4.2.2 API原型

/**
 *  打开视频预览
 *  @param videoView {@link com.netease.vcloud.video.render.NeteaseView}
 *  @param frontCamera 是否前置摄像头
 *  @param filter 是否开启滤镜
 *  @param quality 视频能力
 *  @param scale_16x9 是否强制 16:9 模式
 *
 */
public void startVideoPreview(NeteaseView videoView,boolean frontCamera,boolean filter,VideoQuality quality,boolean scale_16x9)
/**
 *  打开视频预览
 *  @param videoView {@link com.netease.vcloud.video.render.NeteaseView}
 *  @param frontCamera 是否前置摄像头
 *  @param filter 是否开启滤镜
 *  @param para 视频采集以及编码的参数
 */
public void startVideoPreviewEx(NeteaseView videoView,boolean frontCamera,boolean filter,VideoPara para)

4.2.3 参数说明

参数 类型 说明
videoView NeteaseView SDK提供的预览显示View,用户可以布局到自己的APP中
frontCamera boolean 是否默认前置摄像头
filter boolean 是否使用SDK内置滤镜
quality VideoQuality MEDIUM:标清 480360,HIGH:高清 640480,SUPER:超清 960540,SUPER_HIGH:超高清 1280720
scale_16x9 boolean 是否按16:9宽高比例

VideoPara参数说明

参数 类型 说明
setWidth int 设置编码宽
setHeight int 设置编码高
setFps int 设置编码帧率
setBitrate int 设置编码码率

4.2.4 示例

NeteaseView videoView = (NeteaseView) findViewById(R.id.videoview);
boolean frontCamera = publishParam.frontCamera; // 是否前置摄像头
boolean mScale_16x9 = publishParam.isScale_16x9; //是否强制16:9
lsMediaCapture.VideoQuality videoQuality = publishParam.videoQuality; //视频模板(SUPER_HIGH 1280*720、SUPER 960*540、HIGH 640*480、MEDIUM 480*360、LOW 352*288)
mLSMediaCapture.startVideoPreview(videoView,frontCamera,mUseFilter,videoQuality,mScale_16x9);


// SDK 默认提供 /** 标清 480*360 */MEDIUM, /** 高清 640*480 */HIGH,
// /** 超清 960*540 */SUPER,/** 超高清 (1280*720) */SUPER_HIGH  四个模板,
// 用户如果需要自定义分辨率可以调用startVideoPreviewEx 接口并参考以下参数
// 码率计算公式为 width * height * fps * 9 /100;

//        lsMediaCapture.VideoPara para = new lsMediaCapture.VideoPara();
//        para.setHeight(720);
//        para.setWidth(1280);
//        para.setFps(15);
//        para.setBitrate(1200*1024);
//        mLSMediaCapture.startVideoPreviewEx(videoView,frontCamera,mUseFilter,para);

4.2.5 特殊说明

调用startPreview之后,需要检查SDK回调信息,如果返回MSG_START_PREVIEW_ERROR,则说明打开摄像头失败,建议提示用户检查权限

4.3 开始推流

4.3.1 API介绍

4.3.2 API原型

/**
 *  初始化推流所需信息
 *
 *  @param  paraCtx 推流参数
 *  @param pushUrl 推流地址
 *  @return 初始化推流是否成功:true/false
 */
public boolean initLiveStream(LiveStreamingPara paraCtx,String pushUrl)
/**
*  开始直播
*  
*/
public void startLiveStreaming()

4.3.3 参数说明

初始化推流参数说明LiveStreamingPara

参数 类型 说明
setStreamType StreamType AUDIO:但音频,VIDEO:单视频,AV:音视频双流
setFormatType FormatType MP4:MP4纯录制,RTMP:RTMP 推流,RTMP_AND_MP4:边推RTMP 边录制MP4
setRecordPath String 设置本地录制地址,FormatType为MP4或RTMP_AND_MP4有效
setQosOn boolean true:开启 false:关闭,默认开启Qos
setAutoRecord boolean 当formatType为MP4或RTMP_AND_MP4是否推流开始就自动开始录制,默认自动在上述两种模式下推流一开始就录制,只有需要推流与录制不同时进行的用户才需要关心,正常情况下,用户无需关心
setSyncTimestamp(syncTimestamp,absoluteTime) boolean syncTimestamp true:发送同步时间戳 false:不发送,默认不发送。 absoluteTime true:绝对时间(unix时间),false:相对于推流的时间(从0开始)
setStreamTimestampPassthrough boolean true:网易云透传时间戳 false:不透传,默认不透传

4.3.4 示例

mLiveStreamingPara = new lsMediaCapture.LiveStreamingPara();
mLiveStreamingPara.setStreamType(publishParam.streamType); // 推流类型 AV、AUDIO、VIDEO
mLiveStreamingPara.setFormatType(publishParam.formatType); // 推流格式 RTMP、MP4、RTMP_AND_MP4
mLiveStreamingPara.setRecordPath(publishParam.recordPath);//formatType 为 MP4 或 RTMP_AND_MP4 时有效
mLiveStreamingPara.setQosOn(publishParam.qosEnable);
//mLiveStreamingPara.setSyncTimestamp(true,false);//(直播答题使用)网易云透传时间戳,不依赖CDN方式,不需要额外开通(必须包含视频流)
//mLiveStreamingPara.setStreamTimestampPassthrough(true); //(直播答题使用)网易云透传时间戳,但完全透传功能需要联系网易云开通,支持纯音频

mLSMediaCapture.initLiveStream(mLiveStreamingPara,mliveStreamingURL);
mLSMediaCapture.startLiveStreaming();

4.3.5 特殊说明

调用initLiveStream、startLiveStream之后,需要检查SDK回调信息,如果返回MSG_START_LIVESTREAMING_FINISHED,则说明成功开始推流,如果返回MSG_INIT_LIVESTREAMING_OUTFILE_ERROR、MSG_INIT_LIVESTREAMING_VIDEO_ERROR、MSG_INIT_LIVESTREAMING_AUDIO_ERROR则说明推流失败,用户需要检查推流地址是否有效或者被禁用

4.4 结束推流

4.4.1 API介绍

4.4.2 API原型

/**
*  结束推流
*  
*/
public void stopLiveStreaming()
/**
 *  销毁视频预览实例
 */
public void destroyVideoPreview()
/**
*  关闭视频预览
*/
public void stopVideoPreview()
/**
 *  反初始化推流实例
 *  @param  uninitNow 立即反初始化实例的标记
 */
public void uninitLsMediaCapture(boolean uninitNow)

4.4.3 参数说明

参数 类型 说明
uninitNow boolean true:马上释放,false:等待推流结束后释放。(如推流已开始必须设置为false)

4.4.4 示例

mLSMediaCapture.stopLiveStreaming();
mLSMediaCapture.stopVideoPreview();
mLSMediaCapture.destroyVideoPreview();
//反初始化推流实例,当它与stopLiveStreaming连续调用时,参数为false
mLSMediaCapture.uninitLsMediaCapture(false);

4.4.5 特殊说明

uninitLsMediaCapture与stopLiveStreaming连续调用时,参数必须为false,用于SDK异步结束推流释放资源。 如果用户已先调用了stopLiveStreaming,并且等到了MSG_STOP_LIVESTREAMING_FINISHED消息,那可以直接设置为true

自此一个简单的直播推流流程就结束了,用户需要一些高级的操作,可以继续参考以下的API介绍

4.5 音视频推流操作

4.5.1 API介绍

4.5.2 API原型

/**
*  暂停视频推流
*/
public void pauseVideoLiveStream()
/**
*  继续视频推流
*/
public void resumeVideoLiveStream()
/**
*  暂停音频推流
*/
public void pauseAudioLiveStream()
/**
*  继续音频推流
*/
public void resumeAudioLiveStream()
/**
*  程序切后台后继续视频编码,编码最后一帧图像
*/
public void backgroundVideoEncode()
/**
*  程序切回前台后恢复视频编码
*/
public void resumeVideoEncode()
/**
*  程序切后台后继续音频编码,编码静音帧
*/
public void backgroundAudioEncode()
/**
*  程序切回前台后恢复音频编码
*/
public void resumeAudioEncode()

4.5.3 参数说明

4.5.4 示例

@Override
protected void onPause(){
    Log.i(TAG,"Activity onPause");
    if(mLSMediaCapture != null) {          
        if(!m_tryToStopLivestreaming && m_liveStreamingOn)
        {
            if(mLiveStreamingPara.getStreamType() != AUDIO) {
                //推最后一帧图像
                mLSMediaCapture.backgroundVideoEncode();
            }
            else {
                //推静音帧
                mLSMediaCapture.backgroundAudioEncode();
            }
        }
    }
    super.onPause(); 
}
@Override
protected void onResume(){
    Log.i(TAG,"Activity onResume");
    super.onResume();
    if(mLSMediaCapture != null && m_liveStreamingOn) {
        if(mLiveStreamingPara.getStreamType() != AUDIO) {
            //关闭推流固定图像,正常推流
            mLSMediaCapture.resumeVideoEncode();
        }
        else  {
            //关闭推流静音帧
            mLSMediaCapture.resumeAudioEncode();
        }
    }
}

4.5.5 特殊说明

这里的暂停与切后台的差别是,暂停不会关闭摄像头只是不继续推流本地预览还在,切后台则会释放摄像头资源并发送最后一帧画面。同时暂停音频流是发送静音帧

4.6 伴音相关操作

4.6.1 API介绍

4.6.2 API原型

/**
*  开始播放伴音文件
*  @param musicURL 音频文件地址/文件名
*  @param loop 是否循环播放
*  @return 播放伴音文件成功或者失败
*/
 public boolean startPlayMusic(String musicURL,boolean loop)
 /**
 *  结束播放伴音文件,释放播放文件
*  @return 停止伴音成功或者失败
 */
public boolean stopPlayMusic()
/**
*  暂停播放伴音文件
*  
*  @return 暂停播放伴音文件成功或者失败
*/
public boolean pausePlayMusic()
/**
*  继续播放伴音文件
*  
*  @return 继续伴音成功或者失败
*/
public boolean resumePlayMusic()

4.7.3 参数说明

参数 类型 说明
musicURL String 音频文件地址
loop boolean 伴音音频文件是否单曲循环

4.7.4 示例

//伴音开关的控制
if(audioMixMsg == 1)
{
     if(mMixAudioFilePath.isEmpty())
         return;

     if(mLSMediaCapture != null) {  
        mLSMediaCapture.startPlayMusic(mMixAudioFilePath,false);
     }                 
}
else if (audioMixMsg == 2)
{
     if(mLSMediaCapture != null){
         mLSMediaCapture.resumePlayMusic();
     }
}
else if(audioMixMsg == 3)
{
      if(mLSMediaCapture != null){
          mLSMediaCapture.pausePlayMusic();
      }
}
else if(audioMixMsg == 4)
{
      if(mLSMediaCapture != null){
          mLSMediaCapture.stopPlayMusic();
      }
}

4.6.5 特殊说明

4.7 音视频数据操作

4.7.1 API介绍

4.7.2 API原型

/**
 * 设置摄像头采集原始数据回调
 * @param callback 裸流回调接口(NV21格式)
 */
public void setCaptureRawDataCB(VideoCallback callback)
/**
 * 设置麦克风采集原始数据回调
 * @param callback 裸流回调接口(PCM格式)
 */
public void setAudioRawDataCB(lsAudioCaptureCallback callback)
/**
 * 自定义采集的YUV数据(该接口不需要调用 {@link #startVideoPreview})
 * @param buffer YUV数据
 * @param videoWidth 视频原始宽
 * @param videoHeight 视频原始高
 * @param bitrate 编码码率
 * @param framerate 编码帧率
 */
public void sendCustomYUVData(byte[] buffer,int videoWidth,int videoHeight,int bitrate, int framerate)
/**
 * 自定义采集的PCM数据
 * @param buffer PCM数据
 */
public void sendCustomPCMData(byte[] buffer)

4.7.3 参数说明

参数 类型 说明
callback VideoCallback 视频回调函数
callback lsAudioCaptureCallback 音频回调函数
buffer byte[] 视频数据(YUV I420格式)
videoWidth int 视频宽
videoHeight int 视频高
bitrate int 视频码率
framerate int 视频帧率
buffer byte[] 音频数据(PCM)

4.7.4 示例

//********** 摄像头采集原始数据回调(非滤镜模式下开发者可以修改该数据,美颜增加滤镜等,推出的流便随之发生变化) *************//
if(mVideoCallback){
    senseEffect();
    mLSMediaCapture.setCaptureRawDataCB(new VideoCallback() {
        @Override
        /**
         * 摄像头采集数据回调
         * @param data 摄像头采集的原始数据(NV21格式)
         * @param textureId  摄像头采集的纹理ID
         * @param width 视频宽
         * @param height 视频高
         * @param orientation 相机采集角度
         * @return 滤镜后的纹理ID (<=0 表示没有进行滤镜或是滤镜库返回的是buffer数据(NV21格式),sdk将会使用buffer数据进行后续处理)
         */
        public int onVideoCapture(byte[] data, int textureId, int width, int height, int orientation) {
            if(mSenseEffect != null){
                //返回纹理方式
                return mSenseEffect.effect(textureId,data,width,height,orientation);
            }else {
                //返回buffer方式
                for(int j = 0; j< width * height /4;j++){
                    data[j] = 0; //data必须还是原来的NV21格式
                }
                return 0;
            }
        }
    });
}
//********** 麦克风采集原始数据回调(开发者可以修改该数据,进行降噪、回音消除等,推出的流便随之发生变化) *************//
if(mAudioCallback){
    mLSMediaCapture.setAudioRawDataCB(new lsAudioCaptureCallback() {
        int i = 0;
        @Override
        public void onAudioCapture(byte[] data, int len) {
            // 这里将data直接修改,SDK根据修改后的data数据直接推流
            if(i % 10 == 0){
                for(int j = 0; j< 1000;j++){
                    data[j] = 0;
                }
            }
            i++;
        }
    });
}
//【示例代码】设置自定义视频采集类型(如果是自定义YUV则不需要调用startVideoPreview接口)
    mLSMediaCapture.setSourceType(lsMediaCapture.SourceType.CustomAV);
    //自定义输入默认是横屏,正的yuv数据

//【示例代码 customVideo】设置自定义视频采集逻辑 (自定义视频采集逻辑不要调用startPreview,也不用初始化surfaceView)
new Thread() {  //视频采集线程
    @Override
    public void run() {
        while (true) {
            try {
                if(!m_liveStreamingOn){
                    continue;
                }
                int width = 352;
                int height = 288;
                int fps = 20;
                int bitrate = width * height * fps * 9 /100;
                FileInputStream in = new FileInputStream(String.format(Locale.getDefault(),"/sdcard/dump_%d_%d.yuv",width,height));
                int len = width * height * 3 / 2;
                byte buffer[] = new byte[len];
                int count;
                while ((count = in.read(buffer)) != -1) {
                    if (len == count) {
                        mLSMediaCapture.sendCustomYUVData(buffer,width,height,bitrate,fps);
                    } else {
                        break;
                    }
                    sleep(50, 0);
                }
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}.start();
//【示例代码】结束

//【示例代码2】设置自定义音频采集逻辑(音频采样位宽必须是16)
new Thread() {  //音频采集线程
    @Override
    public void run() {
        while (true) {
            try {
                if(!m_liveStreamingOn){
                    continue;
                }
                FileInputStream in = new FileInputStream("/sdcard/dump.pcm");
                int len = 2048;
                byte buffer[] = new byte[len];
                int count;
                while ((count = in.read(buffer)) != -1) {
                    if (len == count) {
                        mLSMediaCapture.sendCustomPCMData(buffer);
                    } else {
                        break;
                    }
                    sleep(20, 0);
                }
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}.start();
//【示例代码】结束

4.7.5 特殊说明

4.8 直播前测速操作

4.8.1 API介绍

4.8.2 API原型

/**
 * 开始测速
 * @param url 推流地址
 * @param bytes 测速文件大小
 */
public void startSpeedCalc(String url, long bytes)
/**
 *  停止测速
 */
public void stopSpeedCalc()

4.8.3 参数说明

参数 类型 说明
url String 测速地址
bytes long 上传数据大小(仅限于文件上传类型,经测试,NTS2不能超过500k(含500k)),单位是字节,500k=500*1024,默认为499k(控制最大不超过10M

4.8.4 示例

if(mLSMediaCapture != null) {
    if (mSpeedCalcRunning) {
        mLSMediaCapture.stopSpeedCalc();
        mSpeedCalcRunning = false;
        showToast("结束测速");
    } else {
        showToast("开始测速");
        mLSMediaCapture.startSpeedCalc(mliveStreamingURL, 1024 * 500);
        mSpeedCalcRunning = true;
    }
}

4.8.5 特殊说明

4.9 摄像头操作

4.9.1 API介绍

4.9.2 API原型

/**
*  设置闪光灯开关
*  @param  onFlash     闪光灯开关
*/
public void setCameraFlashPara(boolean onFlash)
/**
*  获取当前视频缩放比例
*  @return 当前视频缩放比例
*/    
public int getCameraZoomValue()
/**
*  获取摄像头支持的最大视频缩放比例
*  @return 摄像头支持的最大视频缩放比例
*/    
public int getCameraMaxZoomValue()
/**
*  设置视频缩放相关参数
*  @param  zoomValue     缩放参数
*/
public void setCameraZoomPara(int zoomValue)
 /**
 *   手动对焦一次
 */
 public void setCameraFocus()
/**
 * 设置是否自动对焦(自动对焦默认开启)
 * @param isAutoFocus true:开启自动对焦   false:关闭自动对焦
 */
public void setCameraAutoFocus(boolean isAutoFocus)
/**
 *  切换前后摄像头
 */
public void switchCamera()
/**
 *  获取摄像头曝光强度
 *  @return 摄像头曝光强度
 */
public int getExposureCompensation()
/**
 *  获取摄像头支持的最小曝光强度
 *  @return 摄像头支持的最小曝光强度
 */
public int getMinExposureCompensation()
/**
 *  获取摄像头支持的最大曝光强度
 *  @return 摄像头支持的最大曝光强度
 */
public int getMaxExposureCompensation()
/**
 * 设置摄像头曝光强度
 * @param value 摄像头曝光强度 (根据获取的最大和最小曝光度进行设置)
 */
public void setExposureCompensation(int value)
/**
 * 切换分辨率
 * @param quality 需要切换的模板
 * @param scale_16x9 是否16:9
 */
public void changeCaptureFormat(VideoQuality quality,boolean scale_16x9)
/**
 * 切换分辨率
 * @param videoPara 自定义分辨率
 */
public void changeCaptureFormatEx(lsMediaCapture.VideoPara videoPara)

4.9.3 参数说明

参数 类型 说明
onFlash boolean 打开或者关闭摄像头flash
zoomValue int 摄像头变焦功能属性:拉伸值,[1,maxZoomScale]
isAutoFocus boolean true:开启自动对焦 false:关闭自动对焦
value int 曝光度 [MinExposureCompensation,MaxExposureCompensation]
quality VideoQuality MEDIUM:标清 480360,HIGH:高清 640480,SUPER:超清 960540,SUPER_HIGH:超高清 1280720
scale_16x9 boolean 是否按16:9宽高比例

VideoPara参数说明

参数 类型 说明
setWidth int 设置编码宽
setHeight int 设置编码高
setFps int 设置编码帧率
setBitrate int 设置编码码率

4.9.4 示例

//闪光灯
if(mLSMediaCapture != null){
    mFlashOn = !mFlashOn;
    mLSMediaCapture.setCameraFlashPara(mFlashOn);
    if(mFlashOn){
        flashBtn.setImageResource(R.drawable.flashstop);
    }else {
        flashBtn.setImageResource(R.drawable.flashstart);
    }
}
//曝光度
if(mLSMediaCapture != null){
    int max = mLSMediaCapture.getMaxExposureCompensation();
    mLSMediaCapture.setExposureCompensation((progress-50) * max /50);
}
//切换分辨率
private void changeFormat(){
    int index = count % 4;
    count ++ ;
    boolean is16x9 = true;
    switch (index){
        case 0:
            mLSMediaCapture.changeCaptureFormat(lsMediaCapture.VideoQuality.SUPER_HIGH,is16x9);
            break;
        case 1:
            mLSMediaCapture.changeCaptureFormat(lsMediaCapture.VideoQuality.SUPER,is16x9);
            break;
        case 2:
            mLSMediaCapture.changeCaptureFormat(lsMediaCapture.VideoQuality.HIGH,is16x9);
            break;
        case 3:
            mLSMediaCapture.changeCaptureFormat(lsMediaCapture.VideoQuality.MEDIUM,is16x9);
            break;
    }
}

4.9.5 特殊说明

4.10 镜像相关操作

4.10.1 API介绍

4.10.2 API原型

/**
 *  直播过程中,开关本地预览镜像效果(只对前置摄像头有效)
 * @param mirror 是否镜像
 */
public void setPreviewMirror(boolean mirror)
/** 
*   直播过程中,开关视频推流镜像效果(只对前置摄像头有效)
*   @param mirror 是否镜像(观众端)
*/
public void setVideoMirror(boolean mirror)

4.10.3 参数说明

4.10.4 示例

if(mLSMediaCapture != null){
    mLSMediaCapture.setVideoMirror(R.id.live_config_push_mirror_on == checkedId);
}
if(mLSMediaCapture != null){
    mLSMediaCapture.setWaterPreview(R.id.live_config_water_on == checkedId);
}

4.10.5 特殊说明

4.11 视频截图操作

4.11.1 API介绍

4.11.2 API原型

/**
 *   直播过程中,开启截图
 */
 public void enableScreenShot()

4.11.3 参数说明

4.11.4 示例

private void capture(){
    if(mLSMediaCapture != null){
        mLSMediaCapture.enableScreenShot();
    }
}

case MSG_SCREENSHOT_FINISHED://视频截图完成后的消息反馈
{
  getScreenShotByteBuffer((Bitmap) object);

  break;
}

4.11.5 特殊说明

截图在SDK消息回调中返回,为bitmap类型

4.12 滤镜相关操作

4.12.1 API介绍

4.12.2 API原型

 /**
 *   设置滤镜类型
 *   @param filterType 滤镜类型
 */
 public void setFilterType(VideoEffect.FilterType filterType)
 /**
 *   设置滤镜强度
 *   @param filterStrength 滤镜强度 (0 - 1)
 */
 public void setFilterStrength(float filterStrength)
/**
 *   设置磨皮强度
 *   @param level 磨皮强度 (0 - 5)
 */
 public void setBeautyLevel(int level)

4.12.3 参数说明

滤镜类型VideoEffect.FilterType参数说明

参数 说明
none 无滤镜
clean 干净
fairytale 童话
nature 自然
healthy 健康
tender 温柔
whiten 美白
参数 类型 说明
filterStrength float 滤镜强度 (0 - 1)
level int 磨皮强度 (0 - 5)

4.12.4 示例

switch (v.getId()){
    case R.id.brooklyn:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.brooklyn);
        break;
    case R.id.clean:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.clean);
        break;
    case R.id.nature:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.nature);
        break;
    case R.id.healthy:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.healthy);
        break;
    case R.id.pixar:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.pixar);
        break;
    case R.id.tender:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.tender);
        break;
    case R.id.whiten:
        mLSMediaCapture.setFilterType(VideoEffect.FilterType.whiten);
        break;
    default:
        break;

}
//滤镜强度
if(mLSMediaCapture != null){
    float param;
    param = (float)progress/100;
    mLSMediaCapture.setFilterStrength(param);
}
//磨皮强度
if(mLSMediaCapture != null){
    int param;
    param = progress/20;
    mLSMediaCapture.setBeautyLevel(param);
}

4.12.5 特殊说明

4.13 水印相关操作

4.13.1 API介绍

4.13.2 API原型

/**
 * 设置涂鸦
 * @param bitmap 涂鸦图片
 * @param x 水印水平坐标X,整个图像左上角为(0,0)点
 * @param y 水印垂直坐标Y,整个图像左上角为(0,0)点
 */
public void setGraffitiPara(Bitmap bitmap, int x, int y)
/**
 * 是否显示本地涂鸦
 * @param preview true:本地显示 false: 本地不显示
 */
public void setGraffitiPreview(boolean preview)
/**
 *  设置视频水印相关参数
 *  @param  bitmap     水印文件
 * @param rect 水印具体位置(上下左右中四个基本位置)
 * @param x 距离 rect 的 x 坐标
 * @param y 距离 rect 的 y 坐标
 */
public void setWaterMarkPara(Bitmap bitmap, VideoEffect.Rect rect, int x, int y)
/**
 * 是否显示本地水印
 * @param preview true:本地显示 false: 本地不显示
 */
public void setWaterPreview(boolean preview)
/**
 *  设置视频动态水印相关参数
 *  @param  bitmapArray               水印图片数组
 *  @param  rect                     水印具体位置(上下左右中四个基本位置)
 *  @param  x                         距离 rect 的 x 坐标
 *  @param  y                         距离 rect 的 y 坐标
 *  @param  fps                    动态水印的叠加帧率
 *  @param  looped                 动态水印是否循环叠加的标志
 */
public void setDynamicWaterMarkPara(Bitmap[] bitmapArray, VideoEffect.Rect rect,int x, int y, int fps, boolean looped)
/**
 * 是否显示本地动态水印
 * @param preview true:本地显示 false: 本地不显示
 */
public void setDynamicWaterPreview(boolean preview)

4.13.3 参数说明

参数 类型 说明
bitmap Bitmap 图像
rect VideoEffect.Rect 上下左右中四个基本位置
x int 距离 rect 的 水平坐标
y int 距离 rect 的 垂直坐标
fps int 动态水印的叠加帧率
looped int 动态水印是否循环叠加的标志

4.13.4 示例

private void addWaterMark(){
    if(mLSMediaCapture != null){
        Bitmap water = BitmapFactory.decodeResource(getResources(),R.drawable.water);
        int x = 120;
        int y = 60;
        mLSMediaCapture.setWaterMarkPara(water, VideoEffect.Rect.leftTop,x,y);
    }
}
Bitmap[] bitmaps;
private void addDynamicWaterMark(){
    if(mLSMediaCapture != null){
        int x = 0;
        int y = 0;
        int fps = 1; //水印的帧率
        boolean looped = true; //是否循环
        String[] waters;
        try {
            waters = getAssets().list("dynamicWaterMark");
            bitmaps = new Bitmap[waters.length];
            for(int i = 0; i< waters.length;i++){
                waters[i] = "dynamicWaterMark/" + waters[i];
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                Bitmap tmp = BitmapFactory.decodeStream(getAssets().open(waters[i]));
                bitmaps[i] = tmp;
            }
            mLSMediaCapture.setDynamicWaterMarkPara(bitmaps,VideoEffect.Rect.center,x,y,fps,looped);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
private Thread mGraffitiThread;
private boolean mGraffitiOn = false;
private void addGraffiti(){
    if(mGraffitiThread != null){
        return;
    }
    mGraffitiOn = true;
    mGraffitiThread = new Thread(){
        @Override
        public void run() {
            int x = 180;
            int y = 180;
            while (mGraffitiOn && bitmaps != null && mLSMediaCapture != null){
                for(Bitmap bitmap:bitmaps){
                    if(!mGraffitiOn){
                        break;
                    }
                    SystemClock.sleep(1000);
                    if(mLSMediaCapture != null){
                        mLSMediaCapture.setGraffitiPara(bitmap,x,y);
                    }
                }
            }
        }
    };
    mGraffitiThread.start();
}

4.13.5 特殊说明

4.14 直播辅助操作

4.14.1 API介绍

4.14.2 API原型

lsMediaCapture.LsMediaCapturePara lsMediaCapturePara = new lsMediaCapture.LsMediaCapturePara();
lsMediaCapturePara.setMessageHandler(this); //设置SDK消息回调
case MSG_GET_STATICS_INFO://获取统计信息的反馈消息
{
  Message message = Message.obtain(mHandler, MSG_GET_STATICS_INFO);
  Statistics statistics = (Statistics) object;
  Bundle bundle = new Bundle();  
  bundle.putInt("FR", statistics.videoEncodeFrameRate);
  bundle.putInt("VBR", statistics.videoRealSendBitRate);
  bundle.putInt("ABR", statistics.audioRealSendBitRate);
  bundle.putInt("TBR", statistics.totalRealSendBitRate);
  bundle.putInt("networkLevel", statistics.networkLevel);
  bundle.putString("resolution", statistics.videoEncodeWidth + " x " + statistics.videoEncodeHeight);
  message.setData(bundle);
  if(mHandler != null) {
      mHandler.sendMessage(message);
  }
  break;
}
/**
 * 更新自定义统计数据
 * @param jsonObject 自定义统计数据
 */
public void updateCustomStatistics(JSONObject jsonObject)
lsMediaCapturePara.setLogLevel(lsLogUtil.LogLevel.INFO); //日志级别
/**
 *   获取SDK版本号
 *   @return SDK版本号
 */
public String getSDKVersion()
/**
 * 获取当前推流时间戳,对应 setSyncTimestamp
 * @return 当前推流的时间戳(毫秒)
 */
public long currentSyncTimestamp()
/**
 * 获取当前时间戳,对应setStreamTimestampPassthrough 一起使用
 * @return 当前同步时间戳(毫秒)
 */
public long currentStreamTimestamp()
/**
 * 在码流中发送自定义数据
 * @param customData 数据内容
 * @return 0:发送成功,1: 参数长度和值域校验失败,2: 超过并发数限制(5个)
 */
public int sendCustomData(CustomData customData)

4.14.3 参数说明

参数 类型 说明
jsonObject JSONObject 自定义统计数据(key,value)
logLevel lsLogUtil.LogLevel 信息的级别

4.14.4 示例

try {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("appkey","1111");
    jsonObject.put("uid","2222");
    mLSMediaCapture.updateCustomStatistics(jsonObject);
}catch (Exception e){
    e.printStackTrace();
}

4.14.5 特殊说明

5 代码示例

/**   6.0权限处理     **/
private boolean bPermission = false;
private final int WRITE_PERMISSION_REQ_CODE = 100;
private boolean checkPublishPermission() {
    if (Build.VERSION.SDK_INT >= 23) {
        List<String> permissions = new ArrayList<>();
        if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(ConfigActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(ConfigActivity.this, Manifest.permission.CAMERA)) {
            permissions.add(Manifest.permission.CAMERA);
        }
        if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(ConfigActivity.this, Manifest.permission.RECORD_AUDIO)) {
            permissions.add(Manifest.permission.RECORD_AUDIO);
        }
        if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(ConfigActivity.this, Manifest.permission.READ_PHONE_STATE)) {
            permissions.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (permissions.size() != 0) {
            ActivityCompat.requestPermissions(ConfigActivity.this,
                    (String[]) permissions.toArray(new String[0]),
                    WRITE_PERMISSION_REQ_CODE);
            return false;
        }
    }
    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case WRITE_PERMISSION_REQ_CODE:
            for (int ret : grantResults) {
                if (ret != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
            }
            bPermission = true;
            break;
        default:
            break;
    }
}
//以下为SDK调用主要步骤,请用户参考使用
//1、创建直播实例
lsMediaCapture.LsMediaCapturePara lsMediaCapturePara = new lsMediaCapture.LsMediaCapturePara();
lsMediaCapturePara.setContext(getApplicationContext()); //设置SDK上下文(建议使用ApplicationContext)
lsMediaCapturePara.setMessageHandler(this); //设置SDK消息回调
lsMediaCapturePara.setLogLevel(lsLogUtil.LogLevel.INFO); //日志级别
lsMediaCapturePara.setUploadLog(publishParam.uploadLog);//是否上传SDK日志
mLSMediaCapture = new lsMediaCapture(lsMediaCapturePara);

//2、设置直播参数
mLiveStreamingPara = new lsMediaCapture.LiveStreamingPara();
mLiveStreamingPara.setStreamType(publishParam.streamType); // 推流类型 AV、AUDIO、VIDEO
mLiveStreamingPara.setFormatType(publishParam.formatType); // 推流格式 RTMP、MP4、RTMP_AND_MP4
mLiveStreamingPara.setRecordPath(publishParam.recordPath);//formatType 为 MP4 或 RTMP_AND_MP4 时有效
mLiveStreamingPara.setQosOn(publishParam.qosEnable);
mLiveStreamingPara.setQosEncodeMode(publishParam.qosEncodeMode); //1:流畅优先, 2:清晰优先 默认流畅优先

//3、 预览参数设置
NeteaseView videoView = (NeteaseView) findViewById(R.id.videoview);
boolean frontCamera = publishParam.frontCamera; // 是否前置摄像头
boolean mScale_16x9 = publishParam.isScale_16x9; //是否强制16:9
if(publishParam.streamType != AUDIO){ //开启预览画面
    lsMediaCapture.VideoQuality videoQuality = publishParam.videoQuality; //视频模板(SUPER_HIGH 1280*720、SUPER 960*540、HIGH 640*480、MEDIUM 480*360、LOW 352*288)
    mLSMediaCapture.startVideoPreview(videoView,frontCamera,mUseFilter,videoQuality,mScale_16x9);
}

m_startVideoCamera = true;
if(mUseFilter){ //demo中默认设置为干净滤镜
    mLSMediaCapture.setBeautyLevel(5); //磨皮强度为5,共5档,0为关闭
    mLSMediaCapture.setFilterStrength(0.5f); //滤镜强度
    mLSMediaCapture.setFilterType(publishParam.filterType);
}


private boolean startAV(){
    //6、初始化直播
    m_liveStreamingInitFinished = mLSMediaCapture.initLiveStream(mLiveStreamingPara,mliveStreamingURL);
    if(mLSMediaCapture != null && m_liveStreamingInitFinished) {
        //7、开始直播
        mLSMediaCapture.startLiveStreaming();
        m_liveStreamingOn = true;

        if(mNeedWater){
            //8、设置视频水印参数(可选)
            addWaterMark();
            //9、设置视频动态水印参数(可选)
            addDynamicWaterMark();
        }
        if(mNeedGraffiti){
            //10、设置视频涂鸦参数(可选)
            addGraffiti();
        }
        return true;
    }
    return m_liveStreamingInitFinished;
}


//停止直播调用相关API接口
if(mLSMediaCapture != null && m_liveStreamingOn) {

    //停止直播,释放资源
    mLSMediaCapture.stopLiveStreaming();

    //如果音视频或者单独视频直播,需要关闭视频预览
    if(m_startVideoCamera)
    {
        mLSMediaCapture.stopVideoPreview();
        //消耗第三方滤镜
        releaseSenseEffect();
        mLSMediaCapture.destroyVideoPreview();
    }

    //反初始化推流实例,当它与stopLiveStreaming连续调用时,参数为false
    mLSMediaCapture.uninitLsMediaCapture(false);
    mLSMediaCapture = null;
}
//1、调用停止直播接口
if(mLSMediaCapture != null){
    mLSMediaCapture.stopLiveStreaming();
}

//2、等待SDK消息回调中的停止直接结束消息
case MSG_STOP_LIVESTREAMING_FINISHED://停止直播完成
{
  Log.i(TAG, "test: MSG_STOP_LIVESTREAMING_FINISHED");
  showToast("停止直播已完成");
  m_liveStreamingOn = false;
  startPauseResumeBtn.setClickable(true);
  break;
}

//3、重新初始化推流地址并直播
 mLSMediaCapture.initLiveStream(mLiveStreamingPara,mliveStreamingURL);
 mLSMediaCapture.startLiveStreaming();

6 API说明

有关API的详细说明,可参见SDK包中docs,打开index.html查看,或者打开下面的在线文档。

网易云视频直播推流LiveStreaming Android SDK API详细文档