Commit 094e9a7c5f46c5a7695448824cfe5805bef991c1

Authored by yinqiaojuan
0 parents

目击者视频播放第一版

Showing 58 changed files with 3732 additions and 0 deletions
.gitignore 0 → 100644
  1 +++ a/.gitignore
  1 +# OS X
  2 +.DS_Store
  3 +
  4 +# Xcode
  5 +build/
  6 +Products/
  7 +*.pbxuser
  8 +!default.pbxuser
  9 +*.mode1v3
  10 +!default.mode1v3
  11 +*.mode2v3
  12 +!default.mode2v3
  13 +*.perspectivev3
  14 +!default.perspectivev3
  15 +xcuserdata/
  16 +*.xccheckout
  17 +profile
  18 +*.moved-aside
  19 +DerivedData
  20 +*.hmap
  21 +*.ipa
  22 +
  23 +# Bundler
  24 +.bundle
  25 +
  26 +# Add this line if you want to avoid checking in source code from Carthage dependencies.
  27 +# Carthage/Checkouts
  28 +
  29 +Carthage/Build
  30 +
  31 +# We recommend against adding the Pods directory to your .gitignore. However
  32 +# you should judge for yourself, the pros and cons are mentioned at:
  33 +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
  34 +#
  35 +# Note: if you ignore the Pods directory, make sure to uncomment
  36 +# `pod install` in .travis.yml
  37 +#
  38 +# Pods/
... ...
.travis.yml 0 → 100644
  1 +++ a/.travis.yml
  1 +# references:
  2 +# * https://www.objc.io/issues/6-build-tools/travis-ci/
  3 +# * https://github.com/supermarin/xcpretty#usage
  4 +
  5 +osx_image: xcode7.3
  6 +language: objective-c
  7 +# cache: cocoapods
  8 +# podfile: Example/Podfile
  9 +# before_install:
  10 +# - gem install cocoapods # Since Travis is not always on latest version
  11 +# - pod install --project-directory=Example
  12 +script:
  13 +- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/CNLiveWitnessVideoModule.xcworkspace -scheme CNLiveWitnessVideoModule-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
  14 +- pod lib lint
... ...
CNLiveWitnessVideoModule.podspec 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule.podspec
  1 +#
  2 +# Be sure to run `pod lib lint CNLiveWitnessVideoModule.podspec' to ensure this is a
  3 +# valid spec before submitting.
  4 +#
  5 +# Any lines starting with a # are optional, but their use is encouraged
  6 +# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
  7 +#
  8 +
  9 +Pod::Spec.new do |s|
  10 + s.name = 'CNLiveWitnessVideoModule'
  11 + s.version = '0.0.1'
  12 + s.summary = '目击者视频播放功能'
  13 +
  14 +# This description is used to generate tags and improve search results.
  15 +# * Think: What does it do? Why did you write it? What is the focus?
  16 +# * Try to keep it short, snappy and to the point.
  17 +# * Write the description between the DESC delimiters below.
  18 +# * Finally, don't worry about the indent, CocoaPods strips it!
  19 +
  20 + s.description = <<-DESC
  21 +TODO: Add long description of the pod here.
  22 + DESC
  23 +
  24 + s.homepage = 'http://bj.gitlab.cnlive.com/ios-team/CNLiveWitnessVideoModule'
  25 + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  26 + s.license = { :type => 'MIT', :file => 'LICENSE' }
  27 + s.author = { 'dawanzi' => '1427945373@qq.com' }
  28 + s.source = { :git => 'http://bj.gitlab.cnlive.com/ios-team/CNLiveWitnessVideoModule.git', :tag => s.version.to_s }
  29 +
  30 + s.ios.deployment_target = '9.0'
  31 +
  32 + s.subspec 'Model' do |model|
  33 + model.source_files = 'CNLiveWitnessVideoModule/Classes/Model/*.{h,m}'
  34 + end
  35 + s.subspec 'ViewModel' do |viewModel|
  36 + viewModel.source_files = 'CNLiveWitnessVideoModule/Classes/ViewModel/*.{h,m}'
  37 + viewModel.dependency 'CNLiveWitnessVideoModule/Model'
  38 + end
  39 + s.subspec 'View' do |view|
  40 + view.source_files = 'CNLiveWitnessVideoModule/Classes/View/*.{h,m}'
  41 + view.dependency 'CNLiveWitnessVideoModule/ViewModel'
  42 + end
  43 + s.subspec 'Controller' do |controller|
  44 + controller.source_files = 'CNLiveWitnessVideoModule/Classes/Controller/*.{h,m}'
  45 + controller.dependency 'CNLiveWitnessVideoModule/View'
  46 + end
  47 + s.subspec 'Services' do |service|
  48 + service.source_files = 'CNLiveWitnessVideoModule/Classes/Services/*.{h,m}'
  49 + service.dependency 'CNLiveWitnessVideoModule/Controller'
  50 + end
  51 + s.dependency 'CNLiveTripartiteManagement/MJExtension'
  52 + s.dependency 'CNLiveTripartiteManagement/YYKit'
  53 + s.dependency 'CNLiveTripartiteManagement/AFNetworking'
  54 + s.dependency 'CNLiveTripartiteManagement/Masonry'
  55 + s.dependency 'CNLiveTripartiteManagement/QMUIKit'
  56 + s.dependency 'CNLiveTripartiteManagement/SDWebImage'
  57 + #基础业务库
  58 + s.dependency 'CNLiveBusinessTools'
  59 + #基础库
  60 + s.dependency 'CNLiveBaseKit'
  61 + #环境库
  62 + s.dependency 'CNLiveEnvironment'
  63 + #基础类目库
  64 + s.dependency 'CNLiveCommonCategory'
  65 + #网络请求
  66 + s.dependency 'CNLiveRequestBastKit'
  67 + #基础UI
  68 + s.dependency 'CNLiveCustomUI'
  69 + s.dependency 'CNLiveBeeHive'
  70 + s.dependency 'CNLiveBServices'
  71 + s.resource_bundles = {
  72 + 'CNLiveWitnessVideoModule' => ['CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle']
  73 + }
  74 +
  75 + # s.public_header_files = 'Pod/Classes/**/*.h'
  76 + s.frameworks = 'UIKit', 'Foundation'
  77 + # s.dependency 'AFNetworking', '~> 2.3'
  78 +end
... ...
CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/background@2x.png 0 → 100644

719 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/background@3x.png 0 → 100644

948 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/bofang-fail@2x.png 0 → 100644

6.37 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/bofang-fail@3x.png 0 → 100644

20.4 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/dd_wlcw@2x.png 0 → 100644

54.8 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/dd_wlcw@3x.png 0 → 100644

123 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/new_detail_head_play@2x.png 0 → 100644

10.4 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/new_detail_head_play@3x.png 0 → 100644

21.7 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/whiteShutdown@2x.png 0 → 100644

706 Bytes

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/whiteShutdown@3x.png 0 → 100644

1.68 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/wufalianjie@2x.png 0 → 100644

51.4 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/wufalianjie@3x.png 0 → 100644

116 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/zhuangtai_kong@2x.png 0 → 100644

20.7 KB

CNLiveWitnessVideoModule/Assets/CNLiveWitnessVideoModule.bundle/zhuangtai_kong@3x.png 0 → 100644

41.3 KB

CNLiveWitnessVideoModule/Classes/Controller/CNBWitnessListController.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Controller/CNBWitnessListController.h
  1 +//
  2 +// CNBWitnessListController.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNBWitnessListController : UIViewController
  13 +
  14 +/// 跳转到视频播放页
  15 +/// @param data 后台返回数据
  16 +/// @param currentIndex 点击当前在第几个
  17 +/// @param type 0 是作品跳进来 1是收藏跳进来
  18 +- (instancetype)initControllerWithData:(NSDictionary *)data currentIndex:(NSInteger)currentIndex pageNum:(NSInteger)pageNum type:(NSString *)type;
  19 +@end
  20 +
  21 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/Controller/CNBWitnessListController.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Controller/CNBWitnessListController.m
  1 +//
  2 +// CNBWitnessListController.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessListController.h"
  9 +#import "CNBWitnessPlayerManager.h"
  10 +#import "CNBWitnessListModel.h"
  11 +#import "MJExtension.h"
  12 +#import "MJRefresh.h"
  13 +#import "CNLiveRefreshHeader.h"
  14 +#import "CNLiveBaseKit.h"
  15 +#import <QMUIKit/QMUIKit.h>
  16 +#import "CNBWitnessListViewModel.h"
  17 +#import "CNEmptyView.h"
  18 +#import "CNBWitnessListCell.h"
  19 +#import "CNBWitnessGetImage.h"
  20 +#import "UIColor+CNLiveExtension.h"
  21 +#import "CNLiveNetworking.h"
  22 +#define CNBWitnessAppKeyWindow ([UIApplication sharedApplication].delegate).window
  23 +typedef NS_ENUM(NSUInteger,CNBWitnessVideoErrorType) {
  24 + CNBWitnessVideoErrorTypeNoNet, //没网
  25 + CNBWitnessVideoErrorTypeFail, //请求失败
  26 + CNBWitnessVideoErrorTypeNoData //没数据
  27 +};
  28 +NSString * const kIdentifier = @"CNBWitnessListCell";
  29 +@interface CNBWitnessListController ()<UITableViewDelegate,UITableViewDataSource,UIScrollViewDelegate>{
  30 + BOOL _isLightContentStatusBar;
  31 +}
  32 +@property (nonatomic, strong) UITableView *tableView;
  33 +@property (nonatomic, assign) NSInteger currentPlayIndex;
  34 +@property (nonatomic, strong) NSMutableArray *dataSource;
  35 +@property (nonatomic, assign) NSInteger pageIndex;
  36 +@property (nonatomic, assign) NSInteger pageSize;
  37 +@property (nonatomic, copy) NSString *toSid ;//看的那个人sid
  38 +@property (nonatomic, copy) NSString *collectionToSid; //收藏id
  39 +@property (nonatomic, strong) CNBWitnessPlayerManager *videoPlayerManager; //播放视频的管理类
  40 +@property (nonatomic, copy) NSString *isHaveNext; //是否有下一页
  41 +@property (nonatomic, assign) BOOL isRefreshMore; //是否正在请求
  42 +@property (nonatomic, assign) BOOL isRefreshHeader; //是否刷新和重试(这时要调用播放方法)
  43 +@property (nonatomic, copy) NSString *type; //0 是作品 1是收藏
  44 +@property (nonatomic, strong) CNEmptyView *emptyView;
  45 +@end
  46 +
  47 +@implementation CNBWitnessListController
  48 +- (instancetype)initControllerWithData:(NSDictionary *)data currentIndex:(NSInteger)currentIndex pageNum:(NSInteger)pageNum type:(NSString *)type {
  49 + if (self = [super init]) {
  50 + _dataSource = [NSMutableArray array];
  51 + _currentPlayIndex = currentIndex;
  52 + _type = type;
  53 + _isHaveNext = @"1";
  54 + _pageIndex = pageNum + 1;
  55 + NSArray *list = data[@"witnessBeans"];
  56 + if ([type isEqualToString:@"0"]) {
  57 + _pageSize = 10;
  58 + for (NSDictionary *dic in list) {
  59 + CNBWitnessListModel *witnessModel = [CNBWitnessListModel mj_objectWithKeyValues:dic];
  60 + [_dataSource addObject:witnessModel];
  61 + }
  62 + }else {
  63 + NSDictionary *dic = list[currentIndex];
  64 + CNBWitnessListModel *witnessModel = [CNBWitnessListModel mj_objectWithKeyValues:dic];
  65 + [_dataSource addObject:witnessModel];
  66 + }
  67 +
  68 + }
  69 + return self;
  70 +}
  71 +- (void)viewWillAppear:(BOOL)animated {
  72 + [super viewWillAppear:animated];
  73 + self.navigationController.navigationBarHidden = YES;
  74 +}
  75 +- (void)viewDidDisappear:(BOOL)animated {
  76 + [super viewDidDisappear:animated];
  77 + self.navigationController.navigationBarHidden = NO;
  78 +}
  79 +- (void)viewDidLoad {
  80 + [super viewDidLoad];
  81 + if (self.dataSource.count > 0) {
  82 + if ([self.type isEqualToString:@"0"]) {
  83 + self.toSid = ((CNBWitnessListModel *)[self.dataSource objectAtIndex:self.currentPlayIndex]).icon.sid;
  84 + }else {
  85 + self.toSid = ((CNBWitnessListModel *)[self.dataSource objectAtIndex:self.currentPlayIndex]).contentSid;
  86 + }
  87 +
  88 + }
  89 + [self setLeftButton];
  90 + [self setBackgroundImage];
  91 + [self.view addSubview:self.tableView];
  92 + _isLightContentStatusBar = YES;
  93 + if (self.dataSource.count> 0) {
  94 + [_tableView reloadData];
  95 + [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentPlayIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
  96 + [self playIndex:self.currentPlayIndex isAutoPlay:YES];
  97 + }
  98 + if ([self.type isEqualToString:@"0"]) {
  99 + self.tableView.mj_header = [CNLiveRefreshHeader headerWithRefreshingTarget:self refreshingAction:@selector(refreshVideoList)];
  100 + self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(getMoreVideoList)];
  101 + }
  102 +
  103 +}
  104 +#pragma mark -添加关闭按钮
  105 +- (void)setLeftButton {
  106 + UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
  107 + leftButton.frame = CGRectMake(15.0f, StatusBarHeight + 11, 20.0f, 20.0f);
  108 +// leftButton.touchAreaInsets = UIEdgeInsetsMake(5, 5, 15, 15);
  109 + [leftButton setBackgroundImage:[CNBWitnessGetImage cnBWitness_getImageName:@"whiteShutdown" bundle:@"CNLiveWitnessVideoModule.bundle/CNLiveWitnessVideoModule" targetClass:[self class]] forState:UIControlStateNormal];
  110 + [leftButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside];
  111 + [self.view addSubview:leftButton];
  112 + __weak typeof(self) weakSelf = self;
  113 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  114 + [weakSelf.view bringSubviewToFront:leftButton];
  115 + });
  116 +}
  117 +- (void)setBackgroundImage {
  118 + UIImageView *background = [[UIImageView alloc] initWithFrame:self.view.bounds];
  119 + background.clipsToBounds = YES;
  120 + background.contentMode = UIViewContentModeScaleAspectFill;
  121 + background.image = [CNBWitnessGetImage cnBWitness_getImageName:@"background" bundle:@"CNLiveWitnessVideoModule.bundle/CNLiveWitnessVideoModule" targetClass:[self class]];
  122 + [self.view addSubview:background];
  123 +}
  124 +#pragma mark - 关闭按钮点击事件
  125 +-(void) dismiss {
  126 + if(self.navigationController.viewControllers.count > 0){
  127 + [self.navigationController popViewControllerAnimated:YES];
  128 + }else {
  129 + [self dismissViewControllerAnimated:YES completion:nil];
  130 + }
  131 + [self.videoPlayerManager resetPlayer];
  132 +}
  133 +#pragma mark - 上面状态栏显示
  134 +-(UIStatusBarStyle)preferredStatusBarStyle {
  135 + if (_isLightContentStatusBar) {
  136 + return UIStatusBarStyleLightContent;
  137 + } else {
  138 + return UIStatusBarStyleDefault;
  139 + }
  140 +}
  141 +- (void)loadWitnessData:(NSInteger)pageIndex{
  142 + __weak typeof(self) weakSelf = self;
  143 + [CNBWitnessListViewModel getWitnessListDataTosid:self.toSid page:self.pageIndex pageSize:self.pageSize successBlock:^(NSMutableArray * _Nonnull dataArray, NSString * _Nonnull isHaveNext) {
  144 + __strong typeof(weakSelf) strongSelf = weakSelf;
  145 + if (!strongSelf) {
  146 + return ;
  147 + }
  148 + [strongSelf.tableView.mj_footer isRefreshing];
  149 + [strongSelf.tableView.mj_header isRefreshing];
  150 + strongSelf.isHaveNext = isHaveNext;
  151 + if ([isHaveNext isEqualToString:@"1"]) {
  152 + strongSelf.pageIndex ++;
  153 + }else {
  154 + [strongSelf.tableView.mj_footer endRefreshingWithNoMoreData];
  155 + }
  156 + strongSelf.isRefreshMore = NO;
  157 + [strongSelf.dataSource arrayByAddingObject:dataArray];
  158 + strongSelf.tableView.mj_footer.hidden = strongSelf.dataSource.count == 0;
  159 + if (strongSelf.currentPlayIndex > strongSelf.dataSource.count) {
  160 + strongSelf.currentPlayIndex = strongSelf.dataSource.count;
  161 + }
  162 + if (strongSelf.dataSource.count > 0) {
  163 + [strongSelf.tableView reloadData];
  164 + strongSelf.tableView.tableFooterView = [UIView new];
  165 + [strongSelf.emptyView removeFromSuperview];
  166 + if (strongSelf.isRefreshHeader) {
  167 + strongSelf.isRefreshHeader = NO;
  168 + [strongSelf.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:strongSelf.currentPlayIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
  169 + [strongSelf playIndex:strongSelf.currentPlayIndex isAutoPlay:YES];
  170 + }
  171 + }else {
  172 + [self showEmptyView:CNBWitnessVideoErrorTypeNoData];
  173 + }
  174 +
  175 + } failureBlock:^(NSError * _Nonnull error) {
  176 + [weakSelf.tableView.mj_footer endRefreshing];
  177 + [weakSelf.tableView.mj_header endRefreshing];
  178 + weakSelf.tableView.mj_footer.hidden = YES;
  179 + [weakSelf.videoPlayerManager resetPlayer];
  180 + weakSelf.isRefreshMore = NO;
  181 + if (weakSelf.dataSource.count == 0) {
  182 + if (error.code == -1009 || error.code == - 1001) {
  183 + [weakSelf showEmptyView:CNBWitnessVideoErrorTypeNoNet];
  184 + }else {
  185 + [weakSelf showEmptyView:CNBWitnessVideoErrorTypeFail];
  186 + }
  187 + }else {
  188 + [weakSelf.emptyView removeFromSuperview];
  189 + [QMUITips showWithText:error.localizedDescription inView:CNBWitnessAppKeyWindow hideAfterDelay:1.5f];
  190 + }
  191 + }];
  192 +}
  193 +#pragma mark - 添加空白页
  194 +- (void)showEmptyView:(CNBWitnessVideoErrorType)errorType {
  195 + NSString *titleName = @"";
  196 + NSString *imageName = @"";
  197 + NSString *retryName = @"";
  198 + if (errorType == CNBWitnessVideoErrorTypeNoNet) {
  199 + imageName = @"dd_wlcw";
  200 + titleName = @"网络开小差了,刷新试试";
  201 + retryName = @"刷新";
  202 + }else if (errorType == CNBWitnessVideoErrorTypeFail) {
  203 + imageName = @"wufalianjie";
  204 + titleName = @"接口开小差了,试试重新请求";
  205 + retryName = @"重试";
  206 + }else if (errorType == CNBWitnessVideoErrorTypeNoData){
  207 + imageName = @"zhuangtai_kong";
  208 + titleName = @"您现在没有相关内容哦";
  209 + retryName = @"";
  210 + }
  211 + BOOL isHidden = errorType == CNBWitnessVideoErrorTypeNoData;
  212 + [self.emptyView showImage:[CNBWitnessGetImage cnBWitness_getImageName:imageName bundle:@"CNLiveWitnessVideoModule.bundle/CNLiveWitnessVideoModule" targetClass:[self class]] title:titleName detailTitle:@"" retryBtnTitle:retryName];
  213 + self.emptyView.retryBtn.hidden = isHidden;
  214 + self.emptyView.retryBtn.backgroundColor = kWhiteColor;
  215 + self.emptyView.retryBtn.layer.masksToBounds = YES;
  216 + self.emptyView.retryBtn.layer.cornerRadius = 14;
  217 + self.emptyView.retryBtn.layer.borderWidth = 1;
  218 + self.emptyView.retryBtn.layer.borderColor = CNLiveColorWithHexString(@"48A7F9").CGColor;
  219 + [self.emptyView.retryBtn setTitleColor:CNLiveColorWithHexString(@"48A7F9") forState:UIControlStateNormal];
  220 + [self.emptyView.retryBtn setTitleColor:CNLiveColorWithHexString(@"48A7F9") forState:UIControlStateHighlighted];
  221 + errorType == CNBWitnessVideoErrorTypeNoData ?self.tableView.tableFooterView = self.emptyView :[self.view addSubview:self.emptyView];
  222 + [self.emptyView.retryBtn addTarget:self action:@selector(retryloadData) forControlEvents:UIControlEventTouchUpInside];
  223 +}
  224 +#pragma mark - 播放视频
  225 +- (void)playIndex:(NSInteger)currentIndex isAutoPlay:(BOOL)isAutoPlay{
  226 + CNBWitnessListCell *cuurrentCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:currentIndex inSection:0]];
  227 + NSURL *videoURL = nil;
  228 + NSURL *originVideoURL = nil;
  229 + CNBWitnessListModel *model = self.dataSource[currentIndex];
  230 + videoURL = [NSURL URLWithString:CNLiveStringIsEmpty(model.videoUrl)?@"":model.videoUrl];
  231 + originVideoURL = [NSURL URLWithString:CNLiveStringIsEmpty(model.videoUrl)?@"":model.videoUrl];
  232 +
  233 + AVLayerVideoGravity videoGravity = AVLayerVideoGravityResizeAspect;
  234 + if (model.isHorizontalScreen == 0) {
  235 + videoGravity = AVLayerVideoGravityResizeAspectFill;
  236 + }else {
  237 + videoGravity = AVLayerVideoGravityResizeAspect;
  238 + }
  239 + self.videoPlayerManager.playerModel.videoGravity = videoGravity;
  240 + self.videoPlayerManager.playerModel.fatherView = cuurrentCell.playerFaterView;
  241 + self.videoPlayerManager.playerModel.videoURL = videoURL;
  242 + self.videoPlayerManager.originVideoURL = originVideoURL;
  243 + self.videoPlayerManager.playerModel.pid = model.pid;
  244 + if (isAutoPlay) {
  245 + self.videoPlayerManager.playerModel.isAutoPlay = YES;
  246 + }else {
  247 + self.videoPlayerManager.playerModel.isAutoPlay = NO;
  248 + }
  249 + [self.videoPlayerManager resetToPlayNewVideo];
  250 +
  251 +}
  252 +#pragma mark - 重试
  253 +- (void)retryloadData {
  254 + self.isRefreshHeader = YES;
  255 + [self.videoPlayerManager resetPlayer];
  256 + self.pageIndex = 1;
  257 + self.currentPlayIndex = 0;
  258 + if (self.dataSource.count > 0) {
  259 + [self.dataSource removeAllObjects];
  260 + }
  261 + [self loadWitnessData:self.pageIndex];
  262 +}
  263 +#pragma mark - 上拉加载更多
  264 +- (void)getMoreVideoList {
  265 + if (self.dataSource.count <= self.pageSize && !self.isRefreshMore) { ////这是数量少,还没有走在提前加载
  266 + self.isRefreshMore = YES;
  267 + [self loadWitnessData:self.pageIndex];
  268 + }else {
  269 + if ((self.currentPlayIndex > (self.dataSource.count - 2)) && !self.isRefreshMore) {
  270 + self.isRefreshMore = YES;
  271 + [self loadWitnessData:self.pageIndex];
  272 + }
  273 + }
  274 +}
  275 +#pragma mark -下拉刷新
  276 +- (void)refreshVideoList{
  277 + if (self.isRefreshMore) {
  278 + return;
  279 + }
  280 + self.isRefreshMore = YES;
  281 + self.isRefreshHeader = YES;
  282 + [self.videoPlayerManager resetPlayer];
  283 + self.pageIndex = 1;
  284 + self.currentPlayIndex = 0;
  285 + if (self.dataSource.count > 0) {
  286 + [self.dataSource removeAllObjects];
  287 + }
  288 + [self loadWitnessData:self.pageIndex];
  289 +}
  290 +#pragma mark - 预加载视频列表
  291 +- (void)preloadWitnessData {
  292 + self.isRefreshMore = YES;
  293 + [self loadWitnessData:self.pageIndex];
  294 +}
  295 +#pragma mark - UITableViewDataSource & UITableViewDelegate
  296 +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  297 + return 1;
  298 +}
  299 +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  300 + return self.dataSource.count;
  301 +}
  302 +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  303 + CNBWitnessListCell *cell = [tableView dequeueReusableCellWithIdentifier:kIdentifier];
  304 + if (cell == nil) {
  305 + cell = [[CNBWitnessListCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kIdentifier];
  306 + }
  307 + cell.type = self.type;
  308 + cell.witnessModel = self.dataSource[indexPath.row];
  309 +// cell.delegate = self;
  310 + return cell;
  311 +}
  312 +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  313 + return self.view.frame.size.height;
  314 +}
  315 +#pragma mark - scrollViewDelegate
  316 +- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  317 + NSInteger currentIndex = round(scrollView.contentOffset.y / KScreenHeight);
  318 + if (currentIndex != self.currentPlayIndex && !self.isRefreshMore) {
  319 + [self.videoPlayerManager resetPlayer];
  320 + self.currentPlayIndex = currentIndex;
  321 + if (!self.isRefreshMore && [self.isHaveNext isEqualToString:@"1"]) {
  322 + if (self.currentPlayIndex == self.dataSource.count - 2) {
  323 + [self preloadWitnessData];
  324 + }
  325 + }
  326 + }
  327 +}
  328 +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  329 + NSLog(@"播放下一个");
  330 + if (self.currentPlayIndex >= 0 && self.dataSource.count > self.currentPlayIndex) {
  331 + if ([CNLiveNetworking isNetworking]) {
  332 + if ([CNLiveNetworking isWiFiNetwork]) {
  333 + [self playIndex:self.currentPlayIndex isAutoPlay:YES];
  334 + }else if ([CNLiveNetworking isWWANNetwork]) {
  335 + BOOL isAgress4G = [[NSUserDefaults standardUserDefaults] objectForKey:@"isAgress4G"];
  336 + if (isAgress4G) {
  337 + [self playIndex:self.currentPlayIndex isAutoPlay:YES];
  338 + }else {
  339 + [self playIndex:self.currentPlayIndex isAutoPlay:NO];
  340 + }
  341 + }else {
  342 + [self playIndex:self.currentPlayIndex isAutoPlay:NO];
  343 + }
  344 + }
  345 + }
  346 +}
  347 +- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
  348 + CGFloat currentIndex = scrollView.contentOffset.y / KScreenHeight;
  349 + if(fabs(currentIndex - self.currentPlayIndex)>1) {
  350 + [self.videoPlayerManager resetPlayer];
  351 + }
  352 +}
  353 +#pragma mark -lazy
  354 +- (UITableView *)tableView {
  355 + if (_tableView == nil) {
  356 + _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
  357 + _tableView.pagingEnabled = YES;
  358 + _tableView.backgroundColor = [UIColor blackColor];
  359 + if (@available(iOS 11.0, *)) {
  360 + self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;//UIScrollView也适用
  361 + } else {
  362 + self.automaticallyAdjustsScrollViewInsets = NO;
  363 + }
  364 + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  365 + _tableView.scrollsToTop = NO;
  366 + _tableView.estimatedRowHeight = 0;
  367 + _tableView.estimatedSectionHeaderHeight = 0;
  368 + _tableView.estimatedSectionFooterHeight = 0;
  369 + _tableView.dataSource = self;
  370 + _tableView.delegate = self;
  371 + _tableView.rowHeight = KScreenHeight;
  372 + _tableView.showsVerticalScrollIndicator = NO;
  373 +
  374 + }
  375 + return _tableView;
  376 +}
  377 +#pragma mark - 播放视频的manager
  378 +- (CNBWitnessPlayerManager *)videoPlayerManager {
  379 + if (!_videoPlayerManager) {
  380 + _videoPlayerManager = [[CNBWitnessPlayerManager alloc]init];
  381 + }
  382 + return _videoPlayerManager;
  383 +}
  384 +- (CNEmptyView *)emptyView {
  385 + if (!_emptyView) {
  386 + _emptyView = [[CNEmptyView alloc]initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight) type:1];
  387 + }
  388 + return _emptyView;
  389 +}
  390 +
  391 +@end
