1.建议使用cocoapods导入sdk使用,可以参考文档:https://github.com/pili-engineering/PLCameraStreamingKit#%E9%85%8D%E7%BD%AE%E5%B7%A5%E7%A8%8B
2.代码梳理
demo:
https://github.com/pili-engineering/PLCameraStreamingKit/tree/master/Example
2.1 在 AppDelegate.m 中初始化sdk,否则会抛出异常
#import <PLStreamingKit/PLStreamingEnv.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[PLStreamingEnv initEnv];
// Override point for customization after application launch.
return YES;
}
2.2 导入头文件,使用代理(不要忘记设置代理和初始化数据)
#import <PLCameraStreamingKit/PLCameraStreamingKit.h>
@interface ViewController ()<PLCameraStreamingSessionDelegate,PLStreamingSendingBufferDelegate>
2.3
- (void)viewDidLoad {
[super viewDidLoad];
//初始化串行队列 DISPATCH_QUEUE_SERIAL
self.sessionQueue = dispatch_queue_create("pili.queue.streaming", DISPATCH_QUEUE_SERIAL);
/*
先判断是否授权,switch 根据不同的授权调用相应的方法
未授权,授权后在执行
授权,配置流的相关信息
*/
//判断相机、麦克风是否授权
switch ([PLCameraStreamingSession cameraAuthorizationStatus]) {
//授权
case PLAuthorizationStatusAuthorized:
permissionBlock();
break;
//未授权
case PLAuthorizationStatusNotDetermined: {
[PLCameraStreamingSession requestCameraAccessWithCompletionHandler:^(BOOL granted) {
granted ? permissionBlock() : noAccessBlock();
}];
}
break;
default:
noAccessBlock();
break;
}
//未授权
void (^noAccessBlock)(void) = ^{
//询问是否授权
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"授权" message:@"是否授权" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *defult = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:cancel];
[alert addAction:defult];
[self presentViewController:alert animated:YES completion:nil];
};
//授权,添加配置信息
void (^permissionBlock)(void) = ^{
//相机采集信息配置
PLVideoCaptureConfiguration *videoCC = [[PLVideoCaptureConfiguration alloc] initWithVideoFrameRate:20 sessionPreset:AVCaptureSessionPresetiFrame1280x720 horizontallyMirrorFrontFacingCamera:YES horizontallyMirrorRearFacingCamera:NO cameraPosition:AVCaptureDevicePositionFront];
//麦克风采集信息配置
PLAudioCaptureConfiguration *audioCC = [PLAudioCaptureConfiguration defaultConfiguration];
//推流设置 视频(即播放的效果)
PLVideoStreamingConfiguration *videoSC = [PLVideoStreamingConfiguration configurationWithVideoSize:CGSizeMake(320, 570) videoQuality:kPLVideoStreamingQualityLow1];
//推流设置 音频
PLAudioStreamingConfiguration *audioSC = [PLAudioStreamingConfiguration configurationWithAudioQuality:kPLAudioStreamingQualityHigh2]
//设置摄像头
AVCaptureVideoOrientation orientation = (AVCaptureVideoOrientation)(([[UIDevice currentDevice] orientation] <= UIDeviceOrientationLandscapeRight && [[UIDevice currentDevice] orientation] != UIDeviceOrientationUnknown) ? [[UIDevice currentDevice] orientation]: UIDeviceOrientationPortrait);
//后端获取流的信息(字典格式)
PLStream *stream = [PLStream streamWithJSON:dict];
//流 初始化
self.streamSession = [[PLCameraStreamingSession alloc]initWithVideoCaptureConfiguration:videoCC audioCaptureConfiguration:audioCC videoStreamingConfiguration:videoSC audioStreamingConfiguration:audioSC stream:stream videoOrientation:orientation];
//代理设置
self.streamSession.delegate = self;
self.streamSession.bufferDelegate = self;
//添加水印
UIImage *image = [UIImage imageNamed:@"test.jpeg"];
PLFilterHandler fitleHandler = [self.streamSession addWaterMark:image origin:CGPointMake(20, 60)];
//在主线程中设置预览界面
dispatch_async(dispatch_get_main_queue(), ^{
UIView *previewView = self.streamSession.previewView;
//根据枚举值调整预览视图的位置
previewView.autoresizingMask = UIViewAutoresizingFlexibleHeight| UIViewAutoresizingFlexibleWidth;
[self.view insertSubview:previewView atIndex:0];
//缩放设置
self.zoomSlider.minimumValue = 1;
self.zoomSlider.maximumValue = MIN(5, self.streamSession.videoActiveFormat.videoMaxZoomFactor);
});
};
}
#pragma mark -销毁
- (void)dealloc {
dispatch_sync(self.sessionQueue, ^{
[self.streamSession destroy];
});
self.streamSession = nil;
self.sessionQueue = nil;
}
//停止推流
- (void)stopSession {
dispatch_async(self.sessionQueue, ^{
self.keyTime = nil;
[self.streamSession stop];
});
}
//开始推流
- (void)startSession {
self.keyTime = nil;
self.actionBtn.enabled = NO;
dispatch_async(self.sessionQueue, ^{
[self.streamSession startWithCompleted:^(BOOL success) {
dispatch_async(dispatch_get_main_queue(), ^{
self.actionBtn.enabled = YES;
});
}];
});
}
//通过按钮控制开始或者停止
- (IBAction)clickAction:(id)sender {
if (PLStreamStateConnected == self.streamSession.streamState) {
[self stopSession];
} else {
[self startSession];
}
}
3.代理和其他的方法可以参考链接:
http://blog.csdn.net/glassy_sky1207/article/details/51852245
4.纯音频推流可以在数据采集和推流是忽略相机参数
5.push URL 原因
1) 请求streamjson用的异步处理,初始化session时数据没有传输过来
2)使用了无鉴权的方式,目前ios推流只支持 static和dynamic 两种鉴权方式
6.出现URL is not authorited ,请工单提供streamjson 的数据
7.首屏秒开的设置的是默认值