直播
进阶功能
更新时间: 2021/11/02 10:39:15
音视频推流操作
- 中断、恢复视频推流
- 中断、恢复音频推流
API原型
/**
* 重启开始视频推流
* @warning 需要先启动推流startLiveStreamWithError,开启音视频推流,才可以中断视频推流,重启视频推流,
*/
- (void)resumeVideoLiveStream;
/**
* 中断视频推流
* @warning 需要先启动推流startLiveStreamWithError,开启音视频推流,才可以中断视频推流,重启视频推流,
*/
- (void)pauseVideoLiveStream;
/**
* 中断音频推流,
* @warning:需要先启动推流startLiveStreamWithError,开启音视频推流,才可以中断音频推流,重启音频推流,
*/
- (BOOL)pauseAudioLiveStream;
/**
* 重启音频推流,
* @warning:需要先启动推流startLiveStreamWithError,开启音视频推流,才可以中断音频推流,重启音频推流,
*/
- (BOOL)resumeAudioLiveStream;
参数说明
无
示例
- (void)videoBtnTapped:(UIButton *)sender {
if (sender.isSelected) {
[_mediaCapture pauseVideoLiveStream];
}else {
[_mediaCapture resumeVideoLiveStream];
}
}
- (void)audioBtnTapped:(UIButton *)sender {
if (sender.isSelected) {
[_mediaCapture pauseAudioLiveStream];
}else {
[_mediaCapture resumeAudioLiveStream];
}
}
特殊说明
这里的暂停音频流是发送静音帧
MP4录制操作
API介绍
- 开始mp4录制
- 停止mp4录制
API原型
/**
开始录制并保存本地文件(mp4录制)
@param recordFileName 本地录制的文件全路径
@param videoStreamingQuality 需要录制的mp4文件的分辨率,不能大于采集的分辨率
@return 是否成功
*/
- (BOOL)startRecord:(NSString *)recordFileName videoStreamingQuality:(LSVideoStreamingQuality)videoStreamingQuality;
/**
* 停止本地录制
*/
- (BOOL)stopRecord;
参数说明
参数 | 类型 | 说明 |
---|---|---|
recordFileName | NSString | 本地录制的文件全路径 |
videoStreamingQuality | LSVideoStreamingQuality | 录制的mp4文件的分辨率 |
示例
- (void)recordBtnTapped:(UIButton *)sender {
if (sender.isSelected) {
//以开始录制的时间作为时间戳,作为文件名后缀
NSString *fileName = @"/vcloud_";
NSDate *date = [NSDate date];
NSTimeInterval sec = [date timeIntervalSinceNow];
NSDate *currDate = [[NSDate alloc] initWithTimeIntervalSinceNow:sec];
NSDateFormatter *df = [NSDateFormatter new];
[df setDateFormat:@"yyyyMMddHHmmss"];
NSString *dfStr = [df stringFromDate:currDate];
fileName = [fileName stringByAppendingString:dfStr];
fileName = [fileName stringByAppendingString:@".mp4"];
//存储在Documents路径里
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documntsPath = arr[0];
NSString *savePath = [documentsPath stringByAppendingString:fileName];
BOOL isStrated = [_mediaCapture startRecord:savePath videoStreamingQuality:paraCtx.videoStreamingQuality];
if (isStrated) {
_isRecording = YES;
}
}else {
BOOL isStoped = [_mediaCapture stopRecord];
if (isStoped) {
_isRecording = NO;
}
}
}
特殊说明
无
混音相关操作
- 开始、结束、中断、恢复伴音文件;
- 设置混音强度
API原型
/**
* 开始播放混音文件
*
* @param musicURL 音频文件地址/文件名
* @param enableLoop 当前音频文件是否单曲循环
*/
- (BOOL)startPlayMusic:(NSString*)musicURL withEnableSignleFileLooped:(BOOL)enableLoop;
/**
* 结束播放混音文件,释放播放文件
*/
- (BOOL)stopPlayMusic;
/**
* 继续播放混音文件
*/
- (BOOL)resumePlayMusic;
/**
* 中断播放混音文件
*/
- (BOOL)pausePlayMusic;
/**
* 设置混音强度
* @param value 混音强度范围【1-10】
*/
- (void)setMixIntensity:(int)value;
参数说明
参数 | 类型 | 说明 |
---|---|---|
musicURL | NSString | 音频文件地址/文件名 |
enableLoop | BOOL | 前音频文件是否单曲循环 |
value | int | 混音强度范围【1-10 |
示例
switch (item) {
case 0://无伴音
{
[_mediaCapture stopPlayMusic];//关闭音效
}
break;
case 1://伴音1
{
NSString* musicFileURL = [[NSBundle mainBundle]pathForResource:@"lovest" ofType:@"mp3"];
if (musicFileURL == nil) {
NSLog(@"have not found music file");
return;
}
if (![_mediaCapture startPlayMusic:musicFileURL withEnableSignleFileLooped:YES]) {
NSLog(@"播放音乐文件失败");
return;
};
//从itunes music获取本地音乐作为伴音,该代码仅供参考,具体实现要考虑比较多细节
// [self convertMediaPickerController];
}
break;
case 2://伴音2
{
NSString* musicFileURL = [[NSBundle mainBundle]pathForResource:@"lovest" ofType:@"wav"];
if (musicFileURL == nil) {
NSLog(@"have not found music file");
return;
}
if (![_mediaCapture startPlayMusic:musicFileURL withEnableSignleFileLooped:YES]) {
NSLog(@"播放音乐文件失败");
return;
};
}
break;
default:
[_mediaCapture stopPlayMusic];//关闭音效
break;
}
特殊说明
无
音视频数据操作
- 采集的音视频数据回调给用户
- 用户将前处理好的音视频数据塞回给SDK
API原型
/**
采集模块采集的视频数据回调,交由外部进行自定义前处理,处理完后通过externalInputSampleBuffer发送给sdk
*/
@property(nonatomic, copy) void (^externalCaptureSampleBufferCallback)(CMSampleBufferRef sampleBuffer);
/**
将外部前处理之后的视频数据发送给sdk
@param sampleBuffer 视频数据
*/
-(void)externalInputSampleBuffer:(CMSampleBufferRef)sampleBuffer;
/**
* 麦克风采集到的原始裸数据的回调,交由外部进行自定义处理,同步处理
* param rawData 麦克风采集得到的裸数据,PCM格式
*/
@property (nonatomic,copy) void (^externalCaptureAudioRawData)(AudioBufferList *bufferList,NSInteger inNumberFrames);
/**
用户可以通过这个接口,将第三方采集的音频数据送回来,数据的格式要保持不变,由视频云sdk推流出去
@param bufferList 音频数据
@param inNumberFrames frames数据
*/
-(void)externalInputAudioBufferList:(AudioBufferList *)bufferList inNumberFrames:(NSInteger)inNumberFrames;
参数说明
参数 | 类型 | 说明 |
---|---|---|
sampleBuffer | CMSampleBufferRef | 视频帧 |
bufferList | AudioBufferList * | 音频帧 |
inNumberFrames | NSInteger | frames数据 |
示例
_mediaCapture.externalCaptureSampleBufferCallback = ^(CMSampleBufferRef sampleBuffer)
{
//NSLog(@"做一些视频前处理操作");
//然后塞给 推流sdk
[weakSelf.mediaCapture externalInputSampleBuffer:sampleBuffer];
};
_mediaCapture.externalCaptureAudioRawData = ^(AudioBufferList *bufferList,NSInteger inNumberFrames) {
// NSLog(@"做一些音频前处理操作");
//同步操作
if (!weakSelf.soundTouch) {
weakSelf.soundTouch = [[NESoundTouch alloc] initWithSampleRate:streamparaCtx.sLSAudioParaCtx.samplerate pitchSemiTones:8];
}
[weakSelf.soundTouch processSound:bufferList->mBuffers[0].mData number:inNumberFrames];
};
特殊说明
无
直播前测速操作
- 开始测速
- 结束测速
- 测速之前设置测速次数和上传数据大小
API原型
/**
开始测速
*/
-(void)startSpeedCalc:(NSString *)url success:(void(^)(NSMutableArray *array))success fail:(void(^)())fail;
/**
结束测速
*/
-(void)stopSpeedCalc;
/**
测速之前设置测速次数和上传数据大小
@param count 测速次数(默认为1次),测速之后,取平均值返回结果
@param capacity 上传数据大小(仅限于文件上传类型,经测试,NTS2不能超过500k(含500k)),单位是字节,500k=500*1024,默认为499k(控制最大不超过10M)
*/
-(void)setSpeedCacl:(NSInteger)count Capacity:(unsigned long long)capacity;
参数说明
参数 | 类型 | 说明 |
---|---|---|
url | NSString | 测速地址 |
success | void(^)(NSMutableArray *array) | 测速成功返回的结果列表 |
fail | void(^)() | 测速失败错误回调 |
count | NSInteger | 测速次数(默认为1次),测速之后,取平均值返回结果 |
capacity | unsigned long long | 上传数据大小(仅限于文件上传类型,经测试,NTS2不能超过500k(含500k)),单位是字节,500k=500*1024,默认为499k(控制最大不超过10M) |
示例
- (void)startSpeed:(id)sender
{
//测速之前设置测速次数和上传数据大小500k(默认可以不设):接口android之后会统一
[lsMedia setSpeedCacl:1 Capacity:499*1024];
if ([self.urlText length] > 0 && [self.urlText hasPrefix:@"rtmp://"]) {
[lsMedia startSpeedCalc:self.urlText success:^(NSMutableArray *array) {
NSLog(@"\n success!!! \n");
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"测速结果" message:[NSString stringWithFormat:@"%@",array] delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert showAlertWithCompletionHandler:^(NSInteger i) {}];
});
} fail:^{
NSLog(@"failed");
}];
}else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"推流地址不正确" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert showAlertWithCompletionHandler:^(NSInteger i) {
if (i == 0) {
NSLog(@"推流地址不正确");
}
}];
}
}
- (void)stopSpeed:(id)sender
{
[lsMedia stopSpeedCalc];
}
特殊说明
测速次数不建议超过3次,上传内容不宜过大,否则等待时间太久
摄像头操作
- 闪光灯
- 变焦
- 前后摄像头切换
- 分辨率切换
- 采集方向(帧率、码率)设置
API原型
/**
* flash摄像头
*
* @return 打开或者关闭摄像头flash
*/
@property (nonatomic, assign)BOOL flash;
/**
* 摄像头变焦功能属性:最大拉伸值,系统最大为:videoMaxZoomFactor
* @warning iphone4s以及之前的版本,videoMaxZoomFactor=1;不支持拉伸
*/
@property (nonatomic, assign, readonly) CGFloat maxZoomScale;
/**
* 摄像头变焦功能属性:拉伸值,[1,maxZoomScale]
* @warning iphone4s以及之前的版本,videoMaxZoomFactor=1;不支持拉伸
*/
@property (nonatomic, assign) CGFloat zoomScale;
/**
* 摄像头变焦功能属性:拉伸值变化回调block
*
* 摄像头响应uigesture事件,而改变了拉伸系数反馈
* @warning iphone4s以及之前的版本,videoMaxZoomFactor=1;不支持拉伸
*/
@property (nonatomic,copy) void (^onZoomScaleValueChanged)(CGFloat value);
/**
* 切换前后摄像头
*
* @return 当前摄像头的位置,前或者后
*/
- (LSCameraPosition)switchCamera:(LSSwitchModuleVideoCameraPositionBlock)cameraPostionBlock;
/**
切换分辨率,支持直播过程中切换分辨率,切换分辨率,水印将自动清除,需要外部根据分辨率,再次设置水印大小
@param videoResolution
@param videoResolutionBlock
*/
- (void)switchVideoStreamingQuality:(LSVideoStreamingQuality)videoResolution block:(LSVideoStreamingQualityBlock)videoResolutionBlock;
/**
直播推流之前设置如下参数
@param bitrate 推流码率 default会按照分辨率设置
@param fps 采集帧率 default = 15
@param cameraOrientation 摄像头采集方向(一般不变)
*/
- (void)setBitrate:(int)bitrate
fps:(int)fps
cameraOrientation:(LSCameraOrientation) cameraOrientation;
参数说明
参数 | 类型 | 说明 |
---|---|---|
flash | BOOL | 打开或者关闭摄像头flash |
maxZoomScale | CGFloat | 摄像头变焦功能属性:最大拉伸值,系统最大为:videoMaxZoomFactor |
zoomScale | CGFloat | 摄像头变焦功能属性:拉伸值,[1,maxZoomScale] |
cameraPostionBlock | LSSwitchModuleVideoCameraPositionBlock | 当前摄像头的位置,前或者后 |
videoResolution | LSVideoStreamingQuality | 分辨率 |
videoResolutionBlock | LSVideoStreamingQualityBlock | 切换摄像头回调 |
bitrate | int | 推流码率 |
fps | int | 采集帧率 |
cameraOrientation | LSCameraOrientation | 摄像头采集方向( |
示例
self.trackSliderView = [[NETrackingSliderView alloc] initWithView:paraCtx tag:^(SliderTag tag,CGFloat value) {
if (tag == zoomTag) {
_mediaCapture.zoomScale = value;
}
}];
_isBackCameraPosition = [_mediaCapture switchCamera:^{
NSLog(@"切换摄像头");
}];
[_mediaCapture switchVideoStreamingQuality:quality block:^(LSVideoStreamingQuality quality1) {
[self addWaterMarkLayer:quality1];
[self addDynamicWaterMark:quality1];
}];
特殊说明
无
镜像相关操作
- 切换本地预览镜像
- 切换编码镜像(针对拉流端观众)
API原型
/**
切换本地预览镜像
@return 当前是否镜像
*/
-(BOOL)changeIsFrontPreViewMirrored;
/**
切换编码镜像(针对拉流端观众)
@return 当前是否镜像
*/
-(BOOL)changeIsFrontCodeMirrored;
参数说明
无
示例
-(void)onActionPreviewMirror:(id)sender{
[_mediaCapture changeIsFrontPreViewMirrored];
}
-(void)onActionCodeMirror:(id)sender{
[_mediaCapture changeIsFrontCodeMirrored];
}
特殊说明
无
滤视频截图操作
- 获取视频截图
API原型
/**
* 获取视频截图,
*
* @param LSFrameCaptureCompletionBlock 获取最新一幅视频图像的回调
*
*/
- (void)snapShotWithCompletionBlock:(LSFrameCaptureCompletionBlock)completionBlock;
参数说明
参数 | 类型 | 说明 |
---|---|---|
completionBlock | LSFrameCaptureCompletionBlock | 获取最新一幅视频图像的回调 |
示例
__weak MediaCaptureViewController *weakSelf = self;
[weakSelf.mediaCapture snapShotWithCompletionBlock:^(UIImage *latestFrameImage) {
UIImageWriteToSavedPhotosAlbum(latestFrameImage, weakSelf, nil, nil);
}];
特殊说明
无
滤镜相关操作
- 设置滤镜类型
- 设置磨皮强度
- 设置美白强度
- 调节曝光度
API原型
/**
* 设置滤镜类型
*
* @param filterType 滤镜类型,目前支持4种滤镜,参考 LSGpuImageFilterType 描述
*
*/
- (void)setFilterType:(LSGpuImageFilterType)filterType;
/**
设置磨皮强度【0-1】
@param value 值
*/
- (void)setSmoothFilterIntensity:(float)value;
/**
设置美白强度【0-1】
@param value 值
*/
- (void)setWhiteningFilterIntensity:(float)value;
/**
调节曝光度(-10.0 - 10.0 ,默认为0.0)
@param exposure 曝光度
*/
-(void)adjustExposure:(CGFloat)exposure;
参数说明
参数 | 类型 | 说明 |
---|---|---|
filterType | LSGpuImageFilterType | 滤镜类型 |
value | float | 磨皮强度【0-1】 |
value | float | 美白强度【0-1】 |
exposure | CGFloat | 曝光度(-10.0 - 10.0 ,默认为0.0) |
示例
[_mediaCapture setFilterType:(LSGpuImageFilterType)type];
self.trackSliderView = [[NETrackingSliderView alloc] initWithView:paraCtx tag:^(SliderTag tag,CGFloat value) {
if (tag == zoomTag) {
_mediaCapture.zoomScale = value;
}else if (tag == ContrastTag){
[_mediaCapture setSmoothFilterIntensity:value];
}else if (tag == WhiteTag){
[_mediaCapture setWhiteningFilterIntensity:value];
}else{
[_mediaCapture adjustExposure:value];
}
}];
特殊说明
无
水印相关操作
- 添加涂鸦
- 添加静态视频水印
- 关闭本地预览静态水印
- 添加动态视频水印
- 关闭本地预览动态水印
- 清除水印
API原型
/**
添加涂鸦
@param image 涂鸦静态图像
@param rect 具体位置和大小(x,y根据location位置,计算具体的位置信息)
@param location 位置
*/
- (void)addGraffiti:(UIImage*)image
rect:(CGRect)rect
location:(LSWaterMarkLocation)location;
/**
添加静态视频水印
@param image 静态图像
@param rect 具体位置和大小(x,y根据location位置,计算具体的位置信息)
@param location 位置
*/
- (void) addWaterMark: (UIImage*) image
rect: (CGRect) rect
location: (LSWaterMarkLocation) location;
/**
关闭本地预览静态水印
*/
- (void)closePreviewWaterMark:(BOOL)isClosed;
/**
添加动态视频水印
@param imageArray 动态图像数组
@param count 播放速度的快慢:count代表count帧显示同一张图
@param looped 是否循环,不循环就显示一次
@param rect 具体位置和大小(x,y根据location位置,计算具体的位置信息)
@param location 位置
*/
- (void) addDynamicWaterMarks: (NSArray*) imageArray
fpsCount: (unsigned int)count
loop: (BOOL)looped
rect: (CGRect) rect
location: (LSWaterMarkLocation) location;
/**
关闭本地预览动态水印
*/
- (void)closePreviewDynamicWaterMark:(BOOL)isClosed;
/**
清除水印
*/
- (void)cleanWaterMark;
参数说明
参数 | 类型 | 说明 |
---|---|---|
image | UIImage | 图像 |
rect | CGRect | 具体位置和大小(x,y根据location位置,计算具体的位置信息) |
location | LSWaterMarkLocation | 位置 |
isClosed | BOOL | 关闭水印 |
imageArray | NSArray | 动态图像数组 |
count | unsigned int | 放速度的快慢:count代表count帧显示同一张图 |
looped | BOOL | 是否循环,不循环就显示一次 |
示例
- (void)addWaterMarkLayer:(LSVideoStreamingQuality)quality {
CGRect rect = CGRectZero;
//自行根据产品定水印在不同分辨率下的大小
switch (quality) {
case LS_VIDEO_QUALITY_LOW:
rect = CGRectMake(10, 10, 100*0.7*0.7*0.7, 54*0.7*0.7*0.7);
break;
case LS_VIDEO_QUALITY_MEDIUM:
rect = CGRectMake(10, 10, 100*0.7*0.7, 54*0.7*0.7);
break;
case LS_VIDEO_QUALITY_HIGH:
rect = CGRectMake(10, 10, 100*0.7, 54*0.7);
break;
case LS_VIDEO_QUALITY_SUPER:
rect = CGRectMake(10, 10, 100, 54);
break;
default:
rect = CGRectMake(10, 10, 100, 54);
break;
}
//添加静态水印
UIImage* image = [UIImage imageNamed:[[[NSBundle mainBundle] bundlePath]stringByAppendingPathComponent:@"logo.png"]];
[_mediaCapture addWaterMark:image rect:rect location:LS_WATERMARK_LOCATION_RIGHTUP];
}
- (void)addDynamicWaterMark:(LSVideoStreamingQuality)quality {
CGRect rect = CGRectZero;
//自行根据产品定水印在不同分辨率下的大小
switch (quality) {
case LS_VIDEO_QUALITY_LOW:
rect = CGRectMake(10, 10, 220*0.7*0.7*0.7, 80*0.7*0.7*0.7);
break;
case LS_VIDEO_QUALITY_MEDIUM:
rect = CGRectMake(10, 10, 220*0.7*0.7, 80*0.7*0.7);
break;
case LS_VIDEO_QUALITY_HIGH:
rect = CGRectMake(10, 10, 220*0.7, 80*0.7);
break;
case LS_VIDEO_QUALITY_SUPER:
rect = CGRectMake(10, 10, 220, 80);
break;
default:
rect = CGRectMake(10, 10, 220, 80);
break;
}
//屏蔽动态水印oppo广告
NSMutableArray *array = [NSMutableArray array];
for (NSInteger i = 0; i < 23; i++) {
NSString *str = [NSString stringWithFormat:@"water%@.png",[NSString stringWithFormat:@"%ld",(long)i]];
UIImage* image = [UIImage imageNamed:[[[NSBundle mainBundle] bundlePath]stringByAppendingPathComponent:str]];
[array addObject:image];
}
//图片数量少时,建议2帧一次显示,图片多时,建议1帧一次显示
[_mediaCapture addDynamicWaterMarks:array
fpsCount:2
loop:YES
rect:rect
location:LS_WATERMARK_LOCATION_RIGHTDOWN];
}
switch (item) {
case 0://无水印
paraCtx.isVideoWaterMarkEnabled = NO;
[_mediaCapture cleanWaterMark];
break;
case 1://静态水印
{
paraCtx.isVideoWaterMarkEnabled = YES;
[_mediaCapture cleanWaterMark];
[self addWaterMarkLayer:paraCtx.videoStreamingQuality];
}
break;
case 2:
{
paraCtx.isVideoWaterMarkEnabled = YES;
[_mediaCapture cleanWaterMark];
[self addDynamicWaterMark:paraCtx.videoStreamingQuality];
}
break;
default:
break;
}
特殊说明
无
直播辅助操作
- 直播过程中发生错误的回调函数
- 得到直播过程中的统计信息
- 更新自定义统计数据
- 检查是否正在直播
- 设置日志的level
- 获取当前sdk的版本号
API原型
/**
* 直播过程中发生错误的回调函数
*
* @param error 具体错误信息
*/
@property (nonatomic,copy) void (^onLiveStreamError)(NSError *error);
/**
* 得到直播过程中的统计信息
*
* @param statistics 统计信息结构体
*
*/
@property (nonatomic,copy) void (^onStatisticInfoGot)(LSStatisticsObject* statistics);
/**
更新自定义统计数据
@param customDict 自定义统计数据(key,value)
*/
- (void)updateCutomStatistics:(NSDictionary *)customDict;
/**
检查是否正在直播
@return bool值
*/
- (BOOL)checkIsLiving;
/**
* 设置trace 的level
*
* @param loglevl trace 信息的级别
*/
- (void)setTraceLevel:(LSMediaLog)logLevel;
/**
* 获取当前sdk的版本号
*
*/
+ (NSString*) getSDKVersionID;
参数说明
参数 | 类型 | 说明 |
---|---|---|
customDict | NSDictionary | 自定义统计数据(key,value) |
logLevel | LSMediaLog | 信息的级别 |
示例
_mediaCapture.onLiveStreamError = ^(NSError* error){
if (error != nil) {
[weakSelf LiveStreamErrorInterrup];
}
[weakSelf.selectView.startBtn setBackgroundImage:[UIImage imageNamed:@"restart"] forState:UIControlStateNormal];
};
_mediaCapture.onStatisticInfoGot = ^(LSStatisticsObject* statistics){
if (statistics != nil) {
dispatch_async(dispatch_get_main_queue(),^(void){[weakSelf showStatInfo:statistics];});
}
};
[LSMediaCapture getSDKVersionID];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"1111" forKey:@"uid"];
[dict setObject:@"2222" forKey:@"appKey"];
[_mediaCapture updateCutomStatistics:dict];
特殊说明
无
此文档是否对你有帮助?
有帮助
我要吐槽