... ...
CNLiveWitnessVideoModule/Classes/Model/CNBWitnessListModel.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Model/CNBWitnessListModel.h
  1 +//
  2 +// CNBWitnessListModel.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +#import <Foundation/Foundation.h>
  8 +@class CNWitnessUserMsg;
  9 +@class CNTool;
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +@interface CNBWitnessListModel: NSObject
  12 +@property (nonatomic, copy) NSString *activityEndTime;
  13 +@property (nonatomic, copy) NSString *colours;
  14 +@property (nonatomic, copy) NSString *tagName;
  15 +@property (nonatomic, strong) CNWitnessUserMsg *icon;
  16 +@property (nonatomic, copy) NSString *poster;
  17 +@property (nonatomic, copy) NSString *pid;
  18 +@property (nonatomic, copy) NSString *subTitle;
  19 +@property (nonatomic, copy) NSString *address;
  20 +@property (nonatomic, strong) CNTool *tool;
  21 +@property (nonatomic, copy) NSString *number;
  22 +@property (nonatomic, copy) NSString *videoId;
  23 +@property (nonatomic, copy) NSString *witnessId;//不为空
  24 +@property (nonatomic, copy) NSString *model;//3_witness 视频带播放按钮的样式 不满足 显示图文样式
  25 +@property (nonatomic, copy) NSString *h5Url;
  26 +@property (nonatomic, copy) NSString *thirdUrl;
  27 +@property (nonatomic, copy) NSString *shareUrl;
  28 +@property (nonatomic, copy) NSString *contentId;
  29 +@property (nonatomic, copy) NSString *videoUrl;
  30 +@property (nonatomic, copy) NSString *duration;
  31 +@property (nonatomic, assign) NSInteger time;
  32 +@property (nonatomic, copy) NSString * timeStr;
  33 +@property (nonatomic, copy) NSString * tttttttttt;
  34 +@property (nonatomic, copy) NSString * title;
  35 +@property (nonatomic, copy) NSString *tagId;
  36 +@property (nonatomic, assign) NSInteger isHorizontalScreen;
  37 +@property (nonatomic, copy) NSString *contentSid;
  38 +@property (nonatomic, assign) NSInteger height;
  39 +@property (nonatomic, assign) NSInteger width;
  40 +
  41 +@property (nonatomic, strong) UIImage *draftImage;
  42 +@property (nonatomic, assign) NSInteger showType;
  43 +@property (nonatomic, copy) id responseObjc;
  44 +@property (nonatomic, assign) NSInteger pageNo;
  45 +
  46 +@property (nonatomic, copy) NSString *spId;
  47 +@property (nonatomic, copy) NSString *classId;
  48 +@property (nonatomic, copy) NSString * siteId;
  49 +@property (nonatomic, copy) NSString * type;
  50 +
  51 +@property (nonatomic, copy) NSString *img; //相关推荐需要
  52 +@property (nonatomic, copy) NSString *spName; //相关推荐里的spName
  53 +@property (nonatomic, copy) NSString *spIcon; ////相关推荐里头像
  54 +@property (nonatomic, copy) NSString *isFirst;
  55 +@property (nonatomic, copy) NSString *source; //来源,根据这个判断显示什么视频
  56 +@property (nonatomic, copy) NSString *coordinate; //位置
  57 +@end
  58 +
  59 +@interface CNWitnessUserMsg: NSObject
  60 +@property (nonatomic, copy) NSString *name;
  61 +@property (nonatomic, assign) BOOL focused;
  62 +@property (nonatomic, copy) NSString *sid;
  63 +@property (nonatomic, copy) NSString *face;
  64 +@property (nonatomic, copy) NSString *type;
  65 +
  66 +@end
  67 +
  68 +@interface CNTool : NSObject
  69 +@property (nonatomic, assign) BOOL liked;
  70 +@property (nonatomic, assign) NSInteger playNum;
  71 +@property (nonatomic, assign) NSInteger likesNum;
  72 +@property (nonatomic, assign) BOOL collectioned;
  73 +@property (nonatomic, assign) NSInteger commentsNum;
  74 +@end
  75 +
  76 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/Model/CNBWitnessListModel.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Model/CNBWitnessListModel.m
  1 +//
  2 +// CNBWitnessListModel.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessListModel.h"
  9 +#import "MJExtension.h"
  10 +@implementation CNBWitnessListModel
  11 +MJCodingImplementation
  12 ++ (NSDictionary *)mj_replacedKeyFromPropertyName
  13 +{
  14 + return @{
  15 + @"desc":@"description"
  16 + };
  17 +}
  18 +- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property
  19 +{
  20 + if ([property.name isEqualToString:@"time"]) {
  21 +
  22 + self.tttttttttt = [self time_timestampToString:[oldValue integerValue]/1000];
  23 + self.timeStr = [self time_timestampToString:[oldValue integerValue]/1000];
  24 + }
  25 + return oldValue;
  26 +
  27 +}
  28 +- (NSString *)time_timestampToString:(NSInteger)timestamp{
  29 +
  30 + NSDate *confromTimesp = [NSDate dateWithTimeIntervalSince1970:timestamp];
  31 + NSDateFormatter *dateFormat=[[NSDateFormatter alloc]init];
  32 + [dateFormat setDateFormat:@"MM-dd HH:mm"];
  33 + NSString* string=[dateFormat stringFromDate:confromTimesp];
  34 + return string;
  35 +}
  36 +@end
  37 +
  38 +@implementation CNWitnessUserMsg
  39 +
  40 +MJCodingImplementation
  41 +
  42 ++ (NSDictionary *)mj_replacedKeyFromPropertyName
  43 +{
  44 + return @{
  45 + @"sid":@"id"
  46 + };
  47 +}
  48 +
  49 +@end
  50 +
  51 +@implementation CNTool
  52 +
  53 +MJCodingImplementation
  54 +
  55 +
  56 +@end
  57 +
... ...
CNLiveWitnessVideoModule/Classes/Model/CNBWitnessPlayerModel.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Model/CNBWitnessPlayerModel.h
  1 +//
  2 +// CNBWitnessPlayerModel.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <Foundation/Foundation.h>
  9 +#import <AVFoundation/AVFoundation.h>
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +// playerLayer的填充模式(默认:等比例填充,直到一个维度到达区域边界)
  12 +typedef NS_ENUM(NSInteger, CNWitnesslayerLayerGravity) {
  13 + CNWitnessPlayerLayerGravityResize, // 非均匀模式。两个维度完全填充至整个视图区域
  14 + CNWitnessPlayerLayerGravityResizeAspect, // 等比例填充,直到一个维度到达区域边界
  15 + CNWitnessPlayerLayerGravityResizeAspectFill // 等比例填充,直到填充满整个视图区域,其中一个维度的部分区域会被裁剪
  16 +};
  17 +// 播放器的几种状态
  18 +typedef NS_ENUM(NSInteger, CNWitnessPlayerState) {
  19 + CNWitnessPlayerStateUnKonw, // 未知状态
  20 + CNWitnessPlayerStatepPrepare, // 准备播放
  21 + CNWitnessPlayerStateFailed, // 播放失败
  22 + CNWitnessPlayerStateBuffering, // 缓冲中
  23 + CNWitnessPlayerStatePlaying, // 播放中
  24 + CNWitnessPlayerStateStopped, // 播放结束
  25 + CNWitnessPlayerStatePause // 暂停播放
  26 +};
  27 +@interface CNBWitnessPlayerModel : NSObject
  28 +/** 进入后台是否自动暂停播放 */
  29 +@property (nonatomic, assign) BOOL isAutoPauseWhenBackGround;
  30 +
  31 +/** 是否自动播放 默认为YES*/
  32 +@property (nonatomic, assign) BOOL isAutoPlay;
  33 +/** 是否要使用边下边播 */
  34 +@property (nonatomic, assign) BOOL useDownAndPlay;
  35 +
  36 +/** 视频的填充模式 */
  37 +@property (nonatomic, strong) AVLayerVideoGravity videoGravity;
  38 +
  39 +/** 视频标题 */
  40 +@property (nonatomic, copy ) NSString *title;
  41 +/** 作者名 */
  42 +@property (nonatomic, copy) NSString *artist;
  43 +/** 视频URL */
  44 +@property (nonatomic, strong) NSURL *videoURL;
  45 +@property (nonatomic, copy) NSString *pid;
  46 +/** 视频封面本地图片 */
  47 +@property (nonatomic, strong) UIImage *placeholderImage;
  48 +/** 播放器View的父视图(非cell播放使用这个)*/
  49 +@property (nonatomic, weak ) UIView *fatherView;
  50 +
  51 +/**
  52 + * 视频封面网络图片url
  53 + * 如果和本地图片同时设置,则忽略本地图片,显示网络图片
  54 + */
  55 +@property (nonatomic, copy ) NSString *placeholderImageURLString;
  56 +/**
  57 + * 视频分辨率字典, 分辨率标题与该分辨率对应的视频URL.
  58 + * 例如: @{@"高清" : @"https://xx/xx-hd.mp4", @"标清" : @"https://xx/xx-sd.mp4"}
  59 + */
  60 +@property (nonatomic, strong) NSDictionary<NSString *, NSString *> *resolutionDic;
  61 +/** 从xx秒开始播放视频(默认0) */
  62 +@property (nonatomic, assign) NSInteger seekTime;
  63 +// cell播放视频,以下属性必须设置值
  64 +@property (nonatomic, strong) UIScrollView *scrollView;
  65 +/** cell所在的indexPath */
  66 +@property (nonatomic, strong) NSIndexPath *indexPath;
  67 +/**
  68 + * cell上播放必须指定
  69 + * 播放器View的父视图tag(根据tag值在cell里查找playerView加到哪里)
  70 + */
  71 +@property (nonatomic, assign) NSInteger fatherViewTag;
  72 +
  73 +@end
  74 +
  75 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/Model/CNBWitnessPlayerModel.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Model/CNBWitnessPlayerModel.m
  1 +//
  2 +// CNBWitnessPlayerModel.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessPlayerModel.h"
  9 +
  10 +@implementation CNBWitnessPlayerModel
  11 +- (instancetype)init {
  12 + if (self = [super init]) {
  13 + self.useDownAndPlay = YES;
  14 + self.isAutoPlay = YES;
  15 + self.videoGravity = AVLayerVideoGravityResizeAspect;
  16 + self.isAutoPauseWhenBackGround = YES;
  17 + }
  18 + return self;
  19 +}
  20 +@end
