項目文件結構:
- 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 - 彈幕描述符生產方法 /// 生成精靈描述 - 過場文字彈幕 - (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"] = Color(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"] = ^{ UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"彈幕被點擊" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil]; [alertView show]; }; return descriptor; }
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
待續。。。。