项目文件结构:
- Login : 登录页面集成了友盟第三方登录微信和QQ,新浪授权登录是请求新浪官方的OAuth请求,以及一些登录所需要的资源
- Main :主要包含标签视图控制器UITabBarController 、导航控制器UINavigationController、数据请求工具类XLLiveTool、业务逻辑类XLDealData、代理类、pch文件和单例的头文件,都是一些全局都能用的东西。
- Home : 首页,主要包括热门,最新和关注三部分,把这三部分添加到(XLHomeViewController)里面去,方便以后做处理,自定义navigationItem.titleView因为要靠路适配问题这里我把宽设置为屏幕宽度的一半;我有自定义了UISrollView,这纯属个人爱好你也可以直接在home控制器里面添加
- Live : 直播,分两部分看直播和自己直播,看直播主要用了IJKMediaFramework.framework这个框架,直播用到了LFLIveKit另外他还封装了GPUImage可以直接实现智能美颜效果,重点在直播页面的布局和数据处理,要考虑不同机型的屏幕适配和数据传输中不出现问题,具体操作请看代码
- Other : 这个文件夹主要放的是分类,拓展类,plist和第三方库
- CrownRank :这个类主要作用是请求加载webView,排行榜、热门视图的头标题跳转都是利用这个类实现的
- Search : 搜索页面,这个页面我没有做,有兴趣的可以自己添加,基本页面已搭好
- Profile : 个人中心页面主要完成下拉图片放大和波纹效果,跳转页面没有做框架已经打好,有兴趣可以自己填
项目详解:
1.登录模块,运行时不难发现登录页面的背景视频是随机播放的,第三方登录按钮是自定义一个view里面添加UIButton,由于要考虑到自动布局,所以我是这样写的,重写了布局方法,别忘了在前面创建按钮的时候给按钮设置tag,方便监听点击了那个按钮.
- (void)layoutSubviews { [super layoutSubviews]; NSInteger count = self.subviews.count; for (int i=0; i<count; i++){ UIButton *btn = self.subviews[i]; CGFloat margin = (XLScreenW - btn.width* count) / (count + 1); CGFloat x = (btn.width + margin) * i + margin; CGFloat y = 0; btn.frame = CGRectMake(x, y, btn.width, btn.height); } }
2.一个父控制器HomeViewController+三个子控制器(热门/最新/关注. 每个控制器各自管理自己的业务逻辑, 高内聚低耦合). 重写HomeViewController的loadView, 自定义UIScrollView, 将三个子控制器的view添加到UIScrollView上.将self.view替换成UIScrollView
3 . 直播,主要实现功能头部主播信息,旋转主播组信息,猫耳视图是随机送这一组里选择一个主播只有画面没有声音,底部功能按钮实现分享等功能(详情请看代码),另外还有
粒子效果类似于点赞
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer]; // 发射器在xy平面的中心位置 emitterLayer.emitterPosition = CGPointMake(self.moviePlayer.view.frame.size.width-50,self.moviePlayer.view.frame.size.height-50); // 发射器的尺寸大小 emitterLayer.emitterSize = CGSizeMake(20, 20); // 渲染模式 emitterLayer.renderMode = kCAEmitterLayerUnordered; // 开启三维效果 // _emitterLayer.preservesDepth = YES; NSMutableArray *array = [NSMutableArray array]; // 创建粒子 for (int i = 0; i<10; i++) { // 发射单元 CAEmitterCell *stepCell = [CAEmitterCell emitterCell]; // 粒子的创建速率,默认为1/s stepCell.birthRate = 1; // 粒子存活时间 stepCell.lifetime = arc4random_uniform(4) + 1; // 粒子的生存时间容差 stepCell.lifetimeRange = 1.5; // 颜色 // fire.color=[[UIColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:0.1]CGColor]; UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"good%d_30x30", i]]; // 粒子显示的内容 stepCell.contents = (id)[image CGImage]; // 粒子的名字 // [fire setName:@"step%d", i]; // 粒子的运动速度 stepCell.velocity = arc4random_uniform(100) + 100; // 粒子速度的容差 stepCell.velocityRange = 80; // 粒子在xy平面的发射角度 stepCell.emissionLongitude = M_PI+M_PI_2;; // 粒子发射角度的容差 stepCell.emissionRange = M_PI_2/6; // 缩放比例 stepCell.scale = 0.3; [array addObject:stepCell]; } emitterLayer.emitterCells = array; [self.moviePlayer.view.layer insertSublayer:emitterLayer below:self.catEarView.layer]
弹幕效果(开启后会有卡顿现象)
弹幕使用的也是一个第三方轮子BarrageRenderer . 这个开源项目的文档都是中文的, 用法也是很简单的.
- (instancetype)init { if (self == [super init]){ self.bottomToolView.hidden = NO; _renderer = [[BarrageRenderer alloc] init]; _renderer.canvasMargin = UIEdgeInsetsMake(XLScreenH * 0.3, 10, 10, 10); [self.view addSubview:_renderer.view]; NSSafeObject * safeObj = [[NSSafeObject alloc]initWithObject:self withSelector:@selector(autoSendBarrage)]; self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:safeObj selector:@selector(excute) userInfo:nil repeats:YES]; } return self; } #pragma mark - 弹幕描述符生产方法 long _index = 0; /// 生成精灵描述 - 过场文字弹幕 - (BarrageDescriptor *)walkTextSpriteDescriptorWithDirection:(NSInteger)direction { BarrageDescriptor * descriptor = [[BarrageDescriptor alloc]init]; descriptor.spriteName = NSStringFromClass([BarrageWalkTextSprite class]); descriptor.params[@"text"] = self.danMuText[arc4random_uniform((uint32_t)self.danMuText.count)]; descriptor.params[@"textColor"] = XLColor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256)); descriptor.params[@"speed"] = @(100 * (double)random()/RAND_MAX+50); descriptor.params[@"direction"] = @(direction); descriptor.params[@"clickAction"] = ^{ [MBProgressHUD showAlertMessage:@"弹幕被点击"]; }; return descriptor; } //最后别忘了开始 [_renderer start];
4.H264硬编码 如果使用ijkplayer 使用硬解码, 一句代码即可.
[option setPlayerOptionValue:@"1" forKey:@"videotoolbox"];
硬编码的应用场景: 我们要将主播的视频数据传送给服务器
通过摄像头来采集图像,然后将采集到的图像,通过硬编码的方式进行编码,最后编码后的数据将其组合成H264的码流通过网络传播。
摄像头采集图像, iOS系统提供了AVCaptureSession来采集摄像头的图像数据. 项目中我是直接使用 GPUImage 中的GPUImageVideoCamera, 直接设置GPUImageVideoCamera的代理即可, 在其代理方法- (void)willOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer;进行数据编码即可.
切记一点: 不管是系统自带的AVCaptureSession还是GPUImageVideoCamera采集到的数据都是未经过编码的CMSampleBuffer.
5.下拉图片放大和波纹效果大家想要实现波纹就要对正玄波有所了解,废话不多说直接上DEMO:
下载地址:https://github.com/XLAccount/XLTableView
OK接下来看看别的---==============
接下来看看项目中遇到的错误是怎么解决的吧
1.常见的令人抓狂的linker错误
2. was mutated while being enumerated
待续。。。。