... ...
CNLiveWitnessVideoModule/Classes/Services/CNBWitnessVideoService.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Services/CNBWitnessVideoService.h
  1 +//
  2 +// CNBWitnessVideoService.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/21.
  6 +//
  7 +
  8 +#import <Foundation/Foundation.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNBWitnessVideoService : NSObject
  13 +
  14 +@end
  15 +
  16 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/Services/CNBWitnessVideoService.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/Services/CNBWitnessVideoService.m
  1 +//
  2 +// CNBWitnessVideoService.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/21.
  6 +//
  7 +
  8 +#import "CNBWitnessVideoService.h"
  9 +#import <CNLiveBeeHive/BeeHive.h>
  10 +#import "CNBWitnessListController.h"
  11 +#import "CNBWitnessVideoPlayProtocol.h"
  12 +@interface CNBWitnessVideoService () <CNBWitnessVideoPlayProtocol>
  13 +
  14 +@end
  15 +@BeeHiveService(CNBWitnessVideoPlayProtocol,CNBWitnessVideoService)
  16 +@implementation CNBWitnessVideoService
  17 +- (void)pushToWitnessVideoController:(NSDictionary *)data currentIndex:(NSInteger)currentIndex pageNum:(NSInteger)pageNum type:(NSString *)type {
  18 + CNBWitnessListController *witnessVc = [[CNBWitnessListController alloc]initControllerWithData:data currentIndex:currentIndex pageNum:pageNum type:type];
  19 +// CATransition* transition = [CATransition animation];
  20 +// transition.duration = 0.25f;
  21 +// transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
  22 +// transition.type = kCATransitionPush;
  23 +// transition.subtype = kCATransitionFromRight;
  24 + [[self navigationViewController] pushViewController:witnessVc animated:YES];
  25 +}
  26 +#pragma mark -获取当前导航栏
  27 +- (UINavigationController *)navigationViewController {
  28 +
  29 + UIWindow *window = [UIApplication sharedApplication].keyWindow;
  30 +
  31 + if ([window.rootViewController isKindOfClass:[UINavigationController class]]) {
  32 +
  33 + return (UINavigationController *)window.rootViewController;
  34 +
  35 + } else if ([window.rootViewController isKindOfClass:[UITabBarController class]]) {
  36 +
  37 + UIViewController *selectVc = [((UITabBarController *)window.rootViewController)selectedViewController];
  38 +
  39 + if ([selectVc isKindOfClass:[UINavigationController class]]) {
  40 +
  41 + return (UINavigationController *)selectVc;
  42 +
  43 + }
  44 +
  45 + }
  46 +
  47 + return nil;
  48 +
  49 +}
  50 +@end
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessListCell.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessListCell.h
  1 +//
  2 +// CNBWitnessListCell.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +NS_ASSUME_NONNULL_BEGIN
  10 +@class CNBWitnessListModel;
  11 +@interface CNBWitnessListCell : UITableViewCell
  12 +@property (nonatomic, strong) CNBWitnessListModel *witnessModel;
  13 +@property (nonatomic, copy) NSString *type;
  14 +@property (nonatomic, strong) UIView *playerFaterView;
  15 +@end
  16 +
  17 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessListCell.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessListCell.m
  1 +//
  2 +// CNBWitnessListCell.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessListCell.h"
  9 +#import "UIColor+CNLiveExtension.h"
  10 +#import "NSString+CNLiveExtension.h"
  11 +#import "CNBWitnessListModel.h"
  12 +#import <YYKit/YYKit.h>
  13 +#import <Masonry/Masonry.h>
  14 +#import "CNLiveBaseKit.h"
  15 +#import <SDWebImage/SDWebImage.h>
  16 +#import <QMUIKit/QMUIKit.h>
  17 +#import "CNLiveQQEmotionManager.h"
  18 +@interface CNBWitnessListCell ()
  19 +@property (nonatomic, strong) UIImageView *coverImageView;
  20 +@property (nonatomic, strong) YYLabel *desc;//详情
  21 +@property (nonatomic, strong) UILabel *nickName;//名字
  22 +@property (nonatomic, strong) UILabel *dateLabel; //日期
  23 +@property (nonatomic, strong) UILabel *playCount; //播放次数
  24 +@property (nonatomic, strong) UIButton *tagButton; //标签按钮
  25 +@property (nonatomic, assign) NSInteger isHorizontalScreen; //根据封面图判断是不是横竖屏,如果封面图和返回的视频横竖屏不一样,隐藏后面封面图
  26 +@end
  27 +
  28 +@implementation CNBWitnessListCell
  29 +- (void)dealloc {
  30 + NSLog(@"目击者播放页cell走了释放吗");
  31 +}
  32 +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  33 + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  34 + if (self) {
  35 + self.selectionStyle = UITableViewCellSelectionStyleNone;
  36 + self.backgroundColor = [UIColor blackColor];
  37 + [self configUI];
  38 + }
  39 + return self;
  40 +}
  41 +#pragma mark - 配置UI
  42 +- (void)configUI {
  43 + [self.contentView addSubview:self.coverImageView];
  44 + [self.contentView addSubview:self.playerFaterView];
  45 + [self.contentView addSubview:self.dateLabel];
  46 + [self.contentView addSubview:self.desc];
  47 + [self.contentView addSubview:self.nickName];
  48 + [self.contentView addSubview:self.playCount];
  49 + [self.contentView addSubview:self.tagButton];
  50 + [self addMasony];
  51 +}
  52 +- (void)addMasony {
  53 + __weak typeof(self)weakSelf = self;
  54 + [_coverImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  55 + make.edges.equalTo(weakSelf.contentView);
  56 + }];
  57 + [_playerFaterView mas_makeConstraints:^(MASConstraintMaker *make) {
  58 + make.edges.equalTo(weakSelf.contentView);
  59 + }];
  60 + CGFloat margain = 0 ;
  61 + if (IS_IPhoneX_All) {
  62 + margain = 20;
  63 + }else {
  64 + margain = 40;
  65 + }
  66 + [_dateLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  67 + make.bottom.mas_equalTo(weakSelf.contentView.mas_bottom).offset(-margain-kVerticalBottomSafeHeight);
  68 + make.left.mas_equalTo(weakSelf.contentView.mas_left).offset(17);
  69 + make.width.mas_equalTo(83);
  70 + make.height.mas_equalTo(10);
  71 + }];
  72 + [_desc mas_makeConstraints:^(MASConstraintMaker *make) {
  73 + make.left.equalTo(weakSelf).offset(10);
  74 + make.bottom.equalTo(weakSelf.dateLabel.mas_top).offset(-20);
  75 + // make.bottom.equalTo(self).offset(-(60 + SafeAreaBottomHeight));
  76 + make.width.mas_equalTo(KScreenWidth/5*3);
  77 + }];
  78 +
  79 + [_nickName mas_makeConstraints:^(MASConstraintMaker *make) {
  80 + make.left.mas_equalTo(weakSelf).offset(10);
  81 + make.bottom.mas_equalTo(weakSelf.desc.mas_top).offset(-10);
  82 + make.width.mas_lessThanOrEqualTo(KScreenWidth/4*3 + 30);
  83 + }];
  84 +
  85 + [_playCount mas_makeConstraints:^(MASConstraintMaker *make) {
  86 + make.left.mas_equalTo(weakSelf.dateLabel.mas_right).offset(8);
  87 + make.top.mas_equalTo(weakSelf.dateLabel.mas_top);
  88 + make.width.mas_equalTo(70);
  89 + make.height.mas_equalTo(10);
  90 + }];
  91 + [_tagButton mas_makeConstraints:^(MASConstraintMaker *make) {
  92 + make.left.mas_equalTo(weakSelf.playCount.mas_right).offset(15);
  93 + make.centerY.mas_equalTo(weakSelf.dateLabel.mas_centerY);
  94 + make.width.mas_equalTo(46);
  95 + make.height.mas_equalTo(25);
  96 + }];
  97 +}
  98 +#pragma mark - getterAndSetter
  99 +- (void)setWitnessModel:(CNBWitnessListModel *)witnessModel {
  100 + _witnessModel = witnessModel;
  101 + __weak typeof(self) weakSelf = self;
  102 + self.coverImageView.hidden = NO;
  103 + [self.coverImageView sd_setImageWithURL:[NSURL URLWithString:CNLiveStringIsEmpty(witnessModel.poster)?@"":witnessModel.poster] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
  104 +
  105 + if (image.size.height >= image.size.width) {
  106 + self.coverImageView.contentMode = UIViewContentModeScaleAspectFill;
  107 + self.isHorizontalScreen = 0;
  108 + }else {
  109 + self.coverImageView.contentMode = UIViewContentModeScaleAspectFit;
  110 + self.isHorizontalScreen = 1;
  111 + }
  112 + }];
  113 +
  114 + //@目击者
  115 + [_nickName setText:[NSString stringWithFormat:@"@%@", witnessModel.icon.name]];
  116 +
  117 + //内容
  118 + _desc.text = witnessModel.title;
  119 + [_desc mas_updateConstraints:^(MASConstraintMaker *make) {
  120 + make.height.mas_equalTo([weakSelf descibeDetailsHeight:witnessModel.title]);
  121 + }];
  122 + if (!CNLiveStringIsEmpty(witnessModel.title)) {
  123 + [_nickName mas_remakeConstraints:^(MASConstraintMaker *make) {
  124 + make.left.mas_equalTo(weakSelf).offset(10);
  125 + make.bottom.mas_equalTo(weakSelf.desc.mas_top).offset(-10);
  126 + make.width.mas_lessThanOrEqualTo(SCREEN_WIDTH/4*3 + 30);
  127 + }];
  128 + }else {
  129 + [_nickName mas_remakeConstraints:^(MASConstraintMaker *make) {
  130 + make.left.mas_equalTo(weakSelf).offset(10);
  131 + make.bottom.mas_equalTo(weakSelf.dateLabel.mas_top).offset(-10);
  132 + make.width.mas_lessThanOrEqualTo(SCREEN_WIDTH/4*3 + 30);
  133 + }];
  134 + }
  135 + NSString *dateStr = [self getDateByTimeStamp:[NSString stringWithFormat:@"%ld",witnessModel.time]];
  136 + NSString *datestr1 = [dateStr substringWithRange:NSMakeRange(5, 5)];
  137 + NSString *timeStr = [dateStr substringWithRange:NSMakeRange(10, 6)];
  138 +
  139 + [self.dateLabel setText:[NSString stringWithFormat:@"%@ %@",datestr1,timeStr]];
  140 + // _dateLabel.text = @"12-23 23:23";
  141 + [self.playCount setText:[NSString stringWithFormat:@"%ld次播放",witnessModel.tool.playNum]];
  142 + if (!CNLiveStringIsEmpty(witnessModel.tagName)) {
  143 + [self.tagButton setTitle:witnessModel.tagName forState:UIControlStateNormal];
  144 + YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(MAXFLOAT,25)];
  145 + NSMutableAttributedString *tagStr = [[NSMutableAttributedString alloc]initWithString:witnessModel.tagName];
  146 + tagStr.font = [UIFont systemFontOfSize:11];
  147 + YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:tagStr];
  148 + CGFloat width = ceilf(layout.textBoundingSize.width);
  149 + if (width < 46) {
  150 + width = 46;
  151 + }
  152 + if (width > KScreenWidth - 200) {
  153 + width = KScreenWidth - 200;
  154 + }
  155 + [_tagButton mas_remakeConstraints:^(MASConstraintMaker *make) {
  156 + make.left.mas_equalTo(weakSelf.playCount.mas_right).offset(15);
  157 + make.centerY.mas_equalTo(weakSelf.dateLabel.mas_centerY);
  158 + make.width.mas_equalTo(width);
  159 + make.height.mas_equalTo(25);
  160 + }];
  161 + self.tagButton.hidden = NO;
  162 + }else {
  163 + self.tagButton.hidden = YES;
  164 + }
  165 +}
  166 +
  167 +#pragma mark -高度计算
  168 +- (CGFloat)descibeDetailsHeight:(NSString *)title {
  169 + NSString *contentText = [NSString stringWithFormat:@"%@",title];
  170 + NSMutableAttributedString *attStr = [self replaceQQemojiWithCustomText:contentText];
  171 + NSMutableAttributedString *attributes = [[NSMutableAttributedString alloc] initWithAttributedString:attStr];
  172 + [attributes addAttribute:NSForegroundColorAttributeName value:CNLiveColorWithHexString(@"FFFFFF") range:NSMakeRange(0, attStr.length)];
  173 + [attributes addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Regular" size:15.0f] range:NSMakeRange(0, attStr.length)];
  174 + YYTextContainer *textContainer = [YYTextContainer containerWithSize:CGSizeMake(KScreenWidth/5*3, HUGE)];
  175 + textContainer.maximumNumberOfRows = 2;
  176 + textContainer.truncationType = YYTextTruncationTypeEnd;
  177 + YYTextLayout *textLayout = [YYTextLayout layoutWithContainer:textContainer text:attributes];
  178 + _desc.textLayout = textLayout;
  179 + CGFloat desH = textLayout.textBoundingSize.height;
  180 + return desH;
  181 +}
  182 +- (NSMutableAttributedString *)replaceQQemojiWithCustomText:(NSString *)text
  183 +{
  184 + if (text == nil || [text isEqualToString:@""]) return [[NSMutableAttributedString alloc] initWithString:@""];
  185 + //过滤未知字符
  186 + text = [NSString filterUnknownChara:text];
  187 +
  188 + //利用正则 取出 [开头 ]结尾 的数组,内容通配 ,再次forin QQEmojiArr,得到真正的表情个数,再替换删除
  189 + NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
  190 +
  191 + NSString *zhengze = @"\\[(.*?)\\]";
  192 + NSError *error;
  193 + NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:zhengze options:NSRegularExpressionCaseInsensitive error:&error];
  194 + if (!re) {
  195 + NSLog(@"正则表达式匹配错误%@",[error localizedDescription]);
  196 + }
  197 + NSArray * arr = [re matchesInString:text options:0 range:NSMakeRange(0, text.length)];
  198 + if (!arr.count) {//说明字符串中没有表情通配符,是普通的文本
  199 +
  200 + }else{//有表情通配符
  201 + //如果有多个表情图,必须从后往前替换,因为替换后Range就不准确了
  202 + NSArray<QMUIEmotion *> *emojiArr = [CNLiveQQEmotionManager emotionsForQQ];
  203 + for (int i = (int)arr.count - 1; i >= 0; i --) {
  204 + //NSTextCheckingResult里面包含range
  205 + NSTextCheckingResult * result = arr[i];
  206 +
  207 + for (int j = 0; j < emojiArr.count; j ++) {
  208 + if ([[text substringWithRange:result.range] isEqualToString:emojiArr[j].displayName]) {
  209 + @try {
  210 + if (![NSThread isMainThread]) {
  211 + dispatch_sync(dispatch_get_main_queue(), ^{
  212 + YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:emojiArr[j].image];
  213 + imageView.width = 24*RATIO;
  214 + imageView.height = 24*RATIO;
  215 + NSMutableAttributedString *attachText = [NSMutableAttributedString attachmentStringWithContent:imageView contentMode:UIViewContentModeCenter attachmentSize:imageView.size alignToFont:UIFontCNMake(contentLabelFontSize) alignment:YYTextVerticalAlignmentCenter];
  216 + [attStr replaceCharactersInRange:result.range withAttributedString:attachText];
  217 + });
  218 + }else{
  219 + YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:emojiArr[j].image];
  220 + imageView.width = 24*RATIO;
  221 + imageView.height = 24*RATIO;
  222 + NSMutableAttributedString *attachText = [NSMutableAttributedString attachmentStringWithContent:imageView contentMode:UIViewContentModeCenter attachmentSize:imageView.size alignToFont:UIFontCNMake(contentLabelFontSize) alignment:YYTextVerticalAlignmentCenter];
  223 +
  224 + [attStr replaceCharactersInRange:result.range withAttributedString:attachText];
  225 + }
  226 + } @catch (NSException *exception) {
  227 + NSLog(@"获取的异常为=>%@",exception.reason);
  228 + }
  229 + }
  230 + }
  231 + }
  232 + }
  233 + return attStr;
  234 +}
  235 +
  236 +#pragma mark -数量换算
  237 +- (NSString *)formatCount:(NSInteger)count {
  238 + if (count >= 10000000) {
  239 + return @"10000万";
  240 + }
  241 + NSString *orderCount;
  242 + NSInteger tenThousand = (NSInteger)(count / 10000);
  243 + if(tenThousand > 0) {
  244 + NSInteger thousand = (NSInteger)((count - tenThousand * 10000) / 1000);
  245 + orderCount = [NSString stringWithFormat:@"%ld.%ld万",(long)tenThousand,(long)thousand];
  246 + } else {
  247 + orderCount = [NSString stringWithFormat:@"%ld",(long)count];
  248 + }
  249 + return orderCount;
  250 +}
  251 +#pragma mark - 根据时间戳返回时间
  252 +- (NSString *)getDateByTimeStamp:(NSString *)timeStampString
  253 +{
  254 +
  255 + // iOS 生成的时间戳是10位
  256 + NSTimeInterval interval =[timeStampString doubleValue] / 1000.0;
  257 + NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
  258 +
  259 + NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  260 + [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  261 + NSString *dateString = [formatter stringFromDate: date];
  262 + return dateString;
  263 +}
  264 +#pragma mark - 封面图显示隐藏通知(如果返回的封面图横竖屏和视频横竖屏不一样,隐藏)
  265 +- (void)coverImageHidden:(NSNotification *)noti {
  266 + NSString *str = noti.object;
  267 + __weak typeof(self) weakSelf = self;
  268 + if ([str isEqualToString:@"true"] && self.isHorizontalScreen != self.witnessModel.isHorizontalScreen) {
  269 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  270 + weakSelf.coverImageView.hidden = YES;
  271 + });
  272 +
  273 + }
  274 +}
  275 +#pragma mark - lazy
  276 +- (UIImageView *)coverImageView {
  277 + if (!_coverImageView) {
  278 + _coverImageView = [[UIImageView alloc]init];
  279 + _coverImageView.clipsToBounds = YES;
  280 + _coverImageView.contentMode = UIViewContentModeScaleAspectFit;
  281 + }
  282 + return _coverImageView;
  283 +}
  284 +- (UILabel *)dateLabel {
  285 + if (!_dateLabel) {
  286 + _dateLabel = [[UILabel alloc]init];
  287 + _dateLabel.textColor = CNLiveColorWithHexString(@"FFFFFF");
  288 + _dateLabel.font = [UIFont systemFontOfSize:12.0f];
  289 + _dateLabel.text = @"12-13 09:45";
  290 + _dateLabel.textAlignment = NSTextAlignmentLeft;
  291 + }
  292 + return _dateLabel;
  293 +}
  294 +- (YYLabel *)desc {
  295 + if (!_desc) {
  296 + _desc = [[YYLabel alloc]init];
  297 + _desc.textColor = CNLiveColorWithHexString(@"FFFFFF");
  298 + _desc.userInteractionEnabled = YES;
  299 + _desc.font = [UIFont fontWithName:@"PingFangSC-Regular" size:15.0f];
  300 + }
  301 + return _desc;
  302 +}
  303 +- (UILabel *)nickName {
  304 + if (!_nickName) {
  305 + _nickName = [[UILabel alloc]init];
  306 + _nickName.textColor = CNLiveColorWithHexString(@"FFFFFF");
  307 + _nickName.font = [UIFont systemFontOfSize:18.0];
  308 + _nickName.userInteractionEnabled = YES;
  309 + }
  310 + return _nickName;
  311 +}
  312 +- (UILabel *)playCount {
  313 + if (!_playCount) {
  314 + _playCount = [[UILabel alloc]init];
  315 + _playCount.textColor = CNLiveColorWithHexString(@"FFFFFF");
  316 + _playCount.font = [UIFont systemFontOfSize:12.0f];
  317 + _playCount.text = @"34次播放";
  318 + _playCount.textAlignment = NSTextAlignmentLeft;
  319 + }
  320 + return _playCount;
  321 +}
  322 +- (UIButton *)tagButton {
  323 + if (!_tagButton) {
  324 + _tagButton = [UIButton buttonWithType:UIButtonTypeCustom];
  325 + _tagButton.backgroundColor = CNLiveColorWithHexString(@"F4F4F4");
  326 + _tagButton.layer.cornerRadius = 12.5;
  327 + _tagButton.userInteractionEnabled = NO;
  328 + [_tagButton setTitle:@"社会" forState:UIControlStateNormal];
  329 + _tagButton.titleLabel.font = [UIFont systemFontOfSize:11];
  330 + _tagButton.hidden = YES;
  331 + _tagButton.titleLabel.numberOfLines = 1;
  332 + [_tagButton setTitleColor:CNLiveColorWithHexString(@"666666") forState:UIControlStateNormal];
  333 + }
  334 + return _tagButton;
  335 +}
  336 +- (UIView *)playerFaterView {
  337 + if (!_playerFaterView) {
  338 + _playerFaterView = [[UIView alloc]init];
  339 + }
  340 + return _playerFaterView;
  341 +}
  342 +@end
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerControlView.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerControlView.h
  1 +//
  2 +// CNBWitnessPlayerControlView.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +@protocol FailBtnActionDelegate <NSObject>
  12 +
  13 +- (void)failBtnAction;
  14 +
  15 +@end
  16 +@interface CNBWitnessPlayerControlView : UIView
  17 +//暂停按钮是否展示
  18 +- (void)showPauseViewAnim:(BOOL)play;
  19 +//加载中动画展示
  20 +- (void)startLoadingPlayItemAnim:(BOOL)isStart;
  21 +//取消延时隐藏controlView的方法
  22 +- (void)witness_playerCancelAutoFadeOutControlView ;
  23 +- (void)showFailBtn:(BOOL)isfail; //显示隐藏播放失败按钮
  24 +@property (nonatomic, weak) id <FailBtnActionDelegate>delegate;
  25 +@end
  26 +
  27 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerControlView.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerControlView.m
  1 +//
  2 +// CNBWitnessPlayerControlView.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessPlayerControlView.h"
  9 +#import <Masonry/Masonry.h>
  10 +#import "CNLiveBaseKit.h"
  11 +#import "CNBWitnessGetImage.h"
  12 +@interface CNBWitnessPlayerControlView ()
  13 +@property (nonatomic, strong) UIImageView *pauseIcon;
  14 +@property (nonatomic, strong) UIView *playerStatusBar;
  15 +@property (nonatomic, strong) UIButton *failBtn; //失败按钮
  16 +@end
  17 +
  18 +@implementation CNBWitnessPlayerControlView
  19 +- (instancetype)init {
  20 + if (self = [super init]) {
  21 + [self configUI];
  22 + }
  23 + return self;
  24 +}
  25 +
  26 +#pragma mark - 配置UI
  27 +- (void)configUI {
  28 + __weak typeof(self) weakSelf = self;
  29 + CGFloat margain = 0 ;
  30 + if (IS_IPhoneX_All) {
  31 + margain = 5.5;
  32 + }else {
  33 + margain = 25.5;
  34 + }
  35 + [self addSubview:self.pauseIcon];
  36 + [self addSubview:self.playerStatusBar];
  37 + [self addSubview:self.failBtn];
  38 + [_pauseIcon mas_makeConstraints:^(MASConstraintMaker *make) {
  39 + make.center.equalTo(weakSelf);
  40 + make.width.height.mas_equalTo(100);
  41 + }];
  42 + [_playerStatusBar mas_makeConstraints:^(MASConstraintMaker *make) {
  43 + make.centerX.equalTo(weakSelf);
  44 + make.bottom.mas_equalTo(weakSelf.mas_bottom).offset(-margain- kVerticalBottomSafeHeight);
  45 + make.width.mas_equalTo(1.0f);
  46 + make.height.mas_equalTo(0.5f);
  47 + }];
  48 + [self.failBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  49 + make.center.equalTo(self);
  50 + make.width.mas_equalTo(130);
  51 + make.height.mas_equalTo(33);
  52 + }];
  53 +}
  54 +#pragma mark -暂停播放动画
  55 +- (void)showPauseViewAnim:(BOOL)play {
  56 + __weak __typeof(self)weakSelf = self;
  57 + if(!play) {
  58 + [UIView animateWithDuration:0.25f
  59 + animations:^{
  60 + weakSelf.pauseIcon.alpha = 0.0f;
  61 + } completion:^(BOOL finished) {
  62 + [weakSelf.pauseIcon setHidden:YES];
  63 + }];
  64 + }else {
  65 + [weakSelf.pauseIcon setHidden:NO];
  66 + weakSelf.pauseIcon.transform = CGAffineTransformMakeScale(1.8f, 1.8f);
  67 + weakSelf.pauseIcon.alpha = 1.0f;
  68 +// _pauseIcon.image = [UIImage imageNamed:@"new_detail_head_play"];
  69 + _pauseIcon.image = [CNBWitnessGetImage cnBWitness_getImageName:@"new_detail_head_play" bundle:@"CNLiveWitnessVideoModule.bundle/CNLiveWitnessVideoModule" targetClass:[self class]];
  70 + [UIView animateWithDuration:0.25f delay:0
  71 + options:UIViewAnimationOptionCurveEaseIn animations:^{
  72 + weakSelf.pauseIcon.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  73 + } completion:^(BOOL finished) {
  74 + }];
  75 + }
  76 +}
  77 +#pragma mark -视频正在加载中动画
  78 +- (void)startLoadingPlayItemAnim:(BOOL)isStart {
  79 + if (isStart) {
  80 + _playerStatusBar.backgroundColor = [UIColor whiteColor];
  81 + [_playerStatusBar setHidden:NO];
  82 + [_playerStatusBar.layer removeAllAnimations];
  83 +
  84 + CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc]init];
  85 + animationGroup.duration = 0.5;
  86 + animationGroup.beginTime = CACurrentMediaTime() + 0.5;
  87 + animationGroup.repeatCount = MAXFLOAT;
  88 + animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  89 +
  90 + CABasicAnimation * scaleAnimation = [CABasicAnimation animation];
  91 + scaleAnimation.keyPath = @"transform.scale.x";
  92 + scaleAnimation.fromValue = @(1.0f);
  93 + scaleAnimation.toValue = @(1.0f * KScreenWidth);
  94 +
  95 + CABasicAnimation * alphaAnimation = [CABasicAnimation animation];
  96 + alphaAnimation.keyPath = @"opacity";
  97 + alphaAnimation.fromValue = @(1.0f);
  98 + alphaAnimation.toValue = @(0.5f);
  99 + [animationGroup setAnimations:@[scaleAnimation, alphaAnimation]];
  100 + [self.playerStatusBar.layer addAnimation:animationGroup forKey:nil];
  101 + } else {
  102 + [self.playerStatusBar.layer removeAllAnimations];
  103 + [self.playerStatusBar setHidden:YES];
  104 + }
  105 +}
  106 +#pragma mark -播放失败
  107 +- (void)failBtnClicked:(UIButton *)sender {
  108 + if (self.delegate && [self.delegate respondsToSelector:@selector(failBtnAction)]) {
  109 + [self.delegate failBtnAction];
  110 + }
  111 +}
  112 +- (void)showFailBtn:(BOOL)isfail {
  113 + if (isfail) {
  114 + self.failBtn.hidden = NO;
  115 + }else {
  116 + self.failBtn.hidden = YES;
  117 + }
  118 +}
  119 +#pragma mark - 取消延时隐藏controlView方法
  120 +- (void)witness_playerCancelAutoFadeOutControlView {
  121 + [NSObject cancelPreviousPerformRequestsWithTarget:self];
  122 +}
  123 +
  124 +#pragma mark -Lazy
  125 +
  126 +- (UIImageView *)pauseIcon {
  127 + if (!_pauseIcon) {
  128 + _pauseIcon = [[UIImageView alloc] init];
  129 +// _pauseIcon.image = [UIImage imageNamed:@"new_detail_head_play"];
  130 + _pauseIcon.image = [CNBWitnessGetImage cnBWitness_getImageName:@"new_detail_head_play" bundle:@"CNLiveWitnessVideoModule.bundle/CNLiveWitnessVideoModule" targetClass:[self class]];
  131 + _pauseIcon.contentMode = UIViewContentModeCenter;
  132 + _pauseIcon.layer.zPosition = 3;
  133 + _pauseIcon.hidden = YES;
  134 + }
  135 + return _pauseIcon;
  136 +}
  137 +- (UIView *)playerStatusBar {
  138 + if (!_playerStatusBar) {
  139 + _playerStatusBar = [[UIView alloc]init];
  140 + _playerStatusBar.backgroundColor = [UIColor whiteColor];
  141 + [_playerStatusBar setHidden:NO];
  142 + }
  143 + return _playerStatusBar;
  144 +}
  145 +- (UIButton *)failBtn {
  146 + if (!_failBtn) {
  147 + _failBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  148 + [_failBtn setTitle:@"加载失败,点击重试" forState:UIControlStateNormal];
  149 + [_failBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  150 + _failBtn.titleLabel.font = [UIFont systemFontOfSize:14.0f];
  151 + _failBtn.backgroundColor = RGBA(0, 0, 0, 0.7);
  152 + _failBtn.hidden = YES;
  153 + [_failBtn addTarget:self action:@selector(failBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  154 + }
  155 + return _failBtn;
  156 +}
  157 +
  158 +@end
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerManager.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerManager.h
  1 +//
  2 +// CNBWitnessPlayerManager.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <Foundation/Foundation.h>
  9 +#import "CNBWitnessPlayerModel.h"
  10 +@class CNBWitnessPlayerView;
  11 +NS_ASSUME_NONNULL_BEGIN
  12 +
  13 +@interface CNBWitnessPlayerManager : NSObject
  14 ++ (CNBWitnessPlayerManager *)shareManager;
  15 +//原始的(http)网络路径
  16 +@property (nonatomic, strong) NSURL *originVideoURL;
  17 +/** 播放器View的父视图*/
  18 +@property (strong, nonatomic, readonly) CNBWitnessPlayerView *playerView;
  19 +@property (nonatomic, strong, readonly) CNBWitnessPlayerModel *playerModel;
  20 +//@property (nonatomic, assign) BOOL isAgress4G;
  21 +/**
  22 + * 播放
  23 + */
  24 +- (void)play;
  25 +
  26 +/**
  27 + * 暂停
  28 + */
  29 +- (void)pause;
  30 +
  31 +/*
  32 + * 非手动播放
  33 + */
  34 +- (void)autoPlay;
  35 +
  36 +/*
  37 + *非手动暂停
  38 + */
  39 +- (void)autoPause;
  40 +
  41 +/**
  42 + * 重置player
  43 + */
  44 +- (void)resetPlayer;
  45 +
  46 +
  47 +
  48 +/**
  49 + 在当前页面,设置新的视频时候调用此方法
  50 +
  51 + */
  52 +- (void)resetToPlayNewVideo;
  53 +//静音播放
  54 +- (void)shouldMute;
  55 +//恢复声音
  56 +- (void)restoreVoice;
  57 +- (CGFloat)rate;
  58 +
  59 +@end
  60 +
  61 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerManager.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerManager.m
  1 +//
  2 +// CNBWitnessPlayerManager.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessPlayerManager.h"
  9 +#import <AVFoundation/AVFoundation.h>
  10 +#import "CNBWitnessPlayerView.h"
  11 +#import "CNBWitnessPlayerControlView.h"
  12 +
  13 +@interface CNBWitnessPlayerManager ()<CNWitnessPlayerDelegate>
  14 +@property (nonatomic, strong) CNBWitnessPlayerView *playerView;
  15 +@property (nonatomic, strong) CNBWitnessPlayerModel *playerModel;
  16 +@property (nonatomic, strong) CNBWitnessPlayerControlView *playerControlView;
  17 +@end
  18 +
  19 +@implementation CNBWitnessPlayerManager
  20 ++ (CNBWitnessPlayerManager *)shareManager {
  21 + static dispatch_once_t once;
  22 + static CNBWitnessPlayerManager *manager;
  23 + dispatch_once(&once, ^{
  24 + manager = [CNBWitnessPlayerManager new];
  25 + });
  26 + return manager;
  27 +}
  28 +- (void)dealloc {
  29 + [self resetPlayer];
  30 +}
  31 +#pragma mark - play
  32 +- (void)play {
  33 + [self.playerView play];
  34 +}
  35 +#pragma mark - pause
  36 +- (void)pause {
  37 + [self.playerView pause];
  38 +}
  39 +#pragma mark - 非手动播放
  40 +- (void)autoPlay {
  41 + [self.playerView autoPlay];
  42 +}
  43 +#pragma mark - 非手动暂停
  44 +- (void)autoPause {
  45 + [self.playerView autoPause];
  46 +}
  47 +
  48 +#pragma mark - 重置player为nil
  49 +- (void)resetPlayer {
  50 + [self.playerView resetPlayer];
  51 +}
  52 +#pragma mark - 在当前页面,设置新的视频时候调用此方法
  53 +- (void)resetToPlayNewVideo {
  54 + [self.playerView resetToPlayNewVideo:self.playerModel];
  55 +}
  56 +
  57 +#pragma mark - 静音播放
  58 +- (void)shouldMute {
  59 + [self.playerView shouldMute];
  60 +}
  61 +#pragma mark - 恢复声音
  62 +- (void)restoreVoice {
  63 + [self.playerView restoreVoice];
  64 +}
  65 +#pragma mark - 播放速率
  66 +- (CGFloat)rate {
  67 + return [self.playerView rate];
  68 +}
  69 +
  70 +
  71 +- (void)witnessPlayerStatusChange:(CNWitnessPlayerState)status {
  72 + //如果是本地且播放失败
  73 + if(status == CNWitnessPlayerStateFailed ) {
  74 + //如果是播放的本地文件失败,那么删除掉本地文件然后播放网络资源
  75 + self.playerModel.videoURL = self.originVideoURL;
  76 + [self resetToPlayNewVideo];//WithplayNowRealType:NO];
  77 + }
  78 +}
  79 +#pragma marl - Lazy
  80 +- (CNBWitnessPlayerModel *)playerModel {
  81 + if (!_playerModel) {
  82 + _playerModel = [[CNBWitnessPlayerModel alloc]init];
  83 + }
  84 + return _playerModel;
  85 +}
  86 +- (CNBWitnessPlayerView *)playerView {
  87 + if (!_playerView) {
  88 + _playerView = [[CNBWitnessPlayerView alloc]init];
  89 + _playerView.delegate = self;
  90 + [_playerView playerControlView:self.playerControlView playerModel:self.playerModel];
  91 + }
  92 + return _playerView;
  93 +}
  94 +- (CNBWitnessPlayerControlView *)playerControlView {
  95 + if (!_playerControlView) {
  96 + _playerControlView = [[CNBWitnessPlayerControlView alloc]init];
  97 + }
  98 + return _playerControlView;
  99 +}
  100 +@end
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerView.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerView.h
  1 +//
  2 +// CNBWitnessPlayerView.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +#import "CNBWitnessPlayerModel.h"
  10 +@class CNBWitnessPlayerControlView;
  11 +NS_ASSUME_NONNULL_BEGIN
  12 +@protocol CNWitnessPlayerDelegate <NSObject>
  13 +//播放器状态改变通知
  14 +- (void)witnessPlayerStatusChange:(CNWitnessPlayerState)status ;
  15 +
  16 +@end
  17 +@interface CNBWitnessPlayerView : UIView
  18 +@property (nonatomic, strong) AVPlayer *player;
  19 +@property (nonatomic, strong) CNBWitnessPlayerModel *playerModel;
  20 +@property (nonatomic, strong) NSURL *videoURL;
  21 +/** 设置playerLayer的填充模式 */
  22 +@property (nonatomic, assign) CNWitnesslayerLayerGravity playerLayerGravity;
  23 +/** 是否有下载功能(默认是关闭) */
  24 +@property (nonatomic, assign) BOOL hasDownload;
  25 +/** 是否开启预览图 */
  26 +@property (nonatomic, assign) BOOL hasPreviewView;
  27 +@property (nonatomic, assign) BOOL isPauseByUser;
  28 +/** 播发器的几种状态 */
  29 +@property (nonatomic, assign) CNWitnessPlayerState state;
  30 +@property (nonatomic, assign) BOOL stopPlayWhileCellNotVisable;
  31 +/** 当cell播放视频由全屏变为小屏时候,是否回到中间位置(默认YES) */
  32 +@property (nonatomic, assign) BOOL cellPlayerOnCenter;
  33 +/** player在栈上,即此时push或者模态了新控制器 */
  34 +@property (nonatomic, assign) BOOL playerPushedOrPresented;
  35 +@property (nonatomic, weak) id <CNWitnessPlayerDelegate> delegate;
  36 +/**
  37 + * 指定播放的控制层和模型
  38 + * 控制层传nil,默认使用ZFPlayerControlView(如自定义可传自定义的控制层)
  39 + */
  40 +- (void)playerControlView:(CNBWitnessPlayerControlView *)controlView playerModel:(CNBWitnessPlayerModel *)playerModel;
  41 +
  42 +/**
  43 + * 使用自带的控制层时候可使用此API
  44 + */
  45 +- (void)playerModel:(CNBWitnessPlayerModel *)playerModel;
  46 +
  47 +/**
  48 + * 自动播放,默认不自动播放
  49 + */
  50 +- (void)autoPlayTheVideo;
  51 +/**
  52 + * 重置player
  53 + */
  54 +- (void)resetPlayer;
  55 +
  56 +/**
  57 + * 在当前页面,设置新的视频时候调用此方法
  58 + */
  59 +- (void)resetToPlayNewVideo:(CNBWitnessPlayerModel *)playerModel;
  60 +
  61 +/**
  62 + * 播放
  63 + */
  64 +- (void)play;
  65 +
  66 +/**
  67 + * 暂停
  68 + */
  69 +- (void)pause;
  70 +
  71 +
  72 +/*
  73 + * 非手动播放(不是用户主动点击继续播放)
  74 + */
  75 +- (void)autoPlay;
  76 +
  77 +/*
  78 + *非手动暂停(不是用户点击暂停)
  79 + */
  80 +- (void)autoPause;
  81 +//静音播放
  82 +- (void)shouldMute;
  83 +//恢复声音
  84 +- (void)restoreVoice;
  85 +//播放速度
  86 +- (CGFloat)rate;
  87 +@end
  88 +
  89 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerView.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/View/CNBWitnessPlayerView.m
  1 +//
  2 +// CNBWitnessPlayerView.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessPlayerView.h"
  9 +#import "CNBWitnessPlayerModel.h"
  10 +#import <AVFoundation/AVFoundation.h>
  11 +#import <MediaPlayer/MediaPlayer.h>
  12 +#import "CNBWitnessPlayerControlView.h"
  13 +#import "CNLiveNetworking.h"
  14 +#import <Masonry/Masonry.h>
  15 +#import <QMUIKit/QMUIKit.h>
  16 +#define CNBWitnessAppKeyWindow [UIApplication sharedApplication].delegate.window
  17 +@interface CNBWitnessPlayerView ()<UIAlertViewDelegate,FailBtnActionDelegate>
  18 +/** 播放属性 */
  19 +
  20 +@property (nonatomic, strong) AVPlayerItem *playerItem;
  21 +@property (nonatomic, strong) AVURLAsset *urlAsset;
  22 +@property (nonatomic, strong) AVAssetImageGenerator *imageGenerator;
  23 +/** playerLayer */
  24 +@property (nonatomic, strong) AVPlayerLayer *playerLayer;
  25 +@property (nonatomic, strong) id timeObserve;
  26 +/** 是否在调节音量*/
  27 +@property (nonatomic, assign) BOOL isVolume;
  28 +/** 是否播放本地文件 */
  29 +@property (nonatomic, assign) BOOL isLocalVideo;
  30 +/** 是否再次设置URL播放视频 */
  31 +@property (nonatomic, assign) BOOL repeatToPlay;
  32 +/** 播放完了*/
  33 +@property (nonatomic, assign) BOOL playDidEnd;
  34 +/** 进入后台*/
  35 +@property (nonatomic, assign) BOOL didEnterBackground;
  36 +@property (nonatomic, strong) NSArray *videoURLArray;
  37 +/** player所在cell的indexPath */
  38 +@property (nonatomic, strong) NSIndexPath *indexPath;
  39 +
  40 +@property (nonatomic, strong) CNBWitnessPlayerControlView *controlView;
  41 +@property (nonatomic, assign) NSInteger seekTime;
  42 +@property (nonatomic, strong) NSDictionary *resolutionDic;
  43 +@property (nonatomic, strong) dispatch_queue_t cancelLoadingQueue;
  44 +@property (nonatomic, assign) BOOL isCurPlayerPause; //退到后台时是否在播放
  45 +@property (nonatomic, assign) BOOL isPlayingAudio;
  46 +@property (nonatomic, assign) BOOL isOtherPlaying; //其他音乐在播放
  47 +@end
  48 +
  49 +@implementation CNBWitnessPlayerView
  50 +- (instancetype)init {
  51 + if (self = [super init]) {
  52 +
  53 + }
  54 + return self;
  55 +}
  56 +- (void)dealloc {
  57 + self.playerItem = nil;
  58 + self.urlAsset = nil;
  59 + [[NSNotificationCenter defaultCenter] removeObserver:self];
  60 + [self.controlView witness_playerCancelAutoFadeOutControlView] ;
  61 + // 移除time观察者
  62 + if (self.timeObserve) {
  63 + [self.player removeTimeObserver:self.timeObserve];
  64 + self.timeObserve = nil;
  65 + }
  66 +
  67 +}
  68 +- (void)layoutSubviews {
  69 + [super layoutSubviews];
  70 + self.playerLayer.frame = self.bounds;
  71 +}
  72 +#pragma mark - 添加单击手势
  73 +- (void)createGesture {
  74 + UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTapAction:)];
  75 + singleTap.numberOfTapsRequired = 1;
  76 + singleTap.numberOfTouchesRequired = 1;
  77 + [self addGestureRecognizer:singleTap];
  78 +
  79 +}
  80 +#pragma mark - 单击手势
  81 +- (void)singleTapAction:(UIGestureRecognizer *)gesture {
  82 + if ([gesture isKindOfClass:[NSNumber class]] && ![(id)gesture boolValue]) {
  83 + return;
  84 + }
  85 + if (gesture.state == UIGestureRecognizerStateRecognized) {
  86 + [self updatePlayer];
  87 + }
  88 +}
  89 +#pragma mark - 添加通知
  90 +- (void)addNotifications {
  91 + // app启动或者app从后台进入前台都会调用这个方法
  92 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
  93 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterBackground) name: UIApplicationDidEnterBackgroundNotification object:nil];
  94 + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
  95 +}
  96 +#pragma mark - app进入前台通知
  97 +- (void)applicationBecomeActive {
  98 + if ([[self currentViewController] isKindOfClass:[NSClassFromString(@"CNWitnessVideoListController") class]]) {
  99 + if (![CNLiveNetworking isNetworking]) {
  100 + if ([self rate] > 0) {
  101 + [self autoPause];
  102 + }
  103 + }else if ([CNLiveNetworking isWiFiNetwork]) {
  104 + if (!self.isCurPlayerPause) {
  105 + [self autoPlay];
  106 + }
  107 + }else if ([CNLiveNetworking isWWANNetwork]) {
  108 + BOOL isAgress4G = [[NSUserDefaults standardUserDefaults] objectForKey:@"isAgress4G"];
  109 + if (isAgress4G) {
  110 + if (!self.isCurPlayerPause) {
  111 + [self autoPlay];
  112 + }
  113 + }
  114 + }
  115 +}
  116 +}
  117 +#pragma mark - app退出到后台
  118 +- (void)applicationEnterBackground {
  119 + self.isCurPlayerPause = ![self rate];
  120 + if ([self rate] > 0) {
  121 + [self autoPause];
  122 + }
  123 +}
  124 +#pragma mark ====== 耳机插入介绍🎧
  125 +- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
  126 +{
  127 + NSDictionary *interuptionDict = notification.userInfo;
  128 + NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
  129 + switch (routeChangeReason) {
  130 + case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
  131 + NSLog(@"耳机插入");
  132 + break;
  133 + case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
  134 + NSLog(@"耳机拔出,停止播放操作");
  135 + [self pause];
  136 + break;
  137 + case AVAudioSessionRouteChangeReasonCategoryChange:
  138 + break;
  139 + }
  140 +}
  141 +#pragma mark - 播放失败的时候
  142 +- (void)failBtnAction {
  143 + [self configPlayerWithWeb];
  144 +}
  145 +#pragma mark - 静音播放
  146 +- (void)shouldMute {
  147 + AVAudioSession *ses = [AVAudioSession sharedInstance];
  148 + [ses setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  149 + [ses setActive:YES error:nil];
  150 + self.player.muted = YES;
  151 +}
  152 +#pragma mark - 恢复声音
  153 +- (void)restoreVoice {
  154 + self.player.muted = NO;
  155 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  156 + AVAudioSession *ses = [AVAudioSession sharedInstance];
  157 + [ses setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  158 + [ses setCategory:AVAudioSessionCategoryPlayback error:nil];
  159 + [ses setActive:YES error:nil];
  160 + });
  161 +}
  162 + #pragma mark - 获取当前控制器
  163 +- (UIViewController*)currentViewController{
  164 + UIViewController* vc = [UIApplication sharedApplication].keyWindow.rootViewController;
  165 + while (1) {
  166 +
  167 + if ([vc isKindOfClass:[UITabBarController class]]) {
  168 +
  169 + vc = ((UITabBarController*)vc).selectedViewController;
  170 +
  171 + }
  172 + if ([vc isKindOfClass:[UINavigationController class]]) {
  173 +
  174 + vc = ((UINavigationController*)vc).visibleViewController;
  175 +
  176 + }
  177 + if (vc.presentedViewController) {
  178 +
  179 + vc = vc.presentedViewController;
  180 +
  181 + }else{
  182 +
  183 + break;
  184 +
  185 + }
  186 + }
  187 + return vc;
  188 +
  189 +}
  190 +#pragma mark - GetterAndSetter
  191 +- (void)setPlayerModel:(CNBWitnessPlayerModel *)playerModel {
  192 + _playerModel = playerModel;
  193 + [self addPlayerToFatherView:playerModel.fatherView];
  194 + self.videoURL = playerModel.videoURL;
  195 +
  196 +}
  197 +- (void)playerControlView:(CNBWitnessPlayerControlView *)controlView playerModel:(CNBWitnessPlayerModel *)playerModel {
  198 + self.controlView = controlView;
  199 + self.playerModel = playerModel;
  200 +}
  201 +#pragma mark - 设置控制层和播放参数
  202 +- (void)playerModel:(CNBWitnessPlayerModel *)playerModel {
  203 + [self playerControlView:nil playerModel:playerModel];
  204 +}
  205 +#pragma mark -player添加到父视图上
  206 +- (void)addPlayerToFatherView:(UIView *)view {
  207 + // 这里应该添加判断,因为view有可能为空,当view为空时[view addSubview:self]会crash
  208 + if (view) {
  209 + if(self.superview) {
  210 + [self removeFromSuperview];
  211 + }
  212 + [view addSubview:self];
  213 + [self mas_remakeConstraints:^(MASConstraintMaker *make) {
  214 + make.edges.mas_offset(UIEdgeInsetsZero);
  215 + }];
  216 + }
  217 +}
  218 +- (void)setControlView:(CNBWitnessPlayerControlView *)controlView {
  219 + if (_controlView) {
  220 + return;
  221 + }
  222 + _controlView = controlView;
  223 + _controlView.delegate = self;
  224 + [self addSubview:controlView];
  225 + [controlView mas_makeConstraints:^(MASConstraintMaker *make) {
  226 + make.edges.mas_equalTo(self);
  227 + }];
  228 +}
  229 +#pragma mark - 配置播放资源
  230 +- (void)playResource {
  231 + // 初始化playerItem
  232 + self.playerItem = [AVPlayerItem playerItemWithAsset:self.urlAsset];
  233 + // 每次都重新创建Player,替换replaceCurrentItemWithPlayerItem:,该方法阻塞线程
  234 + self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
  235 + // 初始化playerLayer
  236 + self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
  237 + self.playerLayer.videoGravity = self.playerModel.videoGravity;
  238 + // 增加下面这行可以解决iOS10兼容性问题了
  239 + if (@available(iOS 10.0, *)) {
  240 + self.player.automaticallyWaitsToMinimizeStalling = NO;
  241 + } else {
  242 + // Fallback on earlier versions
  243 + }
  244 + [self setAudioMode];
  245 + self.state = CNWitnessPlayerStateBuffering;
  246 + self.isLocalVideo = NO;
  247 + if (self.playerModel.isAutoPlay) {
  248 + [self play];
  249 + self.isCurPlayerPause = YES;
  250 + }else{
  251 + [self pause];
  252 + }
  253 +}
  254 +#pragma mark - 播放
  255 +- (void)configPlayerWithWeb {
  256 + self.urlAsset = [AVURLAsset assetWithURL:self.videoURL];
  257 + [self playResource];
  258 +}
  259 +#pragma mark - 自动播放,默认不自动播放
  260 +- (void)autoPlayTheVideo {
  261 + //设置player相关参数
  262 + [self configPlayerWithWeb];
  263 +}
  264 +#pragma mark - 在当前页面,设置新的视频时候调用此方法
  265 +- (void)resetToPlayNewVideo:(CNBWitnessPlayerModel *)playerModel {
  266 + self.repeatToPlay = YES;
  267 + [self resetPlayer];
  268 + self.playerModel = playerModel;
  269 + [self configPlayerWithWeb];
  270 +}
  271 +#pragma mark - 在当前页面,设置新的player的URL调用此方法
  272 +- (void)resetToPlayNewURL {
  273 + self.repeatToPlay = YES;
  274 + [self resetPlayer];
  275 +}
  276 +#pragma mark - 设置播放Url
  277 +- (void)setVideoURL:(NSURL *)videoURL {
  278 + _videoURL = videoURL;
  279 + //每次加载视频URL都设置重播为NO
  280 + self.repeatToPlay = NO;
  281 + self.playDidEnd = NO;
  282 + [self createGesture];
  283 + //添加通知
  284 + [self addNotifications];
  285 +}
  286 +#pragma mark - play方法
  287 +- (void)play {
  288 + [self.controlView showPauseViewAnim:NO];
  289 + if (self.state == CNWitnessPlayerStatePause) {
  290 + self.state = CNWitnessPlayerStatePlaying;
  291 + }
  292 + self.isPauseByUser = NO;
  293 + [_player play];
  294 +}
  295 +#pragma mark -暂停方法
  296 +- (void)pause {
  297 + [self.controlView showPauseViewAnim:YES];
  298 + if (self.state == CNWitnessPlayerStatePlaying) {
  299 + self.state = CNWitnessPlayerStatePause;
  300 + }
  301 + self.isPauseByUser = YES;
  302 + [_player pause];
  303 +
  304 + if (self.isOtherPlaying) {
  305 + [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
  306 + }
  307 +}
  308 +#pragma mark - 非手动播放
  309 +- (void)autoPlay {
  310 + if (!self.isPauseByUser) {
  311 + [self.controlView showPauseViewAnim:NO];
  312 + self.state = CNWitnessPlayerStatePlaying;
  313 + self.isPauseByUser = NO;
  314 + [self play];
  315 + }
  316 +}
  317 +#pragma mark - 非手动暂停
  318 +- (void)autoPause {
  319 + [self.controlView showPauseViewAnim:YES];
  320 + self.isPauseByUser = NO;
  321 + if(self.state == CNWitnessPlayerStatePlaying) {
  322 + self.state = CNWitnessPlayerStatePause;
  323 + }
  324 + [_player pause];
  325 + if (self.isOtherPlaying) {
  326 + [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
  327 + }
  328 +}
  329 +#pragma mark - 点击暂停或者播放
  330 +- (void)updatePlayer {
  331 + if (![CNLiveNetworking isNetworking]) {
  332 + if ([self rate] > 0) {
  333 + [self pause];
  334 + }else {
  335 + [QMUITips showWithText:@"您似乎断开与互联网的连接" inView:CNBWitnessAppKeyWindow hideAfterDelay:1.5];
  336 + return;
  337 + }
  338 + }else {
  339 + if ([CNLiveNetworking isWWANNetwork]) {
  340 + if ([self rate] > 0) {
  341 + [self pause];
  342 + }else {
  343 + BOOL isAggress4G = [[NSUserDefaults standardUserDefaults] objectForKey:@"isAgress4G"];
  344 + if (isAggress4G) {
  345 + [self play];
  346 + }else {
  347 + [self pause];
  348 + [self showAlertView];
  349 + }
  350 + }
  351 + }else {
  352 + if ([self rate] > 0) {
  353 + [self pause];
  354 + }else {
  355 + [self play];
  356 + }
  357 + }
  358 + }
  359 +
  360 +}
  361 +#pragma mark - 播放速度
  362 +- (CGFloat)rate {
  363 + return [_player rate];
  364 +}
  365 +#pragma mark - 设置播放状态
  366 +- (void)setState:(CNWitnessPlayerState)state {
  367 + _state = state;
  368 + //控制菊花显示隐藏
  369 + [self.controlView startLoadingPlayItemAnim:state == CNWitnessPlayerStateBuffering];
  370 + switch (state) {
  371 + case CNWitnessPlayerStateUnKonw:{ //未知状态
  372 +
  373 + }
  374 + break;
  375 + case CNWitnessPlayerStatepPrepare: { //准备播放
  376 +
  377 + }
  378 + break;
  379 + case CNWitnessPlayerStateFailed:{ //播放失败
  380 +
  381 + }
  382 + break;
  383 + case CNWitnessPlayerStateBuffering:{
  384 +
  385 + }
  386 + break;
  387 + case CNWitnessPlayerStatePlaying: {
  388 +
  389 + }
  390 + break;
  391 + case CNWitnessPlayerStateStopped:{
  392 +
  393 + }
  394 + break;
  395 + case CNWitnessPlayerStatePause:{
  396 +
  397 + }
  398 + break;
  399 +
  400 + default:
  401 + break;
  402 + }
  403 + if (self.delegate && [self.delegate respondsToSelector:@selector(witnessPlayerStatusChange:)]) {
  404 + [self.delegate witnessPlayerStatusChange:state];
  405 + }
  406 +}
  407 +
  408 +// 使用这个category的应用不会随着手机静音键打开而静音,可在手机静音下播放声音
  409 +- (void)setAudioMode {
  410 + AVAudioSession *ses = [AVAudioSession sharedInstance];
  411 + self.isOtherPlaying = [ses isOtherAudioPlaying];
  412 + [ses setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  413 + [ses setCategory:AVAudioSessionCategoryPlayback error:nil];
  414 + [ses setActive:YES error:nil];
  415 +}
  416 +
  417 +#pragma mark- 根据playerItem,来添加移除观察者
  418 +/**
  419 + * 根据playerItem,来添加移除观察者
  420 + *
  421 + * @param playerItem playerItem
  422 + */
  423 +- (void)setPlayerItem:(AVPlayerItem *)playerItem {
  424 + if (_playerItem == playerItem) {
  425 + return;
  426 + }
  427 + if (_playerItem) {
  428 + [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:_playerItem];
  429 + [_playerItem removeObserver:self forKeyPath:@"status"];
  430 + [_playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
  431 + [_playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
  432 + }
  433 + _playerItem = playerItem;
  434 + if (playerItem) {
  435 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
  436 + [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
  437 + // 缓冲区空了,需要等待数据
  438 + [playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
  439 + // 缓冲区有足够数据可以播放了
  440 + [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
  441 + }
  442 +}
  443 +#pragma mark - 重置player
  444 +- (void)resetPlayer {
  445 + // 改为为播放完
  446 + self.playDidEnd = NO;
  447 + self.urlAsset = nil;
  448 + self.playerItem = nil;
  449 + // self.isAutoPlay = YES;
  450 + // 视频跳转秒数置0
  451 + self.seekTime = 0;
  452 + // self.isAutoPlay = YES;
  453 + if (self.timeObserve) {
  454 + [self.player removeTimeObserver:self.timeObserve];
  455 + self.timeObserve = nil;
  456 + }
  457 + // 移除通知
  458 + [[NSNotificationCenter defaultCenter] removeObserver:self];
  459 + // 暂停
  460 + [self.player pause];
  461 + [self.player cancelPendingPrerolls];
  462 + // 移除原来的layer
  463 + [self.playerLayer removeFromSuperlayer];
  464 + // 把player置为nil
  465 + self.imageGenerator = nil;
  466 + self.player = nil;
  467 + self.controlView = nil;
  468 + // 非重播时,移除当前playerView
  469 + if (!self.repeatToPlay) {
  470 + [self removeFromSuperview];
  471 + }
  472 +}
  473 +#pragma mark - KVO
  474 +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
  475 + if (object == self.player.currentItem) {
  476 + if ([keyPath isEqualToString:@"status"]) {
  477 + if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
  478 + [self setNeedsLayout];
  479 + [self layoutIfNeeded];
  480 + //添加playerLayer到self.player
  481 + [self.layer insertSublayer:self.playerLayer atIndex:0];
  482 + self.state = CNWitnessPlayerStatepPrepare;
  483 + [[NSNotificationCenter defaultCenter] postNotificationName:@"WitnessCoverImageHidden" object:@"true" userInfo:nil];
  484 + [self.controlView showFailBtn:NO];
  485 + }else if (self.player.currentItem.status == AVPlayerItemStatusFailed) {
  486 + self.state = CNWitnessPlayerStateFailed;
  487 + if ([CNLiveNetworking isNetworking]) {
  488 + [self.controlView showFailBtn:YES];
  489 + }
  490 + }else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
  491 + //当缓冲是空的时候
  492 + if (self.playerItem.playbackBufferEmpty) {
  493 + self.state = CNWitnessPlayerStateBuffering;
  494 + [self bufferingSomeSecond];
  495 + }
  496 + }else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){
  497 + //当缓冲好的时候
  498 + if (self.playerItem.playbackLikelyToKeepUp && self.state == CNWitnessPlayerStateBuffering) {
  499 + self.state = CNWitnessPlayerStatePlaying;
  500 + }
  501 + }
  502 + }
  503 + }
  504 +
  505 +}
  506 +#pragma mark - 播放完了,从新播放
  507 +- (void)moviePlayDidEnd:(NSNotification *)noti {
  508 + [self seekToTime:kCMTimeZero completionHandler:nil];
  509 +}
  510 +#pragma mark - 从xx秒开始播放视频跳转
  511 +- (void)seekToTime:(CMTime)time completionHandler:(void (^)(BOOL finished))completionHandler {
  512 + if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
  513 + // seekTime:completionHandler:不能精确定位
  514 + // 如果需要精确定位,可以使用seekToTime:toleranceBefore:toleranceAfter:completionHandler:
  515 + // 转换成CMTime才能给player来控制播放进度
  516 + [self.controlView startLoadingPlayItemAnim:YES];
  517 + [self.player pause];
  518 + __weak typeof(self) weakSelf = self;
  519 + [self.player seekToTime:time completionHandler:^(BOOL finished) {
  520 + [weakSelf.controlView startLoadingPlayItemAnim:NO];
  521 + //视频跳转后回调
  522 + if (completionHandler){completionHandler(finished);}
  523 + if (self.isPauseByUser) {
  524 + return ; //如果这时候用户点了暂停,就不要开始了
  525 + }
  526 + [weakSelf.player play];
  527 + weakSelf.seekTime = 0;
  528 + if (!weakSelf.playerItem.isPlaybackLikelyToKeepUp) {
  529 + weakSelf.state = CNWitnessPlayerStateBuffering;
  530 + }
  531 + }];
  532 +
  533 + }
  534 +}
  535 +#pragma mark - 缓冲较差时候回调这里
  536 +- (void)bufferingSomeSecond {
  537 + self.state = CNWitnessPlayerStateBuffering;
  538 + // playbackBufferEmpty会反复进入,因此在bufferingOneSecond延时播放执行完之前再调用bufferingSomeSecond都忽略
  539 + __block BOOL isBuffering = NO;
  540 + if (isBuffering) return;
  541 + BOOL isAgress4G = [[NSUserDefaults standardUserDefaults] objectForKey:@"isAgress4G"];
  542 + if (![CNLiveNetworking isNetworking] || ([CNLiveNetworking isWWANNetwork] && !isAgress4G)) return;
  543 + isBuffering = YES;
  544 + // 需要先暂停一小会之后再播放,否则网络状况不好的时候时间在走,声音播放不出来
  545 + [self autoPause];
  546 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  547 +
  548 + // 如果此时用户已经暂停了,则不再需要开启播放了
  549 + if (self.isPauseByUser) {
  550 + isBuffering = NO;
  551 + return;
  552 + }
  553 +
  554 + [self autoPlay];
  555 + // 如果执行了play还是没有播放则说明还没有缓存好,则再次缓存一段时间
  556 + isBuffering = NO;
  557 + if (!self.playerItem.isPlaybackLikelyToKeepUp) {
  558 + [self bufferingSomeSecond];
  559 + }
  560 +
  561 + });
  562 +}
  563 +#pragma mark -网络弹框
  564 +- (void)showAlertView {
  565 +
  566 + UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"当前为非Wifi环境,已为您暂停播放" message:nil delegate:self cancelButtonTitle:@"" otherButtonTitles:@"继续播放", nil];
  567 + [alertView show];
  568 +}
  569 +//监听点击事件 代理方法
  570 +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  571 +{
  572 + if (buttonIndex==0) {
  573 + NSLog(@"你点击了取消");
  574 + }
  575 + else if (buttonIndex==1) {
  576 +// [CNWitnessAVPlayerManager shareManager].isAgress4G = YES;
  577 + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isAgree4G"];
  578 + [self play];
  579 + }
  580 +}
  581 +
  582 +@end
