diff --git a/APIDiffs/api-diffs-1.1.0.md b/APIDiffs/api-diffs-1.1.0.md new file mode 100644 index 0000000..99d70ce --- /dev/null +++ b/APIDiffs/api-diffs-1.1.0.md @@ -0,0 +1,26 @@ +# PLCameraStreamingKit 1.0.3 to 1.1.0 API Differences + +## General Headers + +```PLStreamingSession.h``` + +- *Added* method `- (void)reloadVideoConfiguration:(PLVideoStreamingConfiguration *)videoConfiguration;` +- *Added* method `- (void)pushVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer completion:(void (^)(void))handler;` +- *Added* method `- (void)pushPixelBuffer:(CVPixelBufferRef)pixelBuffer completion:(void (^)(void))handler;` +- *Added* method `- (void)pushAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer completion:(void (^)(void))handler;` +- *Added* method `- (void)pushAudioBuffer:(AudioBuffer *)audioBuffer completion:(void (^)(void))handler;` +- *removed* method `- (void)beginUpdateConfiguration;` +- *removed* method `- (void)endUpdateConfiguration;` + +```PLVideoStreamingConfiguration.h``` + +- *Modified* property to writable `@property (nonatomic, PL_STRONG) NSString *videoProfileLevel;` +- *Removed* property `@property (nonatomic, assign) PLStreamingDimension dimension;` +- *Removed* property `@property (nonatomic, PL_STRONG) NSString *videoQuality;` +- *Modified* method `+ (instancetype)configurationWithVideoSize:(CGSize)videoSize + videoQuality:(NSString *)quality;` +- *Added* method `- (BOOL)validate;` + +```PLTypeDefines.h``` + +- *Removed* type `PLStreamingDimension` \ No newline at end of file diff --git a/Example/PLStreamingKit/PLViewController.m b/Example/PLStreamingKit/PLViewController.m index 8f0c76c..7779132 100644 --- a/Example/PLStreamingKit/PLViewController.m +++ b/Example/PLStreamingKit/PLViewController.m @@ -59,7 +59,7 @@ @implementation PLViewController - (void)viewDidLoad { [super viewDidLoad]; - PLVideoStreamingConfiguration *videoConfiguration = self.audioOnly ? nil : [PLVideoStreamingConfiguration configurationWithUserDefineDimension:CGSizeMake(320, 576) videoQuality:kPLVideoStreamingQualityLow2]; + PLVideoStreamingConfiguration *videoConfiguration = self.audioOnly ? nil : [PLVideoStreamingConfiguration configurationWithVideoSize:CGSizeMake(320, 576) videoQuality:kPLVideoStreamingQualityLow2]; PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfiguration defaultConfiguration]; #warning 你需要设定 streamJSON 为自己服务端创建的流 @@ -140,6 +140,7 @@ - (IBAction)actionButtonPressed:(id)sender { #pragma mark - - (void)streamingSession:(PLStreamingSession *)session streamStateDidChange:(PLStreamState)state { + // 除 PLStreamStateError 外的所有状态都会回调在这里 NSString *log = [NSString stringWithFormat:@"Stream State: %s", stateNames[state]]; NSLog(@"%@", log); if (PLStreamStateDisconnected == state) { @@ -148,6 +149,7 @@ - (void)streamingSession:(PLStreamingSession *)session streamStateDidChange:(PLS } - (void)streamingSession:(PLStreamingSession *)session didDisconnectWithError:(NSError *)error { + // PLStreamStateError 状态会回调在这里 NSString *log = [NSString stringWithFormat:@"Stream State: Error. %@", error]; NSLog(@"%@", log); [self.actionButton setTitle:@"Start" forState:UIControlStateNormal]; diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 62d3a5b..cf0787f 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,9 +1,9 @@ PODS: - HappyDNS (0.2.3) - - PLStreamingKit (1.0.3): + - PLStreamingKit (1.1.0): - HappyDNS - - PLStreamingKit/precompiled (= 1.0.3) - - PLStreamingKit/precompiled (1.0.3): + - PLStreamingKit/precompiled (= 1.1.0) + - PLStreamingKit/precompiled (1.1.0): - HappyDNS DEPENDENCIES: @@ -15,6 +15,6 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: HappyDNS: 6d85942e64c28b4fa61f8c76580398f52d6d1d11 - PLStreamingKit: f1a50c91774d0ff790e0cfc5c08d5456a562b360 + PLStreamingKit: 3d80f1fac348c8123696234c2762c49b7cdd8769 COCOAPODS: 0.39.0 diff --git a/Example/Pods/Local Podspecs/PLStreamingKit.podspec.json b/Example/Pods/Local Podspecs/PLStreamingKit.podspec.json index d58fa53..c3acc54 100644 --- a/Example/Pods/Local Podspecs/PLStreamingKit.podspec.json +++ b/Example/Pods/Local Podspecs/PLStreamingKit.podspec.json @@ -1,6 +1,6 @@ { "name": "PLStreamingKit", - "version": "1.0.3", + "version": "1.1.0", "summary": "Pili iOS streaming framework via RTMP.", "homepage": "https://github.com/pili-engineering/PLStreamingKit", "license": "Apache License, Version 2.0", @@ -9,7 +9,7 @@ }, "source": { "git": "https://github.com/pili-engineering/PLStreamingKit.git", - "tag": "v1.0.3" + "tag": "v1.1.0" }, "platforms": { "ios": "7.0" diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index 62d3a5b..cf0787f 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -1,9 +1,9 @@ PODS: - HappyDNS (0.2.3) - - PLStreamingKit (1.0.3): + - PLStreamingKit (1.1.0): - HappyDNS - - PLStreamingKit/precompiled (= 1.0.3) - - PLStreamingKit/precompiled (1.0.3): + - PLStreamingKit/precompiled (= 1.1.0) + - PLStreamingKit/precompiled (1.1.0): - HappyDNS DEPENDENCIES: @@ -15,6 +15,6 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: HappyDNS: 6d85942e64c28b4fa61f8c76580398f52d6d1d11 - PLStreamingKit: f1a50c91774d0ff790e0cfc5c08d5456a562b360 + PLStreamingKit: 3d80f1fac348c8123696234c2762c49b7cdd8769 COCOAPODS: 0.39.0 diff --git a/PLStreamingKit.podspec b/PLStreamingKit.podspec index ff607d6..5c4ff69 100644 --- a/PLStreamingKit.podspec +++ b/PLStreamingKit.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = "PLStreamingKit" - s.version = "1.0.3" + s.version = "1.1.0" s.summary = "Pili iOS streaming framework via RTMP." s.homepage = "https://github.com/pili-engineering/PLStreamingKit" s.license = 'Apache License, Version 2.0' diff --git a/Pod/Library/include/PLStreamingKit/PLStreamingSession.h b/Pod/Library/include/PLStreamingKit/PLStreamingSession.h index c8e025b..8d0fb20 100644 --- a/Pod/Library/include/PLStreamingKit/PLStreamingSession.h +++ b/Pod/Library/include/PLStreamingKit/PLStreamingSession.h @@ -119,23 +119,30 @@ */ - (void)stop; -- (void)beginUpdateConfiguration; -- (void)endUpdateConfiguration; +- (void)reloadVideoConfiguration:(PLVideoStreamingConfiguration *)videoConfiguration; // 处理发送数据 /*! * 处理视频数据 */ - (void)pushVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer; +/// 注意: completion 回调不在主线程 +- (void)pushVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer completion:(void (^)(void))handler; - (void)pushPixelBuffer:(CVPixelBufferRef)pixelBuffer; +/// 注意: completion 回调不在主线程 +- (void)pushPixelBuffer:(CVPixelBufferRef)pixelBuffer completion:(void (^)(void))handler; /*! * 处理音频数据 */ - (void)pushAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer; +/// 注意: completion 回调不在主线程 +- (void)pushAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer completion:(void (^)(void))handler; - (void)pushAudioBuffer:(AudioBuffer *)audioBuffer; +/// 注意: completion 回调不在主线程 +- (void)pushAudioBuffer:(AudioBuffer *)audioBuffer completion:(void (^)(void))handler; @end diff --git a/Pod/Library/include/PLStreamingKit/PLTypeDefines.h b/Pod/Library/include/PLStreamingKit/PLTypeDefines.h index 9c2a312..97522e2 100644 --- a/Pod/Library/include/PLStreamingKit/PLTypeDefines.h +++ b/Pod/Library/include/PLStreamingKit/PLTypeDefines.h @@ -57,36 +57,6 @@ typedef NS_ENUM(NSInteger, PLStreamError) { PLStreamErrorDNSResolveFailed = -1300, }; -#pragma mark - Video Dimension - -/// 流编码分辨率 -typedef NS_ENUM(NSUInteger, PLStreamingDimension) { - /// 16 : 9 横纵比,416 x 234 分辨率 - PLStreamingDimension_16_9__416x234, - /// 16 : 9 横纵比,480 x 270 分辨率 - PLStreamingDimension_16_9__480x270, - /// 16 : 9 横纵比,640 x 360 分辨率 - PLStreamingDimension_16_9__640x360, - /// 16 : 9 横纵比,960 x 540 分辨率 - PLStreamingDimension_16_9__960x540, - /// 16 : 9 横纵比,1280 x 720 分辨率 - PLStreamingDimension_16_9__1280x720, - /// 4 : 3 横纵比,400 x 300 分辨率 - PLStreamingDimension_4_3__400x300, - /// 4 : 3 横纵比,480 x 360 分辨率 - PLStreamingDimension_4_3__480x360, - /// 4 : 3 横纵比,640 x 480 分辨率 - PLStreamingDimension_4_3__640x480, - /// 4 : 3 横纵比,960 x 720 分辨率 - PLStreamingDimension_4_3__960x720, - /// 4 : 3 横纵比,1280 x 960 分辨率 - PLStreamingDimension_4_3__1280x960, - /// 自定义分辨率 - PLStreamingDimension_UserDefine, - /// 默认分辨率,默认为 4 : 3 横纵比,640 x 480 分辨率 - PLStreamingDimension_Default = PLStreamingDimension_4_3__640x480, -}; - #pragma mark - Video Streaming Quality /*! diff --git a/Pod/Library/include/PLStreamingKit/PLVideoStreamingConfiguration.h b/Pod/Library/include/PLStreamingKit/PLVideoStreamingConfiguration.h index ff0676c..69de6b8 100644 --- a/Pod/Library/include/PLStreamingKit/PLVideoStreamingConfiguration.h +++ b/Pod/Library/include/PLStreamingKit/PLVideoStreamingConfiguration.h @@ -12,52 +12,56 @@ #import "PLTypeDefines.h" #import "PLMacroDefines.h" +/*! + * PLVideoStreamingConfiguration 是推流前视频编码时的具体参数 + * + * @discussion 当你不明白每个具体参数是什么含义前,你可以使用 defaultConfiguration 或者通过指定分辨率和推流质量生成一个 config. + * 在设定一个参数时,请务必明白其含义,并且知道其可能造成的影响,随意的设定可能引起编码器设定失败。在 configuration 内部检查如果发现了超过 + */ @interface PLVideoStreamingConfiguration : NSObject /// 编码的 profile level -@property (nonatomic, readonly, PL_STRONG) NSString *videoProfileLevel; +@property (nonatomic, PL_STRONG) NSString *videoProfileLevel; -///// 分辨率,如果自定义了 videoSize, 该值为 PLStreamingDimension_UserDefine -@property (nonatomic, assign) PLStreamingDimension dimension; -// -///// 推流质量 -@property (nonatomic, PL_STRONG) NSString *videoQuality; - -/// 视频的分辨率 +/// 视频的分辨率,宽高务必设定为 2 的倍数,否则解码播放时可能出现绿边 @property (nonatomic, assign) CGSize videoSize; /// 视频的帧率,即 fps @property (nonatomic, assign) NSUInteger videoFrameRate; -/// 最大关键帧间隔 +/// 最大关键帧间隔,可设定为 fps 的三倍,影响一个 gop 的大小 @property (nonatomic, assign) NSUInteger videoMaxKeyframeInterval; -/// 视频的码率 +/// 视频的码率,单位是 bps @property (nonatomic, assign) NSUInteger videoBitRate; /*! * 生成一个默认的配置 - * @discussion 该方法每次都会生成一个新的配置,不是单例方法。默认情况下,对应的参数为 PLStreamingDimension_Default, PLStreamingQualityMedium1 + * @discussion 该方法每次都会生成一个新的配置,不是单例方法。默认情况下,对应的参数为分辨率 (320, 480), video quality PLStreamingQualityMedium1 */ + (instancetype)defaultConfiguration; /*! - * 指定可选分辨率和推流质量生成一个配置 + * 指定自定义分辨率和推流质量生成一个配置 */ -+ (instancetype)configurationWithDimension:(PLStreamingDimension)dimension ++ (instancetype)configurationWithVideoSize:(CGSize)videoSize videoQuality:(NSString *)quality; /*! - * 指定自定义分辨率和推流质量生成一个配置 + * 请务必在清楚每个参数的意义及影响后再调用此方法做初始化,该方法内部会调用 validate 接口 + * 如果不能通过 validate 验证,将抛出异常 */ -+ (instancetype)configurationWithUserDefineDimension:(CGSize)videoSize - videoQuality:(NSString *)quality; - -- (instancetype)initWithUserDefineDimension:(CGSize)videoSize - videoFrameRate:(NSUInteger)fps - videoMaxKeyframeInterval:(NSUInteger)videoMaxKeyframeInterval - videoBitrate:(NSUInteger)videoBitRate; +- (instancetype)initWithVideoSize:(CGSize)videoSize + videoFrameRate:(NSUInteger)fps + videoMaxKeyframeInterval:(NSUInteger)videoMaxKeyframeInterval + videoBitrate:(NSUInteger)videoBitRate + videoProfileLevel:(NSString *)videoProfileLevel; +/*! + * 当更改了某些属性时,调用 validate 方法验证参数是否正确,如果有错会抛出异常 + * - (instancetype)initWithVideoSize:videoFrameRate:videoMaxKeyframeInterval:videoBitrate:videoProfileLevel: 方法内部会调用该方法 + */ +- (BOOL)validate; @end diff --git a/Pod/Library/lib/libPLStreamingKit.a b/Pod/Library/lib/libPLStreamingKit.a index 192594b..8d43db1 100644 Binary files a/Pod/Library/lib/libPLStreamingKit.a and b/Pod/Library/lib/libPLStreamingKit.a differ diff --git a/README.md b/README.md index 39fb9a9..4fd2be7 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ pod update // ... // } NSDictionary *streamJSON; -PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration configurationWithUserDefineDimension:CGSizeMake(320, 576) videoQuality:kPLVideoStreamingQualityLow2]; +PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration configurationWithVideoSize:CGSizeMake(320, 576) videoQuality:kPLVideoStreamingQualityLow2]; PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfiguration defaultConfiguration]; PLStream *stream = [PLStream streamWithJSON:streamJSON]; @@ -126,26 +126,6 @@ self.session.delegate = self; ### 视频编码参数 ```Objective-C -// 初始化编码配置类的实例需要的两个参数 - -// 视频横纵比及分辨率 -typedef NS_ENUM(NSUInteger, PLStreamingDimension) { - PLStreamingDimension_16_9__416x234, - PLStreamingDimension_16_9__480x270, - PLStreamingDimension_16_9__640x360, - PLStreamingDimension_16_9__960x540, - PLStreamingDimension_16_9__1280x720, - PLStreamingDimension_16_9__1920x1080, - PLStreamingDimension_4_3__400x300, - PLStreamingDimension_4_3__480x360, - PLStreamingDimension_4_3__640x480, - PLStreamingDimension_4_3__960x720, - PLStreamingDimension_4_3__1280x960, - PLStreamingDimension_4_3__1920x1140, - PLStreamingDimension_UserDefine, - PLStreamingDimension_Default = PLStreamingDimension_4_3__640x480 -}; - // 视频推流质量 /*! * @abstract Video streaming quality low 1 @@ -214,14 +194,14 @@ extern NSString *kPLVideoStreamingQualityHigh3; 需要明确以上两者,便可以直接获取到最佳的视频编码配置。 ```Objective-C -// 默认情况下,PLStreamingKit 会使用 4:3 的 640x480 分辨率,及 kPLVideoStreamingQualityMedium1 作为参数初始化编码配置类的实例. +// 该方法每次都会生成一个新的配置,不是单例方法。默认情况下,对应的参数为分辨率 (320, 480), video quality PLStreamingQualityMedium1 PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration defaultConfiguration]; -// 当然你也可以自己指定,比如你希望输出直播视频是 16:9 的 960x540 的分辨率,并且你已经明确你需要的视频质量为 High1,你可以这样来设置编码配置 -PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration configurationWithDimension:PLStreamingDimension_16_9__960x540 videoQuality:kPLVideoStreamingQualityHigh1]; +// 你也可以指定自己想要的分辨率和已有的 video quality 参数 +PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration configurationWithVideoSize:CGSizeMake(320, 480) videoQuality:kPLVideoStreamingQualityHigh1]; -// 当已有的分辨率无法满足你的需求时,你可以自己定义视频的大小 -PLVideoStreamingConfiguration *videoConfiguration = [PLVideoStreamingConfiguration configurationWithUserDefineDimension:CGSizeMake(width, height) videoQuality:kPLVideoStreamingQualityHigh1]; +// 当已有的分辨率无法满足你的需求时,你可以自己定义所有参数,但请务必确保你清楚参数的含义 +PLVideoStreamingConfiguration *videoConfiguration = [[PLVideoStreamingConfiguration alloc] initWithVideoSize:CGSizeMake(width, height) videoFrameRate:30 videoMaxKeyframeInterval:90 videoBitrate:1200 * 1000 videoProfileLevel:AVVideoProfileLevelH264Main32]]; ``` ### Video Quality 具体参数 @@ -274,7 +254,7 @@ PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfigurati |kPLAudioStreamingQualityHigh1|44|96| |kPLAudioStreamingQualityHigh2|44|128| -在创建好编码配置对象后,就可以用它来初始化 ```PLCameraStreamingSession``` 了。 +在创建好编码配置对象后,就可以用它来初始化 ```PLStreamingSession``` 了。 ## 流状态变更及处理处理 @@ -309,7 +289,6 @@ PLAudioStreamingConfiguration *audioConfiguration = [PLAudioStreamingConfigurati - (void)streamingSessionSendingBufferDidEmpty:(id)session; - (void)streamingSessionSendingBufferDidFull:(id)session; - (void)streamingSession:(id)session sendingBufferDidDropItems:(NSArray *)items; -- (void)streamingSession:(id)session sendingBufferCurrentDurationDidChange:(NSTimeInterval)currentDuration; @end @@ -350,26 +329,21 @@ buffer 的内容高过上阈值时,会回调 `- (void)streamingSessionSendingBufferFillDidHigherThanHighThreshold:(id)session;` -这是可以尝试降低 quality 的时机 +这是可以尝试切换到较低推流质量的 video configuration 内容低于下阈值时,会回调 `- (void)streamingSessionSendingBufferFillDidLowerThanLowThreshold:(id)session;` -这是可以尝试增加 quality 的时机。 - -当了解了可以触发变更 quality 的时机,那么当你需要变更 quality 时,通过下面的方式来做调用 +这是可以尝试切换到较高推流质量的 video configuration ```Objective-C -[self.session beginUpdateConfiguration]; -self.session.videoConfiguration.videoQuality = kPLVideoStreamingQualityMedium2; -self.session.audioConfiguration.audioQuality = kPLAudioStreamingQualityHigh1; -[self.session endUpdateConfiguration]; +[self.session reloadVideoConfiguration:newConfiguraiton]; ``` ### 重要事项 -**在不断流切换 Video Quality 时需要保证 profileLevel 基本不变,即 baseline 只可与 baseline 的 quality 相互切换。以现在的 quality 为例, low 和 medium 的 quality 可以互相切换,但是 high 的 quality 不可以与 low 及 medium 在不断流的情况下无缝切换,否则会导致播放器花屏。** +**在调用 `reloadVideoConfiguration:newConfiguraiton` 时,请务必确保 profileLevel 前后一致,如果该参数有变更,需要先调用 stop, 重新开始推流, 否则可能会因播放器差异而产生花屏等问题。** ## 文档支持 @@ -384,6 +358,10 @@ PLStreamingKit 使用 HeaderDoc 注释来做文档支持。 ## 版本历史 +- 1.1.0 ([Release Notes](https://github.com/pili-engineering/PLStreamingKit/blob/master/ReleaseNotes/release-notes-1.1.0.md) && [API Diffs](https://github.com/pili-engineering/PLStreamingKit/blob/master/APIDiffs/api-diffs-1.1.0.md)) + - 重构 `PLVideoStreamingConfiguration`, 提供给开发者更大的视频编码定制自由度 + - `PLVideoStreamingConfiguration` 提供了 `validate` 方法, 确保 fast fail 减少开发者 app 携带不正确编码参数上线的可能性 + - 优化推送音视频数据, 添加了编码处理完后的回调 - 1.0.3 ([Release Notes](https://github.com/pili-engineering/PLStreamingKit/blob/master/ReleaseNotes/release-notes-1.0.3.md) && [API Diffs](https://github.com/pili-engineering/PLStreamingKit/blob/master/APIDiffs/api-diffs-1.0.3.md)) - 优化 dns 解析部分,补全 happydns 解析失败后的本地解析 - 1.0.2 ([Release Notes](https://github.com/pili-engineering/PLStreamingKit/blob/master/ReleaseNotes/release-notes-1.0.2.md) && [API Diffs](https://github.com/pili-engineering/PLStreamingKit/blob/master/APIDiffs/api-diffs-1.0.2.md)) diff --git a/ReleaseNotes/release-notes-1.1.0.md b/ReleaseNotes/release-notes-1.1.0.md new file mode 100644 index 0000000..3b14527 --- /dev/null +++ b/ReleaseNotes/release-notes-1.1.0.md @@ -0,0 +1,27 @@ +# PLStreamingKit Release Notes for 1.1.0 + +## 内容 + +- [简介](#简介) +- [问题反馈](#问题反馈) +- [记录](#记录) + +## 简介 + +PLStreamingKit 为 iOS 开发者提供直播推流 SDK。 + +## 问题反馈 + +当你遇到任何问题时,可以通过在 GitHub 的 repo 提交 ```issues``` 来反馈问题,请尽可能的描述清楚遇到的问题,如果有错误信息也一同附带,并且在 ```Labels``` 中指明类型为 bug 或者其他。 + +[通过这里查看已有的 issues 和提交 Bug](https://github.com/pili-engineering/PLStreamingKit/issues) + +## 记录 + +PLStreamingKit 第一公开版本发布,提供基础的编码推流功能,音视频采集及其余工作交给开发者自己完成。 + +### 架构 + +- 重构 `PLVideoStreamingConfiguration`, 提供给开发者更大的视频编码定制自由度 +- `PLVideoStreamingConfiguration` 提供了 `validate` 方法, 确保 fast fail 减少开发者 app 携带不正确编码参数上线的可能性 +- 优化推送音视频数据, 添加了编码处理完后的回调 \ No newline at end of file