Git: ?https://github.com/DrunkenMouse/miaobo
參考:http://www.reibang.com/p/b8db6c142aad
總結(jié):?
彈幕使用Barrage、編碼推流使用LFLive(自帶美顏勘究、攝像頭切換)皱蹦、拉流解碼使用IJK、特效使用粒子動畫 景馁。以下內(nèi)容建議伴隨源碼觀看。
宏定義:
先判斷判斷OC語言才執(zhí)行定義的操作,#ifndef PresfixHeader_pch // 防止頭文件被重復引用
#define PrefixHeader_pch //引用頭文件 ?NSLog的輸出為DeBug時才輸出
showTime(直播)文件夾:
實現(xiàn)直播的文件夾虚青,推流使用的LFLive框架,其自身集合了美顏菱涤、攝像頭切換苞也、轉(zhuǎn)碼推流到服務(wù)器
與直播狀態(tài)的獲取等方法
本案例通過自己本地搭建的nginx + RTMP服務(wù)器與ffmpeg協(xié)議來接收推流,通過IJK框架
實現(xiàn)拉流解碼的操作
仿寫時發(fā)現(xiàn)作者用的LFLive有修改一些文件,而我怎么嘗試都失敗就只好老老實實pod粘秆,而區(qū)別僅僅在于直播時的session少了一個推流類型設(shè)置為rtmp(本地搭建的服務(wù)器如迟,用來接收推流的內(nèi)容)
網(wǎng)絡(luò)狀態(tài)監(jiān)聽:Reachability
據(jù)我所知,很多框架都是使用Reachability來監(jiān)聽網(wǎng)絡(luò)狀態(tài)攻走,如網(wǎng)絡(luò)狀態(tài)是否改變殷勘、有網(wǎng)沒網(wǎng)、2G昔搂、3G玲销、4G還是WIFI
Main - 主界面
主體控件使用tabbarController搭建,包含三個控制器摘符。分為左側(cè)觀看直播贤斜,中間開啟直播,右側(cè)個人中心
開啟直播時需判斷攝像頭可否使用逛裤,麥克風可否使用瘩绒,當前機型是否支持(模擬器不支持直播)
手機型號通過UIDevice的utsname獲得,因為系統(tǒng)提供的型號描述與通常我們自己的描述不太相同,所以通過延展類轉(zhuǎn)換
判斷是否有攝像頭通過UIImagePickerController
判斷攝像頭權(quán)限通過AVAuthorizationStatus
判斷是否有麥克風權(quán)限通過AVAudioSession
Home(文件夾)-Hot(子文件夾) 熱播
使用TbleView來展示頁面,頂端廣告輪播圖的展示使用XRCarouselView第三方带族,下拉刷新上拉加載使用的MJ
其中下拉刷新是自定義繼承了MJ的RefreshGifHeader,通過繼承后重寫init完成初始化時帶有自定義操作锁荔,在通過MJ的Block設(shè)置時Block內(nèi)部會調(diào)用[[self alloc]init]實現(xiàn)通過類方法生成一個對象
對于下拉加載、上拉刷新時通過網(wǎng)絡(luò)請求獲取所需數(shù)據(jù)的參數(shù)設(shè)置使用CurrentPage蝙砌,CurrentPage值初始化為1阳堕。
下拉刷新時CurrentPage值為1跋理,并清空之前通過數(shù)組保存的直播數(shù)據(jù),而后獲取頂部廣告與直播數(shù)據(jù)
上拉加載時CurrentPage值加1恬总,并獲取直播數(shù)組數(shù)據(jù)前普,停止上拉、下拉的刷新狀態(tài)越驻,新數(shù)據(jù)添加到當前數(shù)組汁政,隨后頁數(shù)減1恢復到原來值
展示時tableViewCell的第一行為廣告,其余為直播展示缀旁。
廣告圖片的點擊是跳轉(zhuǎn)到一個WebView记劈,通過請求回來的廣告信息中的URL跳轉(zhuǎn)
直播視圖的點擊事件通過tableView的點擊事件來響應跳轉(zhuǎn)到另一個控制器展示直播(ADLiveCollectionViewController)
展示直播的控制器是CollectionViewController類型,以便滑動時切換不同主播
Home-Home 熱播并巍、最新目木、關(guān)注所在的View
頂部是UIView掛載三個按鈕,通過按鈕的點擊事件來切換underLine的位置懊渡,詳情可參考我的上一篇文章:按鈕點擊切換不同頁面
滑動選中的按鈕與按鈕代表的Type值通過枚舉值setSelectedType來保存
底部是ScrollView,其寬度是屏幕寬*3,通過將最新最熱關(guān)心三個控制器加到自身刽射,與將控制器的View加到ScrollView上達到顯示的目的
若滾動切換界面,則滾動結(jié)束后需設(shè)置導航欄的underLine剃执,若ScrollView滑動的當前頁過一半即為下一頁
皇冠的點擊是跳轉(zhuǎn)到一個WebView, WebView通過一個UIViewController展示誓禁,通過自定義初始化方法設(shè)置WebView的內(nèi)容,并通過點語法調(diào)用創(chuàng)建WebView
Home-NEW 最新
沒啥好說的肾档,就是一個TableView
第一行cell為輪播圖摹恰,其余為直播的介紹,數(shù)據(jù)通過網(wǎng)絡(luò)請求獲取怒见,點擊Cell后跳轉(zhuǎn)到直播頁面
Home-Live? 所有的直播展示都是通過其來展示
頁面由CollectionView展示俗慈,展示時只有一個item即為直播的界面內(nèi)容
init初始化時即設(shè)置flowLayout,設(shè)置下拉刷新時操作為結(jié)束當前刷新。而后currentIndex(區(qū)分當前是哪一個頁面)+1,若此時currentIndex等于lives.count代表是最后一個主播遣耍,則currentIndex變?yōu)?闺阱,刷新當前collectionView實現(xiàn)直播切換功能
直播頁面的詳細設(shè)置在ADLiveViewCell中,通過currentIndex來區(qū)分當前是哪一個頁面舵变,lives數(shù)組獲取直播數(shù)據(jù)皆由外界賦值
直播關(guān)閉事件通過block來調(diào)用
直播的顯示頁面通過自定義cell(ADLiveViewCell)來展示酣溃、
對于直播顯示頁面cell的設(shè)置
先設(shè)置底部工具欄,通過ADBottomToolView來初始化設(shè)置棋傍【壤控件的寬度固定,間距為自動計算瘫拣,通過ImageView展示內(nèi)容并開啟用戶交互,通過自定義添加的手勢來響應圖片的點擊事件告喊,imageView以tag值區(qū)分
點擊事件中通過block來調(diào)用當前控制器中設(shè)置的響應事件麸拄,目前只有close和publicTalk(彈幕)有響應事件執(zhí)行,其余為空派昧。
通過insert: aboveSubView: 將其置于placeHolderView之上
placeHolderView如果沒有GIF展示,就展示一組默認image拢切,通過自定義ViewController延展類中對象方法howGifLoding: inView: 完成蒂萎。
具體操作為若傳來的image數(shù)組為空,則設(shè)置一組默認數(shù)組淮椰,若傳來的View為空五慈,則為當前控制器的View。
而后通過ImageView的延展類中對象方法playGifAnim播放主穗,具體播放為通過ImageView的animationImages設(shè)置imageArr泻拦,通過ImageView的animationDuration設(shè)置播放一次的時間,通過ImageView的animationRepeatCount設(shè)置播放次數(shù),0為無限忽媒,而后通過startAnimating 和 stopAnimating開始\暫停播放
直播時的彈幕效果使用的是BarrageRenderer框架,通過direction設(shè)置最大數(shù)量
在初始化中通過NSSafeObject與NSTimer結(jié)合使得每過0.5秒就當前對象限制一下彈幕數(shù)量<=50争拐。NSSafeObject就是通過初始化綁定一個對象與一個方法執(zhí)行操作
通過對cell的live(主播的相關(guān)信息數(shù)據(jù))設(shè)置,而調(diào)用anchorView并設(shè)置live晦雨,通過anchorView(頂部主播相關(guān)視圖)的點語法來生成一個UIView視圖架曹,每個anchorView都保存有主播user(chaoyangUser)、直播live的相關(guān)視圖與點擊開關(guān)闹瞧。
圓角信息通過maskToBounds來設(shè)置绑雄,邊框使用layer
在線人數(shù)與貓糧娃娃皆是隨機生成,并通過NSTimer設(shè)置為1.0秒更新一次,頭像的點擊事件與右側(cè)關(guān)聯(lián)頭像圖標為同一事件奥邮。
anchorView生成之后通過block響應關(guān)閉的點擊事件來控制直播播放器万牺,shouldShowHudView(右側(cè)詳細信息)是否開啟,默認是關(guān)閉的,通過insert插入到placeHolder上
當設(shè)置了Cell的live信息后漠烧,就開始播放杏愤。通過plarFLV: placeHolderUrl:方法
前者為播放的flv,后者為播放時的placeHolderView.image的地址已脓。每次播放時珊楼,都將上一次的播放shutdown并移除,粒子特效移除并置空度液,同類型直播視圖移除厕宗,并從控制中心移除對自己的監(jiān)聽
而后從新設(shè)置IJK的options與Player(options設(shè)置音量、幀速率堕担、聲音視頻的播放模式等,player則為controllor負責flv的播放與播放模式已慢、HudView等),并prepareToPlayer,設(shè)置播放器的監(jiān)聽
工會其他主播/類似主播(otherView)顯示霹购,開啟粒子特效(EmitterLayer)
其中otherView與EmitterLayer都是點語法生成佑惠,otherView添加點擊手勢來響應點擊事件
粒子特效使用CAEmitterLayer框架,通過image顯示內(nèi)容,添加到moviePlayer的layer層上
關(guān)聯(lián)主播即為位于當前列表主播的下一個主播膜楷,若當前主播為最后一個主播旭咽,則下一個主播即為第一個主播,通過外界賦值獲取數(shù)據(jù)赌厅,重寫set方法顯示catEarView
如果相關(guān)主播值為nil穷绵,就隱藏catEarView,catEarView(ADCatEarView)通過options設(shè)置只播放視頻沒有聲音且自動播放特愿,而后通過播放控制器播放仲墨,圓角為自身View的mask.
需注意,要重寫removeFromSuperView,判斷播放器存在時應先關(guān)閉remove而后置空
對于關(guān)聯(lián)主播的點擊事件
通過block調(diào)用寫在控制器里的事件揍障,當播放器的播放狀態(tài)發(fā)生改變時
如果是自動播放,并當前控制器沒有播放時則開啟播放(如網(wǎng)絡(luò)狀態(tài)不好暫停后恢復)目养,并于一秒后移除placeHolderView,添加彈幕,隱藏父控制器的GIF
如果正在播放狀態(tài)則隱藏父控制器的GIF,如果是網(wǎng)絡(luò)不佳正在加載狀態(tài)就讓父控制器顯示GIF亚兄,所以若網(wǎng)絡(luò)狀態(tài)不好, 斷開后恢復, 也需要去掉加載
播放結(jié)束時需判斷若因為網(wǎng)速或者其他原因?qū)е轮辈top了而且GIF沒有顯示混稽,則也要顯示GIF,存在狀態(tài)如暫停狀態(tài)后直接stop,所以自動暫停時不需要判斷,而后從新獲取直播flv數(shù)據(jù)開始播放,若獲取失敗則關(guān)閉移除播放器并置空
Home - web
點擊皇冠后的頁面用Web展示审胚,webView通過點語法設(shè)置匈勋,在initWithUrl的時候就創(chuàng)建出了webView并設(shè)置了內(nèi)容。
至此膳叨,穿針引線思路完畢洽洁。