... ...
CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessGetImage.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessGetImage.h
  1 +//
  2 +// CNBWitnessGetImage.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <Foundation/Foundation.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNBWitnessGetImage : NSObject
  13 ++ (UIImage *)cnBWitness_getImageName:(NSString *)imageName bundle:(NSString *)bundlePath targetClass:(Class)targetClass;
  14 +@end
  15 +
  16 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessGetImage.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessGetImage.m
  1 +//
  2 +// CNBWitnessGetImage.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessGetImage.h"
  9 +
  10 +@implementation CNBWitnessGetImage
  11 ++ (UIImage *)cnBWitness_getImageName:(NSString *)imageName bundle:(NSString *)bundlePath targetClass:(Class)targetClass {
  12 + NSInteger scale = [[UIScreen mainScreen]scale];
  13 + NSBundle *bundle = [NSBundle bundleForClass:targetClass];
  14 + NSURL *url = [bundle URLForResource:bundlePath withExtension:@"bundle"];
  15 +
  16 + if (!url) {
  17 + return [UIImage new];
  18 + }
  19 + NSBundle *targetBundle = [NSBundle bundleWithURL:url];
  20 + if (!targetBundle) {
  21 + return [UIImage new];
  22 + }
  23 + NSString *imgName = [NSString stringWithFormat:@"%@@%zdx.png",imageName,scale];
  24 + UIImage *image = [UIImage imageNamed:imgName inBundle:targetBundle compatibleWithTraitCollection:nil];
  25 + if (image) {
  26 + return image;
  27 + }else {
  28 + if ([UIImage imageNamed:imgName inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil]) {
  29 + return [UIImage imageNamed:imgName inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil];
  30 + }else{
  31 + return [UIImage new];
  32 + }
  33 + }
  34 +}
  35 +@end
... ...
CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessListViewModel.h 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessListViewModel.h
  1 +//
  2 +// CNBWitnessListViewModel.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import <Foundation/Foundation.h>
  9 +
  10 +NS_ASSUME_NONNULL_BEGIN
  11 +
  12 +@interface CNBWitnessListViewModel : NSObject
  13 +
  14 ++ (void)getWitnessListDataTosid:(NSString *)toSid page:(NSInteger)page pageSize:(NSInteger)pageSize successBlock:(void(^)(NSMutableArray *dataArray,NSString *isHaveNext))successBlock failureBlock:(void (^)(NSError *error))failureBlock;
  15 +@end
  16 +
  17 +NS_ASSUME_NONNULL_END
... ...
CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessListViewModel.m 0 → 100644
  1 +++ a/CNLiveWitnessVideoModule/Classes/ViewModel/CNBWitnessListViewModel.m
  1 +//
  2 +// CNBWitnessListViewModel.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by 殷巧娟 on 2020/4/19.
  6 +//
  7 +
  8 +#import "CNBWitnessListViewModel.h"
  9 +#import "CNLiveEnvironment.h"
  10 +#import "NSString+CNLiveExtension.h"
  11 +#import "CNLiveNetworking.h"
  12 +#import "CNBWitnessListModel.h"
  13 +#import "MJExtension.h"
  14 +#import <QMUIKit/QMUIKit.h>
  15 +#define CNBWitnessAppKeyWindow ([UIApplication sharedApplication].delegate).window
  16 +@implementation CNBWitnessListViewModel
  17 ++ (void)getWitnessListDataTosid:(NSString *)toSid page:(NSInteger)page pageSize:(NSInteger)pageSize successBlock:(void(^)(NSMutableArray *dataArray,NSString *isHaveNext))successBlock failureBlock:(void (^)(NSError *error))failureBlock {
  18 + NSMutableArray *array = [NSMutableArray array];
  19 + NSString *url = @"";
  20 + NSDictionary *param = [NSDictionary dictionary];
  21 + param = @{
  22 + @"toSid" :CNLiveStringIsEmpty(toSid)? @"":toSid,
  23 + @"pageNo" :[NSString stringWithFormat:@"%ld",page],
  24 + @"pageSize" :[NSString stringWithFormat:@"%ld",pageSize],
  25 + @"type":@"0",
  26 + @"reviewStatus":@"1"
  27 + };
  28 + https://apiwjjtest.cnlive.com/Daren/bWitness/getBWitnessList.action
  29 + url = cn_API_Host(@"/Daren/bWitness/getBWitnessList.action");
  30 + [CNLiveNetworking setAllowRequestDefaultArgument:YES];
  31 + [CNLiveNetworking setupShowDataResult:NO];
  32 + [CNLiveNetworking requestNetworkWithMethod:CNLiveRequestMethodPOST URLString:url Param:param CacheType:CNLiveNetworkCacheTypeNetworkOnly CompletionBlock:^(NSURLSessionTask *requestTask, id responseObject, NSError *error) {
  33 + NSLog(@"打印这个responseObjeect%@",responseObject);
  34 + if (responseObject && [responseObject isKindOfClass:[NSDictionary class]]) {
  35 + NSString *errorCode = [NSString stringWithFormat:@"%@",responseObject[@"errorCode"]];
  36 + NSString *errorMessage = responseObject[@"errorMessage"];
  37 + NSString *isHaveNext = @"";
  38 + if ([errorCode isEqualToString:@"0"]) {
  39 + isHaveNext = [NSString stringWithFormat:@"%@",responseObject[@"data"][@"hasNext"]];
  40 + if ([responseObject[@"data"][@"witnessBeans"]isKindOfClass:[NSArray class]] && responseObject[@"data"][@"witnessBeans"]) {
  41 + NSArray *lists = responseObject[@"data"][@"witnessBeans"];
  42 + for (NSDictionary *dic in lists) {
  43 + [array addObject:[CNBWitnessListModel mj_objectWithKeyValues:dic]];
  44 + }
  45 + }
  46 + !successBlock ? :successBlock(array,isHaveNext);
  47 + }else {
  48 + [QMUITips showWithText:errorMessage inView:CNBWitnessAppKeyWindow hideAfterDelay:1.5f];
  49 + }
  50 + }else {
  51 + !failureBlock? :failureBlock(error);
  52 + }
  53 + }];
  54 +}
  55 +@end
... ...
Example/CNLiveWitnessVideoModule.xcodeproj/project.pbxproj 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule.xcodeproj/project.pbxproj
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 46;
  7 + objects = {
  8 +
  9 +/* Begin PBXBuildFile section */
  10 + 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
  11 + 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
  12 + 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
  13 + 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; };
  14 + 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; };
  15 + 6003F59E195388D20070C39A /* CNLIVEAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* CNLIVEAppDelegate.m */; };
  16 + 6003F5A7195388D20070C39A /* CNLIVEViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* CNLIVEViewController.m */; };
  17 + 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; };
  18 + 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };
  19 + 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
  20 + 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
  21 + 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
  22 + 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
  23 + 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; };
  24 + 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
  25 + D6EDFBEF08A459B311850807 /* Pods_CNLiveWitnessVideoModule_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0824F298109D8C2CD0FF626C /* Pods_CNLiveWitnessVideoModule_Tests.framework */; };
  26 + F19BC46DCAC2AFEF8FF45DB7 /* Pods_CNLiveWitnessVideoModule_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F49CA52845E54392EEC3A8E /* Pods_CNLiveWitnessVideoModule_Example.framework */; };
  27 +/* End PBXBuildFile section */
  28 +
  29 +/* Begin PBXContainerItemProxy section */
  30 + 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = {
  31 + isa = PBXContainerItemProxy;
  32 + containerPortal = 6003F582195388D10070C39A /* Project object */;
  33 + proxyType = 1;
  34 + remoteGlobalIDString = 6003F589195388D20070C39A;
  35 + remoteInfo = CNLiveWitnessVideoModule;
  36 + };
  37 +/* End PBXContainerItemProxy section */
  38 +
  39 +/* Begin PBXFileReference section */
  40 + 02F1A649C8BDFE8A35C8C031 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
  41 + 0824F298109D8C2CD0FF626C /* Pods_CNLiveWitnessVideoModule_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveWitnessVideoModule_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  42 + 1D164965CD31C5087617E6CD /* CNLiveWitnessVideoModule.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLiveWitnessVideoModule.podspec; path = ../CNLiveWitnessVideoModule.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
  43 + 4F49CA52845E54392EEC3A8E /* Pods_CNLiveWitnessVideoModule_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveWitnessVideoModule_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  44 + 6003F58A195388D20070C39A /* CNLiveWitnessVideoModule_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveWitnessVideoModule_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
  45 + 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
  46 + 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
  47 + 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
  48 + 6003F595195388D20070C39A /* CNLiveWitnessVideoModule-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CNLiveWitnessVideoModule-Info.plist"; sourceTree = "<group>"; };
  49 + 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
  50 + 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
  51 + 6003F59B195388D20070C39A /* CNLiveWitnessVideoModule-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CNLiveWitnessVideoModule-Prefix.pch"; sourceTree = "<group>"; };
  52 + 6003F59C195388D20070C39A /* CNLIVEAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLIVEAppDelegate.h; sourceTree = "<group>"; };
  53 + 6003F59D195388D20070C39A /* CNLIVEAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLIVEAppDelegate.m; sourceTree = "<group>"; };
  54 + 6003F5A5195388D20070C39A /* CNLIVEViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLIVEViewController.h; sourceTree = "<group>"; };
  55 + 6003F5A6195388D20070C39A /* CNLIVEViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLIVEViewController.m; sourceTree = "<group>"; };
  56 + 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
  57 + 6003F5AE195388D20070C39A /* CNLiveWitnessVideoModule_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CNLiveWitnessVideoModule_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
  58 + 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
  59 + 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; };
  60 + 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
  61 + 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; };
  62 + 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
  63 + 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  64 + 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  65 + 8D78AF0A28AFEC64871E74C3 /* Pods-CNLiveWitnessVideoModule_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveWitnessVideoModule_Example.release.xcconfig"; path = "Target Support Files/Pods-CNLiveWitnessVideoModule_Example/Pods-CNLiveWitnessVideoModule_Example.release.xcconfig"; sourceTree = "<group>"; };
  66 + 949F6950D43D5E4B91225E30 /* Pods-CNLiveWitnessVideoModule_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveWitnessVideoModule_Tests.debug.xcconfig"; path = "Target Support Files/Pods-CNLiveWitnessVideoModule_Tests/Pods-CNLiveWitnessVideoModule_Tests.debug.xcconfig"; sourceTree = "<group>"; };
  67 + 9B02142E70C0198AB081034C /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
  68 + C9FC37C78CD26C3B7A48C085 /* Pods-CNLiveWitnessVideoModule_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveWitnessVideoModule_Tests.release.xcconfig"; path = "Target Support Files/Pods-CNLiveWitnessVideoModule_Tests/Pods-CNLiveWitnessVideoModule_Tests.release.xcconfig"; sourceTree = "<group>"; };
  69 + E800FB63728EF89706426613 /* Pods-CNLiveWitnessVideoModule_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveWitnessVideoModule_Example.debug.xcconfig"; path = "Target Support Files/Pods-CNLiveWitnessVideoModule_Example/Pods-CNLiveWitnessVideoModule_Example.debug.xcconfig"; sourceTree = "<group>"; };
  70 +/* End PBXFileReference section */
  71 +
  72 +/* Begin PBXFrameworksBuildPhase section */
  73 + 6003F587195388D20070C39A /* Frameworks */ = {
  74 + isa = PBXFrameworksBuildPhase;
  75 + buildActionMask = 2147483647;
  76 + files = (
  77 + 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
  78 + 6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
  79 + 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
  80 + F19BC46DCAC2AFEF8FF45DB7 /* Pods_CNLiveWitnessVideoModule_Example.framework in Frameworks */,
  81 + );
  82 + runOnlyForDeploymentPostprocessing = 0;
  83 + };
  84 + 6003F5AB195388D20070C39A /* Frameworks */ = {
  85 + isa = PBXFrameworksBuildPhase;
  86 + buildActionMask = 2147483647;
  87 + files = (
  88 + 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
  89 + 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
  90 + 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
  91 + D6EDFBEF08A459B311850807 /* Pods_CNLiveWitnessVideoModule_Tests.framework in Frameworks */,
  92 + );
  93 + runOnlyForDeploymentPostprocessing = 0;
  94 + };
  95 +/* End PBXFrameworksBuildPhase section */
  96 +
  97 +/* Begin PBXGroup section */
  98 + 5D69ABFE56E1B1FC68128222 /* Pods */ = {
  99 + isa = PBXGroup;
  100 + children = (
  101 + E800FB63728EF89706426613 /* Pods-CNLiveWitnessVideoModule_Example.debug.xcconfig */,
  102 + 8D78AF0A28AFEC64871E74C3 /* Pods-CNLiveWitnessVideoModule_Example.release.xcconfig */,
  103 + 949F6950D43D5E4B91225E30 /* Pods-CNLiveWitnessVideoModule_Tests.debug.xcconfig */,
  104 + C9FC37C78CD26C3B7A48C085 /* Pods-CNLiveWitnessVideoModule_Tests.release.xcconfig */,
  105 + );
  106 + path = Pods;
  107 + sourceTree = "<group>";
  108 + };
  109 + 6003F581195388D10070C39A = {
  110 + isa = PBXGroup;
  111 + children = (
  112 + 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */,
  113 + 6003F593195388D20070C39A /* Example for CNLiveWitnessVideoModule */,
  114 + 6003F5B5195388D20070C39A /* Tests */,
  115 + 6003F58C195388D20070C39A /* Frameworks */,
  116 + 6003F58B195388D20070C39A /* Products */,
  117 + 5D69ABFE56E1B1FC68128222 /* Pods */,
  118 + );
  119 + sourceTree = "<group>";
  120 + };
  121 + 6003F58B195388D20070C39A /* Products */ = {
  122 + isa = PBXGroup;
  123 + children = (
  124 + 6003F58A195388D20070C39A /* CNLiveWitnessVideoModule_Example.app */,
  125 + 6003F5AE195388D20070C39A /* CNLiveWitnessVideoModule_Tests.xctest */,
  126 + );
  127 + name = Products;
  128 + sourceTree = "<group>";
  129 + };
  130 + 6003F58C195388D20070C39A /* Frameworks */ = {
  131 + isa = PBXGroup;
  132 + children = (
  133 + 6003F58D195388D20070C39A /* Foundation.framework */,
  134 + 6003F58F195388D20070C39A /* CoreGraphics.framework */,
  135 + 6003F591195388D20070C39A /* UIKit.framework */,
  136 + 6003F5AF195388D20070C39A /* XCTest.framework */,
  137 + 4F49CA52845E54392EEC3A8E /* Pods_CNLiveWitnessVideoModule_Example.framework */,
  138 + 0824F298109D8C2CD0FF626C /* Pods_CNLiveWitnessVideoModule_Tests.framework */,
  139 + );
  140 + name = Frameworks;
  141 + sourceTree = "<group>";
  142 + };
  143 + 6003F593195388D20070C39A /* Example for CNLiveWitnessVideoModule */ = {
  144 + isa = PBXGroup;
  145 + children = (
  146 + 6003F59C195388D20070C39A /* CNLIVEAppDelegate.h */,
  147 + 6003F59D195388D20070C39A /* CNLIVEAppDelegate.m */,
  148 + 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
  149 + 6003F5A5195388D20070C39A /* CNLIVEViewController.h */,
  150 + 6003F5A6195388D20070C39A /* CNLIVEViewController.m */,
  151 + 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */,
  152 + 6003F5A8195388D20070C39A /* Images.xcassets */,
  153 + 6003F594195388D20070C39A /* Supporting Files */,
  154 + );
  155 + name = "Example for CNLiveWitnessVideoModule";
  156 + path = CNLiveWitnessVideoModule;
  157 + sourceTree = "<group>";
  158 + };
  159 + 6003F594195388D20070C39A /* Supporting Files */ = {
  160 + isa = PBXGroup;
  161 + children = (
  162 + 6003F595195388D20070C39A /* CNLiveWitnessVideoModule-Info.plist */,
  163 + 6003F596195388D20070C39A /* InfoPlist.strings */,
  164 + 6003F599195388D20070C39A /* main.m */,
  165 + 6003F59B195388D20070C39A /* CNLiveWitnessVideoModule-Prefix.pch */,
  166 + );
  167 + name = "Supporting Files";
  168 + sourceTree = "<group>";
  169 + };
  170 + 6003F5B5195388D20070C39A /* Tests */ = {
  171 + isa = PBXGroup;
  172 + children = (
  173 + 6003F5BB195388D20070C39A /* Tests.m */,
  174 + 6003F5B6195388D20070C39A /* Supporting Files */,
  175 + );
  176 + path = Tests;
  177 + sourceTree = "<group>";
  178 + };
  179 + 6003F5B6195388D20070C39A /* Supporting Files */ = {
  180 + isa = PBXGroup;
  181 + children = (
  182 + 6003F5B7195388D20070C39A /* Tests-Info.plist */,
  183 + 6003F5B8195388D20070C39A /* InfoPlist.strings */,
  184 + 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */,
  185 + );
  186 + name = "Supporting Files";
  187 + sourceTree = "<group>";
  188 + };
  189 + 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {
  190 + isa = PBXGroup;
  191 + children = (
  192 + 1D164965CD31C5087617E6CD /* CNLiveWitnessVideoModule.podspec */,
  193 + 9B02142E70C0198AB081034C /* README.md */,
  194 + 02F1A649C8BDFE8A35C8C031 /* LICENSE */,
  195 + );
  196 + name = "Podspec Metadata";
  197 + sourceTree = "<group>";
  198 + };
  199 +/* End PBXGroup section */
  200 +
  201 +/* Begin PBXNativeTarget section */
  202 + 6003F589195388D20070C39A /* CNLiveWitnessVideoModule_Example */ = {
  203 + isa = PBXNativeTarget;
  204 + buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveWitnessVideoModule_Example" */;
  205 + buildPhases = (
  206 + 4F88F72B4508E693CF9FE3DD /* [CP] Check Pods Manifest.lock */,
  207 + 6003F586195388D20070C39A /* Sources */,
  208 + 6003F587195388D20070C39A /* Frameworks */,
  209 + 6003F588195388D20070C39A /* Resources */,
  210 + 7DBC28A442E3D79AF6D6849E /* [CP] Embed Pods Frameworks */,
  211 + );
  212 + buildRules = (
  213 + );
  214 + dependencies = (
  215 + );
  216 + name = CNLiveWitnessVideoModule_Example;
  217 + productName = CNLiveWitnessVideoModule;
  218 + productReference = 6003F58A195388D20070C39A /* CNLiveWitnessVideoModule_Example.app */;
  219 + productType = "com.apple.product-type.application";
  220 + };
  221 + 6003F5AD195388D20070C39A /* CNLiveWitnessVideoModule_Tests */ = {
  222 + isa = PBXNativeTarget;
  223 + buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveWitnessVideoModule_Tests" */;
  224 + buildPhases = (
  225 + 09EC029E54A94E8D3B439ABD /* [CP] Check Pods Manifest.lock */,
  226 + 6003F5AA195388D20070C39A /* Sources */,
  227 + 6003F5AB195388D20070C39A /* Frameworks */,
  228 + 6003F5AC195388D20070C39A /* Resources */,
  229 + );
  230 + buildRules = (
  231 + );
  232 + dependencies = (
  233 + 6003F5B4195388D20070C39A /* PBXTargetDependency */,
  234 + );
  235 + name = CNLiveWitnessVideoModule_Tests;
  236 + productName = CNLiveWitnessVideoModuleTests;
  237 + productReference = 6003F5AE195388D20070C39A /* CNLiveWitnessVideoModule_Tests.xctest */;
  238 + productType = "com.apple.product-type.bundle.unit-test";
  239 + };
  240 +/* End PBXNativeTarget section */
  241 +
  242 +/* Begin PBXProject section */
  243 + 6003F582195388D10070C39A /* Project object */ = {
  244 + isa = PBXProject;
  245 + attributes = {
  246 + CLASSPREFIX = CNLIVE;
  247 + LastUpgradeCheck = 0720;
  248 + ORGANIZATIONNAME = dawanzi;
  249 + TargetAttributes = {
  250 + 6003F589195388D20070C39A = {
  251 + DevelopmentTeam = 94X49GG3ZW;
  252 + };
  253 + 6003F5AD195388D20070C39A = {
  254 + TestTargetID = 6003F589195388D20070C39A;
  255 + };
  256 + };
  257 + };
  258 + buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "CNLiveWitnessVideoModule" */;
  259 + compatibilityVersion = "Xcode 3.2";
  260 + developmentRegion = English;
  261 + hasScannedForEncodings = 0;
  262 + knownRegions = (
  263 + English,
  264 + en,
  265 + Base,
  266 + );
  267 + mainGroup = 6003F581195388D10070C39A;
  268 + productRefGroup = 6003F58B195388D20070C39A /* Products */;
  269 + projectDirPath = "";
  270 + projectRoot = "";
  271 + targets = (
  272 + 6003F589195388D20070C39A /* CNLiveWitnessVideoModule_Example */,
  273 + 6003F5AD195388D20070C39A /* CNLiveWitnessVideoModule_Tests */,
  274 + );
  275 + };
  276 +/* End PBXProject section */
  277 +
  278 +/* Begin PBXResourcesBuildPhase section */
  279 + 6003F588195388D20070C39A /* Resources */ = {
  280 + isa = PBXResourcesBuildPhase;
  281 + buildActionMask = 2147483647;
  282 + files = (
  283 + 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,
  284 + 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */,
  285 + 6003F5A9195388D20070C39A /* Images.xcassets in Resources */,
  286 + 6003F598195388D20070C39A /* InfoPlist.strings in Resources */,
  287 + );
  288 + runOnlyForDeploymentPostprocessing = 0;
  289 + };
  290 + 6003F5AC195388D20070C39A /* Resources */ = {
  291 + isa = PBXResourcesBuildPhase;
  292 + buildActionMask = 2147483647;
  293 + files = (
  294 + 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */,
  295 + );
  296 + runOnlyForDeploymentPostprocessing = 0;
  297 + };
  298 +/* End PBXResourcesBuildPhase section */
  299 +
  300 +/* Begin PBXShellScriptBuildPhase section */
  301 + 09EC029E54A94E8D3B439ABD /* [CP] Check Pods Manifest.lock */ = {
  302 + isa = PBXShellScriptBuildPhase;
  303 + buildActionMask = 2147483647;
  304 + files = (
  305 + );
  306 + inputFileListPaths = (
  307 + );
  308 + inputPaths = (
  309 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  310 + "${PODS_ROOT}/Manifest.lock",
  311 + );
  312 + name = "[CP] Check Pods Manifest.lock";
  313 + outputFileListPaths = (
  314 + );
  315 + outputPaths = (
  316 + "$(DERIVED_FILE_DIR)/Pods-CNLiveWitnessVideoModule_Tests-checkManifestLockResult.txt",
  317 + );
  318 + runOnlyForDeploymentPostprocessing = 0;
  319 + shellPath = /bin/sh;
  320 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
  321 + showEnvVarsInLog = 0;
  322 + };
  323 + 4F88F72B4508E693CF9FE3DD /* [CP] Check Pods Manifest.lock */ = {
  324 + isa = PBXShellScriptBuildPhase;
  325 + buildActionMask = 2147483647;
  326 + files = (
  327 + );
  328 + inputFileListPaths = (
  329 + );
  330 + inputPaths = (
  331 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  332 + "${PODS_ROOT}/Manifest.lock",
  333 + );
  334 + name = "[CP] Check Pods Manifest.lock";
  335 + outputFileListPaths = (
  336 + );
  337 + outputPaths = (
  338 + "$(DERIVED_FILE_DIR)/Pods-CNLiveWitnessVideoModule_Example-checkManifestLockResult.txt",
  339 + );
  340 + runOnlyForDeploymentPostprocessing = 0;
  341 + shellPath = /bin/sh;
  342 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
  343 + showEnvVarsInLog = 0;
  344 + };
  345 + 7DBC28A442E3D79AF6D6849E /* [CP] Embed Pods Frameworks */ = {
  346 + isa = PBXShellScriptBuildPhase;
  347 + buildActionMask = 2147483647;
  348 + files = (
  349 + );
  350 + inputPaths = (
  351 + "${PODS_ROOT}/Target Support Files/Pods-CNLiveWitnessVideoModule_Example/Pods-CNLiveWitnessVideoModule_Example-frameworks.sh",
  352 + "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
  353 + "${BUILT_PRODUCTS_DIR}/CNLiveBaseKit/CNLiveBaseKit.framework",
  354 + "${BUILT_PRODUCTS_DIR}/CNLiveBeeHive/CNLiveBeeHive.framework",
  355 + "${BUILT_PRODUCTS_DIR}/CNLiveBusinessTools/CNLiveBusinessTools.framework",
  356 + "${BUILT_PRODUCTS_DIR}/CNLiveCommonCategory/CNLiveCommonCategory.framework",
  357 + "${BUILT_PRODUCTS_DIR}/CNLiveCustomUI/CNLiveCustomUI.framework",
  358 + "${BUILT_PRODUCTS_DIR}/CNLiveEnvironment/CNLiveEnvironment.framework",
  359 + "${BUILT_PRODUCTS_DIR}/CNLiveRequestBastKit/CNLiveRequestBastKit.framework",
  360 + "${BUILT_PRODUCTS_DIR}/CNLiveTripartiteManagement/CNLiveTripartiteManagement.framework",
  361 + "${BUILT_PRODUCTS_DIR}/CNLiveUserManagement/CNLiveUserManagement.framework",
  362 + "${BUILT_PRODUCTS_DIR}/CNLiveWitnessVideoModule/CNLiveWitnessVideoModule.framework",
  363 + "${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework",
  364 + "${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework",
  365 + "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework",
  366 + "${BUILT_PRODUCTS_DIR}/QMUIKit/QMUIKit.framework",
  367 + "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
  368 + "${BUILT_PRODUCTS_DIR}/YYKit/YYKit.framework",
  369 + );
  370 + name = "[CP] Embed Pods Frameworks";
  371 + outputPaths = (
  372 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
  373 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBaseKit.framework",
  374 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBeeHive.framework",
  375 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBusinessTools.framework",
  376 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveCommonCategory.framework",
  377 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveCustomUI.framework",
  378 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveEnvironment.framework",
  379 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveRequestBastKit.framework",
  380 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveTripartiteManagement.framework",
  381 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveUserManagement.framework",
  382 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveWitnessVideoModule.framework",
  383 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJExtension.framework",
  384 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework",
  385 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework",
  386 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QMUIKit.framework",
  387 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
  388 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYKit.framework",
  389 + );
  390 + runOnlyForDeploymentPostprocessing = 0;
  391 + shellPath = /bin/sh;
  392 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CNLiveWitnessVideoModule_Example/Pods-CNLiveWitnessVideoModule_Example-frameworks.sh\"\n";
  393 + showEnvVarsInLog = 0;
  394 + };
  395 +/* End PBXShellScriptBuildPhase section */
  396 +
  397 +/* Begin PBXSourcesBuildPhase section */
  398 + 6003F586195388D20070C39A /* Sources */ = {
  399 + isa = PBXSourcesBuildPhase;
  400 + buildActionMask = 2147483647;
  401 + files = (
  402 + 6003F59E195388D20070C39A /* CNLIVEAppDelegate.m in Sources */,
  403 + 6003F5A7195388D20070C39A /* CNLIVEViewController.m in Sources */,
  404 + 6003F59A195388D20070C39A /* main.m in Sources */,
  405 + );
  406 + runOnlyForDeploymentPostprocessing = 0;
  407 + };
  408 + 6003F5AA195388D20070C39A /* Sources */ = {
  409 + isa = PBXSourcesBuildPhase;
  410 + buildActionMask = 2147483647;
  411 + files = (
  412 + 6003F5BC195388D20070C39A /* Tests.m in Sources */,
  413 + );
  414 + runOnlyForDeploymentPostprocessing = 0;
  415 + };
  416 +/* End PBXSourcesBuildPhase section */
  417 +
  418 +/* Begin PBXTargetDependency section */
  419 + 6003F5B4195388D20070C39A /* PBXTargetDependency */ = {
  420 + isa = PBXTargetDependency;
  421 + target = 6003F589195388D20070C39A /* CNLiveWitnessVideoModule_Example */;
  422 + targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */;
  423 + };
  424 +/* End PBXTargetDependency section */
  425 +
  426 +/* Begin PBXVariantGroup section */
  427 + 6003F596195388D20070C39A /* InfoPlist.strings */ = {
  428 + isa = PBXVariantGroup;
  429 + children = (
  430 + 6003F597195388D20070C39A /* en */,
  431 + );
  432 + name = InfoPlist.strings;
  433 + sourceTree = "<group>";
  434 + };
  435 + 6003F5B8195388D20070C39A /* InfoPlist.strings */ = {
  436 + isa = PBXVariantGroup;
  437 + children = (
  438 + 6003F5B9195388D20070C39A /* en */,
  439 + );
  440 + name = InfoPlist.strings;
  441 + sourceTree = "<group>";
  442 + };
  443 + 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */ = {
  444 + isa = PBXVariantGroup;
  445 + children = (
  446 + 71719F9E1E33DC2100824A3D /* Base */,
  447 + );
  448 + name = LaunchScreen.storyboard;
  449 + sourceTree = "<group>";
  450 + };
  451 +/* End PBXVariantGroup section */
  452 +
  453 +/* Begin XCBuildConfiguration section */
  454 + 6003F5BD195388D20070C39A /* Debug */ = {
  455 + isa = XCBuildConfiguration;
  456 + buildSettings = {
  457 + ALWAYS_SEARCH_USER_PATHS = NO;
  458 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  459 + CLANG_CXX_LIBRARY = "libc++";
  460 + CLANG_ENABLE_MODULES = YES;
  461 + CLANG_ENABLE_OBJC_ARC = YES;
  462 + CLANG_WARN_BOOL_CONVERSION = YES;
  463 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  464 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  465 + CLANG_WARN_EMPTY_BODY = YES;
  466 + CLANG_WARN_ENUM_CONVERSION = YES;
  467 + CLANG_WARN_INT_CONVERSION = YES;
  468 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  469 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  470 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  471 + COPY_PHASE_STRIP = NO;
  472 + ENABLE_TESTABILITY = YES;
  473 + GCC_C_LANGUAGE_STANDARD = gnu99;
  474 + GCC_DYNAMIC_NO_PIC = NO;
  475 + GCC_OPTIMIZATION_LEVEL = 0;
  476 + GCC_PREPROCESSOR_DEFINITIONS = (
  477 + "DEBUG=1",
  478 + "$(inherited)",
  479 + );
  480 + GCC_SYMBOLS_PRIVATE_EXTERN = NO;
  481 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  482 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  483 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  484 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  485 + GCC_WARN_UNUSED_FUNCTION = YES;
  486 + GCC_WARN_UNUSED_VARIABLE = YES;
  487 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  488 + ONLY_ACTIVE_ARCH = YES;
  489 + SDKROOT = iphoneos;
  490 + TARGETED_DEVICE_FAMILY = "1,2";
  491 + };
  492 + name = Debug;
  493 + };
  494 + 6003F5BE195388D20070C39A /* Release */ = {
  495 + isa = XCBuildConfiguration;
  496 + buildSettings = {
  497 + ALWAYS_SEARCH_USER_PATHS = NO;
  498 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  499 + CLANG_CXX_LIBRARY = "libc++";
  500 + CLANG_ENABLE_MODULES = YES;
  501 + CLANG_ENABLE_OBJC_ARC = YES;
  502 + CLANG_WARN_BOOL_CONVERSION = YES;
  503 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  504 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  505 + CLANG_WARN_EMPTY_BODY = YES;
  506 + CLANG_WARN_ENUM_CONVERSION = YES;
  507 + CLANG_WARN_INT_CONVERSION = YES;
  508 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  509 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  510 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  511 + COPY_PHASE_STRIP = YES;
  512 + ENABLE_NS_ASSERTIONS = NO;
  513 + GCC_C_LANGUAGE_STANDARD = gnu99;
  514 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  515 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  516 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  517 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  518 + GCC_WARN_UNUSED_FUNCTION = YES;
  519 + GCC_WARN_UNUSED_VARIABLE = YES;
  520 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  521 + SDKROOT = iphoneos;
  522 + TARGETED_DEVICE_FAMILY = "1,2";
  523 + VALIDATE_PRODUCT = YES;
  524 + };
  525 + name = Release;
  526 + };
  527 + 6003F5C0195388D20070C39A /* Debug */ = {
  528 + isa = XCBuildConfiguration;
  529 + baseConfigurationReference = E800FB63728EF89706426613 /* Pods-CNLiveWitnessVideoModule_Example.debug.xcconfig */;
  530 + buildSettings = {
  531 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  532 + DEVELOPMENT_TEAM = 94X49GG3ZW;
  533 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  534 + GCC_PREFIX_HEADER = "CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Prefix.pch";
  535 + INFOPLIST_FILE = "CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Info.plist";
  536 + MODULE_NAME = ExampleApp;
  537 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  538 + PRODUCT_NAME = "$(TARGET_NAME)";
  539 + SWIFT_VERSION = 4.0;
  540 + WRAPPER_EXTENSION = app;
  541 + };
  542 + name = Debug;
  543 + };
  544 + 6003F5C1195388D20070C39A /* Release */ = {
  545 + isa = XCBuildConfiguration;
  546 + baseConfigurationReference = 8D78AF0A28AFEC64871E74C3 /* Pods-CNLiveWitnessVideoModule_Example.release.xcconfig */;
  547 + buildSettings = {
  548 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  549 + DEVELOPMENT_TEAM = 94X49GG3ZW;
  550 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  551 + GCC_PREFIX_HEADER = "CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Prefix.pch";
  552 + INFOPLIST_FILE = "CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Info.plist";
  553 + MODULE_NAME = ExampleApp;
  554 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  555 + PRODUCT_NAME = "$(TARGET_NAME)";
  556 + SWIFT_VERSION = 4.0;
  557 + WRAPPER_EXTENSION = app;
  558 + };
  559 + name = Release;
  560 + };
  561 + 6003F5C3195388D20070C39A /* Debug */ = {
  562 + isa = XCBuildConfiguration;
  563 + baseConfigurationReference = 949F6950D43D5E4B91225E30 /* Pods-CNLiveWitnessVideoModule_Tests.debug.xcconfig */;
  564 + buildSettings = {
  565 + BUNDLE_LOADER = "$(TEST_HOST)";
  566 + FRAMEWORK_SEARCH_PATHS = (
  567 + "$(PLATFORM_DIR)/Developer/Library/Frameworks",
  568 + "$(inherited)",
  569 + "$(DEVELOPER_FRAMEWORKS_DIR)",
  570 + );
  571 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  572 + GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
  573 + GCC_PREPROCESSOR_DEFINITIONS = (
  574 + "DEBUG=1",
  575 + "$(inherited)",
  576 + );
  577 + INFOPLIST_FILE = "Tests/Tests-Info.plist";
  578 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  579 + PRODUCT_NAME = "$(TARGET_NAME)";
  580 + SWIFT_VERSION = 4.0;
  581 + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CNLiveWitnessVideoModule_Example.app/CNLiveWitnessVideoModule_Example";
  582 + WRAPPER_EXTENSION = xctest;
  583 + };
  584 + name = Debug;
  585 + };
  586 + 6003F5C4195388D20070C39A /* Release */ = {
  587 + isa = XCBuildConfiguration;
  588 + baseConfigurationReference = C9FC37C78CD26C3B7A48C085 /* Pods-CNLiveWitnessVideoModule_Tests.release.xcconfig */;
  589 + buildSettings = {
  590 + BUNDLE_LOADER = "$(TEST_HOST)";
  591 + FRAMEWORK_SEARCH_PATHS = (
  592 + "$(PLATFORM_DIR)/Developer/Library/Frameworks",
  593 + "$(inherited)",
  594 + "$(DEVELOPER_FRAMEWORKS_DIR)",
  595 + );
  596 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  597 + GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
  598 + INFOPLIST_FILE = "Tests/Tests-Info.plist";
  599 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  600 + PRODUCT_NAME = "$(TARGET_NAME)";
  601 + SWIFT_VERSION = 4.0;
  602 + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CNLiveWitnessVideoModule_Example.app/CNLiveWitnessVideoModule_Example";
  603 + WRAPPER_EXTENSION = xctest;
  604 + };
  605 + name = Release;
  606 + };
  607 +/* End XCBuildConfiguration section */
  608 +
  609 +/* Begin XCConfigurationList section */
  610 + 6003F585195388D10070C39A /* Build configuration list for PBXProject "CNLiveWitnessVideoModule" */ = {
  611 + isa = XCConfigurationList;
  612 + buildConfigurations = (
  613 + 6003F5BD195388D20070C39A /* Debug */,
  614 + 6003F5BE195388D20070C39A /* Release */,
  615 + );
  616 + defaultConfigurationIsVisible = 0;
  617 + defaultConfigurationName = Release;
  618 + };
  619 + 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveWitnessVideoModule_Example" */ = {
  620 + isa = XCConfigurationList;
  621 + buildConfigurations = (
  622 + 6003F5C0195388D20070C39A /* Debug */,
  623 + 6003F5C1195388D20070C39A /* Release */,
  624 + );
  625 + defaultConfigurationIsVisible = 0;
  626 + defaultConfigurationName = Release;
  627 + };
  628 + 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveWitnessVideoModule_Tests" */ = {
  629 + isa = XCConfigurationList;
  630 + buildConfigurations = (
  631 + 6003F5C3195388D20070C39A /* Debug */,
  632 + 6003F5C4195388D20070C39A /* Release */,
  633 + );
  634 + defaultConfigurationIsVisible = 0;
  635 + defaultConfigurationName = Release;
  636 + };
  637 +/* End XCConfigurationList section */
  638 + };
  639 + rootObject = 6003F582195388D10070C39A /* Project object */;
  640 +}
... ...
Example/CNLiveWitnessVideoModule.xcodeproj/xcshareddata/xcschemes/CNLiveWitnessVideoModule-Example.xcscheme 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule.xcodeproj/xcshareddata/xcschemes/CNLiveWitnessVideoModule-Example.xcscheme
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "0720"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "6003F589195388D20070C39A"
  18 + BuildableName = "CNLiveWitnessVideoModule_Example.app"
  19 + BlueprintName = "CNLiveWitnessVideoModule_Example"
  20 + ReferencedContainer = "container:CNLiveWitnessVideoModule.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <Testables>
  31 + <TestableReference
  32 + skipped = "NO">
  33 + <BuildableReference
  34 + BuildableIdentifier = "primary"
  35 + BlueprintIdentifier = "6003F5AD195388D20070C39A"
  36 + BuildableName = "CNLiveWitnessVideoModule_Tests.xctest"
  37 + BlueprintName = "CNLiveWitnessVideoModule_Tests"
  38 + ReferencedContainer = "container:CNLiveWitnessVideoModule.xcodeproj">
  39 + </BuildableReference>
  40 + </TestableReference>
  41 + </Testables>
  42 + <MacroExpansion>
  43 + <BuildableReference
  44 + BuildableIdentifier = "primary"
  45 + BlueprintIdentifier = "6003F589195388D20070C39A"
  46 + BuildableName = "CNLiveWitnessVideoModule_Example.app"
  47 + BlueprintName = "CNLiveWitnessVideoModule_Example"
  48 + ReferencedContainer = "container:CNLiveWitnessVideoModule.xcodeproj">
  49 + </BuildableReference>
  50 + </MacroExpansion>
  51 + <AdditionalOptions>
  52 + </AdditionalOptions>
  53 + </TestAction>
  54 + <LaunchAction
  55 + buildConfiguration = "Debug"
  56 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  57 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  58 + launchStyle = "0"
  59 + useCustomWorkingDirectory = "NO"
  60 + ignoresPersistentStateOnLaunch = "NO"
  61 + debugDocumentVersioning = "YES"
  62 + debugServiceExtension = "internal"
  63 + allowLocationSimulation = "YES">
  64 + <BuildableProductRunnable
  65 + runnableDebuggingMode = "0">
  66 + <BuildableReference
  67 + BuildableIdentifier = "primary"
  68 + BlueprintIdentifier = "6003F589195388D20070C39A"
  69 + BuildableName = "CNLiveWitnessVideoModule_Example.app"
  70 + BlueprintName = "CNLiveWitnessVideoModule_Example"
  71 + ReferencedContainer = "container:CNLiveWitnessVideoModule.xcodeproj">
  72 + </BuildableReference>
  73 + </BuildableProductRunnable>
  74 + <AdditionalOptions>
  75 + </AdditionalOptions>
  76 + </LaunchAction>
  77 + <ProfileAction
  78 + buildConfiguration = "Release"
  79 + shouldUseLaunchSchemeArgsEnv = "YES"
  80 + savedToolIdentifier = ""
  81 + useCustomWorkingDirectory = "NO"
  82 + debugDocumentVersioning = "YES">
  83 + <BuildableProductRunnable
  84 + runnableDebuggingMode = "0">
  85 + <BuildableReference
  86 + BuildableIdentifier = "primary"
  87 + BlueprintIdentifier = "6003F589195388D20070C39A"
  88 + BuildableName = "CNLiveWitnessVideoModule_Example.app"
  89 + BlueprintName = "CNLiveWitnessVideoModule_Example"
  90 + ReferencedContainer = "container:CNLiveWitnessVideoModule.xcodeproj">
  91 + </BuildableReference>
  92 + </BuildableProductRunnable>
  93 + </ProfileAction>
  94 + <AnalyzeAction
  95 + buildConfiguration = "Debug">
  96 + </AnalyzeAction>
  97 + <ArchiveAction
  98 + buildConfiguration = "Release"
  99 + revealArchiveInOrganizer = "YES">
  100 + </ArchiveAction>
  101 +</Scheme>
... ...
Example/CNLiveWitnessVideoModule/Base.lproj/LaunchScreen.storyboard 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/Base.lproj/LaunchScreen.storyboard
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
  3 + <device id="retina4_7" orientation="portrait">
  4 + <adaptation id="fullscreen"/>
  5 + </device>
  6 + <dependencies>
  7 + <deployment identifier="iOS"/>
  8 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
  9 + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
  10 + </dependencies>
  11 + <scenes>
  12 + <!--View Controller-->
  13 + <scene sceneID="EHf-IW-A2E">
  14 + <objects>
  15 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  16 + <layoutGuides>
  17 + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
  18 + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
  19 + </layoutGuides>
  20 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  21 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  22 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  23 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  24 + </view>
  25 + </viewController>
  26 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  27 + </objects>
  28 + <point key="canvasLocation" x="53" y="375"/>
  29 + </scene>
  30 + </scenes>
  31 +</document>
... ...
Example/CNLiveWitnessVideoModule/Base.lproj/Main.storyboard 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/Base.lproj/Main.storyboard
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="whP-gf-Uak">
  3 + <device id="retina4_7" orientation="portrait">
  4 + <adaptation id="fullscreen"/>
  5 + </device>
  6 + <dependencies>
  7 + <deployment identifier="iOS"/>
  8 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
  9 + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
  10 + </dependencies>
  11 + <scenes>
  12 + <!--View Controller-->
  13 + <scene sceneID="wQg-tq-qST">
  14 + <objects>
  15 + <viewController id="whP-gf-Uak" customClass="CNLIVEViewController" sceneMemberID="viewController">
  16 + <layoutGuides>
  17 + <viewControllerLayoutGuide type="top" id="uEw-UM-LJ8"/>
  18 + <viewControllerLayoutGuide type="bottom" id="Mvr-aV-6Um"/>
  19 + </layoutGuides>
  20 + <view key="view" contentMode="scaleToFill" id="TpU-gO-2f1">
  21 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  22 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  23 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  24 + </view>
  25 + </viewController>
  26 + <placeholder placeholderIdentifier="IBFirstResponder" id="tc2-Qw-aMS" userLabel="First Responder" sceneMemberID="firstResponder"/>
  27 + </objects>
  28 + <point key="canvasLocation" x="305" y="433"/>
  29 + </scene>
  30 + </scenes>
  31 +</document>
... ...
Example/CNLiveWitnessVideoModule/CNLIVEAppDelegate.h 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/CNLIVEAppDelegate.h
  1 +//
  2 +// CNLIVEAppDelegate.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by dawanzi on 04/03/2020.
  6 +// Copyright (c) 2020 dawanzi. All rights reserved.
  7 +//
  8 +
  9 +@import UIKit;
  10 +
  11 +@interface CNLIVEAppDelegate : UIResponder <UIApplicationDelegate>
  12 +
  13 +@property (strong, nonatomic) UIWindow *window;
  14 +
  15 +@end
... ...
Example/CNLiveWitnessVideoModule/CNLIVEAppDelegate.m 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/CNLIVEAppDelegate.m
  1 +//
  2 +// CNLIVEAppDelegate.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by dawanzi on 04/03/2020.
  6 +// Copyright (c) 2020 dawanzi. All rights reserved.
  7 +//
  8 +
  9 +#import "CNLIVEAppDelegate.h"
  10 +#import "CNLiveEnvironment.h"
  11 +#import "CNLiveNetworking.h"
  12 +#import "CNLIVEViewController.h"
  13 +static NSString * uuid;
  14 +@implementation CNLIVEAppDelegate
  15 +
  16 +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  17 +{
  18 + // Override point for customization after application launch.
  19 + self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
  20 + self.window.backgroundColor = [UIColor whiteColor];
  21 + CNLIVEViewController *vc = [[CNLIVEViewController alloc]init];
  22 + UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
  23 + self.window.rootViewController = nav;
  24 + [self.window makeKeyAndVisible];
  25 + [self networkParamAction];
  26 + return YES;
  27 +}
  28 +- (void)networkParamAction {
  29 + NSMutableDictionary * mDict = [[NSMutableDictionary alloc] init];
  30 + [mDict setValue:@"10511059" forKey:@"loginSid"];
  31 + [mDict setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"] forKey:@"platform_id"];
  32 + [mDict setValue:[self appUUIDString] forKey:@"uuid"];
  33 + [mDict setValue:@"i" forKey:@"plat"];
  34 + [mDict setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] forKey:@"ver"];
  35 + [mDict setObject:AppId forKey:@"appId"];
  36 + [CNLiveNetworking setupDefaultParam:mDict];
  37 + [CNLiveNetworking setupShowResult:NO];
  38 + [CNLiveNetworking setupSignKey:APPKey];
  39 + NSLog(@"打印appkey%@",APPKey);
  40 + [CNLiveNetworking setAllowRequestDefaultArgument:YES];
  41 + [CNLiveNetworking setResponseSerializerType:CNLiveResponseSerializerJSON];
  42 +
  43 +}
  44 +- (NSString *)appUUIDString
  45 +{
  46 + static dispatch_once_t onceToken;
  47 + dispatch_once(&onceToken, ^{
  48 + uuid = [[[[UIDevice currentDevice] identifierForVendor] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""];
  49 + });
  50 + return uuid;
  51 +}
  52 +
  53 +
  54 +- (void)applicationWillResignActive:(UIApplication *)application
  55 +{
  56 + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  57 + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
  58 +}
  59 +
  60 +- (void)applicationDidEnterBackground:(UIApplication *)application
  61 +{
  62 + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  63 + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  64 +}
  65 +
  66 +- (void)applicationWillEnterForeground:(UIApplication *)application
  67 +{
  68 + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
  69 +}
  70 +
  71 +- (void)applicationDidBecomeActive:(UIApplication *)application
  72 +{
  73 + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  74 +}
  75 +
  76 +- (void)applicationWillTerminate:(UIApplication *)application
  77 +{
  78 + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  79 +}
  80 +
  81 +@end
... ...
Example/CNLiveWitnessVideoModule/CNLIVEViewController.h 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/CNLIVEViewController.h
  1 +//
  2 +// CNLIVEViewController.h
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by dawanzi on 04/03/2020.
  6 +// Copyright (c) 2020 dawanzi. All rights reserved.
  7 +//
  8 +
  9 +@import UIKit;
  10 +
  11 +@interface CNLIVEViewController : UIViewController
  12 +
  13 +@end
... ...
Example/CNLiveWitnessVideoModule/CNLIVEViewController.m 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/CNLIVEViewController.m
  1 +//
  2 +// CNLIVEViewController.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by dawanzi on 04/03/2020.
  6 +// Copyright (c) 2020 dawanzi. All rights reserved.
  7 +//
  8 +
  9 +#import "CNLIVEViewController.h"
  10 +#import "CNLiveEnvironment.h"
  11 +#import "CNLiveNetworking.h"
  12 +#import "NSString+CNLiveExtension.h"
  13 +#import "CNLiveBaseKit.h"
  14 +#import "CNBWitnessListModel.h"
  15 +#import "MJExtension.h"
  16 +#import "CNBWitnessListController.h"
  17 +#import "CNBWitnessVideoPlayProtocol.h"
  18 +#import <CNLiveBeeHive/BeeHive.h>
  19 +@interface CNLIVEViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
  20 +@property (nonatomic, strong) NSDictionary *data;
  21 +@property(nonatomic, copy) NSString *type;
  22 +@property (nonatomic, strong) UICollectionView *collectionView;
  23 +@property (nonatomic, strong) NSMutableArray *dataSource;
  24 +
  25 +@end
  26 +
  27 +@implementation CNLIVEViewController
  28 +
  29 +- (void)viewDidLoad
  30 +{
  31 + [super viewDidLoad];
  32 + [self setUPCollectionView];
  33 + [self getWitnessListDataTosid:@"10511059" page:1 pageSize:10 type:@"0"];
  34 + self.dataSource = [NSMutableArray array];
  35 +}
  36 +- (void)setUPCollectionView {
  37 + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
  38 + CGFloat itemWidth = (KScreenWidth - 40) / 3;
  39 +
  40 + //设置单元格大小
  41 + layout.itemSize = CGSizeMake(itemWidth, itemWidth);
  42 + //最小行间距(默认为10)
  43 + layout.minimumLineSpacing = 10;
  44 + //最小item间距(默认为10)
  45 + layout.minimumInteritemSpacing = 10;
  46 + //设置UICollectionView的滑动方向
  47 + layout.scrollDirection = UICollectionViewScrollDirectionVertical;
  48 + //设置UICollectionView的间距
  49 + layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
  50 +
  51 + _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 40, KScreenWidth, KScreenHeight) collectionViewLayout:layout];
  52 + [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
  53 + //遵循CollectionView的代理方法
  54 + _collectionView.delegate = self;
  55 + _collectionView.dataSource = self;
  56 +
  57 + _collectionView.backgroundColor = [UIColor clearColor];
  58 + //注册cell
  59 + [self.view addSubview:self.collectionView];
  60 +}
  61 +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  62 + return self.dataSource.count;
  63 +}
  64 +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  65 + UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
  66 + if (!cell) {
  67 + cell = [[UICollectionViewCell alloc]init];
  68 + }
  69 + cell.backgroundColor = [UIColor cyanColor];
  70 + return cell;
  71 +}
  72 +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  73 + CNBWitnessListModel *model = self.dataSource[indexPath.row];
  74 +// CNBWitnessListController *vc = [[CNBWitnessListController alloc]initControllerWithData:self.data currentIndex:indexPath.row pageNum:1 type:@"0"];
  75 +// [self.navigationController pushViewController:vc animated:YES];
  76 + id <CNBWitnessVideoPlayProtocol>service = [[BeeHive shareInstance]createService:@protocol(CNBWitnessVideoPlayProtocol)];
  77 + [service pushToWitnessVideoController:self.data currentIndex:indexPath.row pageNum:1 type:@"1"];
  78 +}
  79 +- (void)getWitnessListDataTosid:(NSString *)toSid page:(NSInteger)page pageSize:(NSInteger)pageSize type:(NSString *)type {
  80 + NSString *url = @"";
  81 + NSDictionary *param = [NSDictionary dictionary];
  82 + if ([type isEqualToString:@"0"]) { //0 作品跳进来
  83 + param = @{
  84 + @"toSid" :CNLiveStringIsEmpty(toSid)? @"":toSid,
  85 + @"pageNo" :[NSString stringWithFormat:@"%ld",page],
  86 + @"pageSize" :[NSString stringWithFormat:@"%ld",pageSize]
  87 + };
  88 + url = cn_API_Host(@"/Daren/bWitness/getBWitnessList.action");
  89 +
  90 + }else if ([type isEqualToString:@"1"]) { //1 动态跳进来的
  91 + param = @{
  92 + @"toSid":CNLiveStringIsEmpty(toSid)? @"":toSid,
  93 + @"pageNo" :[NSString stringWithFormat:@"%ld",page],
  94 + @"pageSize" :[NSString stringWithFormat:@"%ld",pageSize]
  95 + };
  96 + url = CNGetWitnessCollectionListContent;
  97 + }
  98 + __weak typeof(self) weakSelf = self;
  99 + [CNLiveNetworking setAllowRequestDefaultArgument:YES];
  100 + [CNLiveNetworking setupShowDataResult:NO];
  101 + [CNLiveNetworking requestNetworkWithMethod:CNLiveRequestMethodPOST URLString:url Param:param CacheType:CNLiveNetworkCacheTypeNetworkOnly CompletionBlock:^(NSURLSessionTask *requestTask, id responseObject, NSError *error) {
  102 + NSLog(@"打印这个responseObjeect%@",responseObject);
  103 + if (responseObject && [responseObject isKindOfClass:[NSDictionary class]]) {
  104 + NSString *errorCode = [NSString stringWithFormat:@"%@",responseObject[@"errorCode"]];
  105 + if ([errorCode isEqualToString:@"0"]) {
  106 + NSDictionary *data = responseObject[@"data"];
  107 + weakSelf.data = data;
  108 + if ([responseObject[@"data"][@"witnessBeans"]isKindOfClass:[NSArray class]] && responseObject[@"data"][@"witnessBeans"]) {
  109 + NSArray *lists = responseObject[@"data"][@"witnessBeans"];
  110 + for (NSDictionary *dic in lists) {
  111 + [self.dataSource addObject:[CNBWitnessListModel mj_objectWithKeyValues:dic]];
  112 + }
  113 + }
  114 + [self.collectionView reloadData];
  115 + }
  116 + }
  117 + }];
  118 +}
  119 +- (void)didReceiveMemoryWarning
  120 +{
  121 + [super didReceiveMemoryWarning];
  122 + // Dispose of any resources that can be recreated.
  123 +}
  124 +
  125 +@end
... ...
Example/CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Info.plist 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Info.plist
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>en</string>
  7 + <key>CFBundleDisplayName</key>
  8 + <string>${PRODUCT_NAME}</string>
  9 + <key>CFBundleExecutable</key>
  10 + <string>${EXECUTABLE_NAME}</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleName</key>
  16 + <string>${PRODUCT_NAME}</string>
  17 + <key>CFBundlePackageType</key>
  18 + <string>APPL</string>
  19 + <key>CFBundleShortVersionString</key>
  20 + <string>1.0</string>
  21 + <key>CFBundleSignature</key>
  22 + <string>????</string>
  23 + <key>CFBundleVersion</key>
  24 + <string>1.0</string>
  25 + <key>LSRequiresIPhoneOS</key>
  26 + <true/>
  27 + <key>NSAppTransportSecurity</key>
  28 + <dict>
  29 + <key>NSAllowsArbitraryLoads</key>
  30 + <true/>
  31 + </dict>
  32 + <key>UILaunchStoryboardName</key>
  33 + <string>LaunchScreen</string>
  34 + <key>UIMainStoryboardFile</key>
  35 + <string>Main</string>
  36 + <key>UIRequiredDeviceCapabilities</key>
  37 + <array>
  38 + <string>armv7</string>
  39 + </array>
  40 + <key>UISupportedInterfaceOrientations</key>
  41 + <array>
  42 + <string>UIInterfaceOrientationPortrait</string>
  43 + <string>UIInterfaceOrientationLandscapeLeft</string>
  44 + <string>UIInterfaceOrientationLandscapeRight</string>
  45 + </array>
  46 + <key>UISupportedInterfaceOrientations~ipad</key>
  47 + <array>
  48 + <string>UIInterfaceOrientationPortrait</string>
  49 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  50 + <string>UIInterfaceOrientationLandscapeLeft</string>
  51 + <string>UIInterfaceOrientationLandscapeRight</string>
  52 + </array>
  53 +</dict>
  54 +</plist>
... ...
Example/CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Prefix.pch 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/CNLiveWitnessVideoModule-Prefix.pch
  1 +//
  2 +// Prefix header
  3 +//
  4 +// The contents of this file are implicitly included at the beginning of every source file.
  5 +//
  6 +
  7 +#import <Availability.h>
  8 +
  9 +#ifndef __IPHONE_5_0
  10 +#warning "This project uses features only available in iOS SDK 5.0 and later."
  11 +#endif
  12 +
  13 +#ifdef __OBJC__
  14 + @import UIKit;
  15 + @import Foundation;
  16 +#endif
... ...
Example/CNLiveWitnessVideoModule/Images.xcassets/AppIcon.appiconset/Contents.json 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/Images.xcassets/AppIcon.appiconset/Contents.json
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "iphone",
  5 + "size" : "20x20",
  6 + "scale" : "2x"
  7 + },
  8 + {
  9 + "idiom" : "iphone",
  10 + "size" : "20x20",
  11 + "scale" : "3x"
  12 + },
  13 + {
  14 + "idiom" : "iphone",
  15 + "size" : "29x29",
  16 + "scale" : "2x"
  17 + },
  18 + {
  19 + "idiom" : "iphone",
  20 + "size" : "29x29",
  21 + "scale" : "3x"
  22 + },
  23 + {
  24 + "idiom" : "iphone",
  25 + "size" : "40x40",
  26 + "scale" : "2x"
  27 + },
  28 + {
  29 + "idiom" : "iphone",
  30 + "size" : "40x40",
  31 + "scale" : "3x"
  32 + },
  33 + {
  34 + "idiom" : "iphone",
  35 + "size" : "60x60",
  36 + "scale" : "2x"
  37 + },
  38 + {
  39 + "idiom" : "iphone",
  40 + "size" : "60x60",
  41 + "scale" : "3x"
  42 + },
  43 + {
  44 + "idiom" : "ipad",
  45 + "size" : "20x20",
  46 + "scale" : "1x"
  47 + },
  48 + {
  49 + "idiom" : "ipad",
  50 + "size" : "20x20",
  51 + "scale" : "2x"
  52 + },
  53 + {
  54 + "idiom" : "ipad",
  55 + "size" : "29x29",
  56 + "scale" : "1x"
  57 + },
  58 + {
  59 + "idiom" : "ipad",
  60 + "size" : "29x29",
  61 + "scale" : "2x"
  62 + },
  63 + {
  64 + "idiom" : "ipad",
  65 + "size" : "40x40",
  66 + "scale" : "1x"
  67 + },
  68 + {
  69 + "idiom" : "ipad",
  70 + "size" : "40x40",
  71 + "scale" : "2x"
  72 + },
  73 + {
  74 + "idiom" : "ipad",
  75 + "size" : "76x76",
  76 + "scale" : "1x"
  77 + },
  78 + {
  79 + "idiom" : "ipad",
  80 + "size" : "76x76",
  81 + "scale" : "2x"
  82 + },
  83 + {
  84 + "idiom" : "ipad",
  85 + "size" : "83.5x83.5",
  86 + "scale" : "2x"
  87 + },
  88 + {
  89 + "idiom" : "ios-marketing",
  90 + "size" : "1024x1024",
  91 + "scale" : "1x"
  92 + }
  93 + ],
  94 + "info" : {
  95 + "version" : 1,
  96 + "author" : "xcode"
  97 + }
  98 +}
... ...
Example/CNLiveWitnessVideoModule/en.lproj/InfoPlist.strings 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/en.lproj/InfoPlist.strings
  1 +/* Localized versions of Info.plist keys */
  2 +
... ...
Example/CNLiveWitnessVideoModule/main.m 0 → 100644
  1 +++ a/Example/CNLiveWitnessVideoModule/main.m
  1 +//
  2 +// main.m
  3 +// CNLiveWitnessVideoModule
  4 +//
  5 +// Created by dawanzi on 04/03/2020.
  6 +// Copyright (c) 2020 dawanzi. All rights reserved.
  7 +//
  8 +
  9 +@import UIKit;
  10 +#import "CNLIVEAppDelegate.h"
  11 +
  12 +int main(int argc, char * argv[])
  13 +{
  14 + @autoreleasepool {
  15 + return UIApplicationMain(argc, argv, nil, NSStringFromClass([CNLIVEAppDelegate class]));
  16 + }
  17 +}
... ...
Example/Podfile 0 → 100644
  1 +++ a/Example/Podfile
  1 +use_frameworks!
  2 +source 'https://github.com/CocoaPods/Specs.git'
  3 +source 'http://bj.gitlab.cnlive.com/ios-team/CNLiveRepos.git'
  4 +platform :ios, '9.0'
  5 +
  6 +target 'CNLiveWitnessVideoModule_Example' do
  7 + pod 'CNLiveWitnessVideoModule', :path => '../'
  8 +
  9 + target 'CNLiveWitnessVideoModule_Tests' do
  10 + inherit! :search_paths
  11 +
  12 +
  13 + end
  14 +end
... ...
Example/Tests/Tests-Info.plist 0 → 100644
  1 +++ a/Example/Tests/Tests-Info.plist
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>en</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>${EXECUTABLE_NAME}</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundlePackageType</key>
  14 + <string>BNDL</string>
  15 + <key>CFBundleShortVersionString</key>
  16 + <string>1.0</string>
  17 + <key>CFBundleSignature</key>
  18 + <string>????</string>
  19 + <key>CFBundleVersion</key>
  20 + <string>1</string>
  21 +</dict>
  22 +</plist>
... ...
Example/Tests/Tests-Prefix.pch 0 → 100644
  1 +++ a/Example/Tests/Tests-Prefix.pch
  1 +// The contents of this file are implicitly included at the beginning of every test case source file.
  2 +
  3 +#ifdef __OBJC__
  4 +
  5 +
  6 +
  7 +#endif
... ...
Example/Tests/Tests.m 0 → 100644
  1 +++ a/Example/Tests/Tests.m
  1 +//
  2 +// CNLiveWitnessVideoModuleTests.m
  3 +// CNLiveWitnessVideoModuleTests
  4 +//
  5 +// Created by dawanzi on 04/03/2020.
  6 +// Copyright (c) 2020 dawanzi. All rights reserved.
  7 +//
  8 +
  9 +@import XCTest;
  10 +
  11 +@interface Tests : XCTestCase
  12 +
  13 +@end
  14 +
  15 +@implementation Tests
  16 +
  17 +- (void)setUp
  18 +{
  19 + [super setUp];
  20 + // Put setup code here. This method is called before the invocation of each test method in the class.
  21 +}
  22 +
  23 +- (void)tearDown
  24 +{
  25 + // Put teardown code here. This method is called after the invocation of each test method in the class.
  26 + [super tearDown];
  27 +}
  28 +
  29 +- (void)testExample
  30 +{
  31 + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
  32 +}
  33 +
  34 +@end
  35 +
... ...
Example/Tests/en.lproj/InfoPlist.strings 0 → 100644
  1 +++ a/Example/Tests/en.lproj/InfoPlist.strings
  1 +/* Localized versions of Info.plist keys */
  2 +
... ...
LICENSE 0 → 100644
  1 +++ a/LICENSE
  1 +Copyright (c) 2020 dawanzi <1427945373@qq.com>
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining a copy
  4 +of this software and associated documentation files (the "Software"), to deal
  5 +in the Software without restriction, including without limitation the rights
  6 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7 +copies of the Software, and to permit persons to whom the Software is
  8 +furnished to do so, subject to the following conditions:
  9 +
  10 +The above copyright notice and this permission notice shall be included in
  11 +all copies or substantial portions of the Software.
  12 +
  13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19 +THE SOFTWARE.
... ...
README.md 0 → 100644
  1 +++ a/README.md
  1 +# CNLiveWitnessVideoModule
  2 +
  3 +[![CI Status](https://img.shields.io/travis/dawanzi/CNLiveWitnessVideoModule.svg?style=flat)](https://travis-ci.org/dawanzi/CNLiveWitnessVideoModule)
  4 +[![Version](https://img.shields.io/cocoapods/v/CNLiveWitnessVideoModule.svg?style=flat)](https://cocoapods.org/pods/CNLiveWitnessVideoModule)
  5 +[![License](https://img.shields.io/cocoapods/l/CNLiveWitnessVideoModule.svg?style=flat)](https://cocoapods.org/pods/CNLiveWitnessVideoModule)
  6 +[![Platform](https://img.shields.io/cocoapods/p/CNLiveWitnessVideoModule.svg?style=flat)](https://cocoapods.org/pods/CNLiveWitnessVideoModule)
  7 +
  8 +## Example
  9 +
  10 +To run the example project, clone the repo, and run `pod install` from the Example directory first.
  11 +
  12 +## Requirements
  13 +
  14 +## Installation
  15 +
  16 +CNLiveWitnessVideoModule is available through [CocoaPods](https://cocoapods.org). To install
  17 +it, simply add the following line to your Podfile:
  18 +
  19 +```ruby
  20 +pod 'CNLiveWitnessVideoModule'
  21 +```
  22 +
  23 +## Author
  24 +
  25 +dawanzi, 1427945373@qq.com
  26 +
  27 +## License
  28 +
  29 +CNLiveWitnessVideoModule is available under the MIT license. See the LICENSE file for more info.
... ...
_Pods.xcodeproj 0 → 120000
  1 +++ a/_Pods.xcodeproj
  1 +Example/Pods/Pods.xcodeproj
0 2 \ No newline at end of file
... ...