關(guān)于封裝播放器相關(guān)

一:基礎(chǔ)功能的實現(xiàn):

? ? 1.基于AVFoundation/AVFoundation.h來實現(xiàn)功能.

1.1創(chuàng)建一個播放器,并且傳一個url過來就播放,是否考慮緩存

- (void)playWithURL:(NSURL*)url isCache:(BOOL)isCache;

播放需要2個類來輔助,AVURLAsset,AVPlayerItem.

AVURLAsset:用來處理資源的請求

AVPlayerItem:用來組織資源,? 當資源的組織者, 告訴我們資源準備好了之后, 我們再播放(后續(xù)會在個里面做緩存相關(guān)).使用KVO監(jiān)聽他的兩個狀態(tài)? ,來做播放的相應(yīng)的操作.item 是他的實例對象.

//AVPlayerItemStatus statu

? ? [itemaddObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

? ? [itemaddObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];

這里給播放器設(shè)置資源組織者,讓他來管理資源.

? ? self.player = [AVPlayer playerWithPlayerItem:item];

#pragma mark - KVO

-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context {

? ? if([keyPathisEqualToString:@"status"]) {

? ? ? ? AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] integerValue];

? ? ? ? if (status == AVPlayerItemStatusReadyToPlay) {

? ? ? ? ? ? NSLog(@"資源準備好了, 這時候播放就沒有問題");

? ? ? ? ? ? [selfresume];

//? ? ? ? ? ? [self.player play];

? ? ? ? }else{

? ? ? ? ? ? NSLog(@"狀態(tài)未知");

? ? ? ? ? ? self.playState = MLRemotePlayerStateFailed;

? ? ? ? }

? ? }

? ? else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {

? ? ? ? BOOLisKeepUp = [change[NSKeyValueChangeNewKey]boolValue];

? ? ? ? if(isKeepUp) {

? ? ? ? ? ? NSLog(@"當前的資源, 準備的已經(jīng)足夠播放了");

? ? ? ? ? ? if(!_isUserPause) {

? ? ? ? ? ? ? ? [selfresume];

? ? ? ? ? ? }

? ? ? ? }else{

? ? ? ? ? ? NSLog(@"資源還不夠, 正在加載過程當中");

? ? ? ? ? ? self.playState = MLRemotePlayerStateLoading;

? ? ? ? }

? ? }

}

? ? 2.基礎(chǔ)功能包括播放,暫停,繼續(xù)播放,快進,進度條拖動,倍速,靜音功能,

基礎(chǔ)的功能大部分都是都有直接調(diào)用的方法.直接自己封裝下就好了,幾個需要自己計算的功能.


方法聲明


要注意用戶的操作的優(yōu)先級要高,弄一個暫停的屬性來記錄用戶的暫停操作


幾個需要計算的方法,很簡單,有些方法看名字就知道意思了


這個是加載的進度,因為音頻是一段一段加載的所以取出最新的那一段/總時長

二:狀態(tài)控制,播放事件

比較煩的狀態(tài)控制,需要不斷調(diào)試,寫一個枚舉來記錄.


狀態(tài)控制的枚舉

在播放,暫停,加載數(shù)據(jù)等時候去賦值就好,需要自己去看在哪里加合適.

播放事件就是上面說到的監(jiān)聽的兩個屬性,AVPlayerItemStatus status ,self.player.currentItem.playbackLikelyToKeepUp

status :來監(jiān)聽狀態(tài)是否資源準備好了,好了就可以播放

playbackLikelyToKeepUp:這個也是用來準備資源,看準備的資源是否足夠這一段的播放,是一段一段的,所以寫一個if else.

注意:要注意用戶重復(fù)點擊播放按鈕,重復(fù)監(jiān)聽這兩個屬性,寫一個移除監(jiān)聽的方法,判斷當前播放任務(wù)已經(jīng)存在并且是同一個url地址,是的話就繼續(xù)播放,還要判斷當前self.palyer.currentItem是否存在 存在就移除,然重新去監(jiān)聽.


三:攔截播放請求,準備動態(tài)下載,緩存數(shù)據(jù)

播放請求其實走的是資源組織者對象的代理方法,?AVURLAsset *asset = [AVURLAsset assetWithURL:url]; 所以以這個為切入點,來攔截他的請求.

自己實現(xiàn)一個代理的類MLRemoteResourceLoaderDelegate,并且設(shè)置asset的代理為 這個類的實例.? ? [asset.resourceLoader setDelegate:self.resourceLoaderDelegate queue:dispatch_get_main_queue()];

實現(xiàn)這兩個代理:

/**當外界, 需要播放一段音頻資源是, 會跑一個請求, 給這個對象

?? 這個對象, 到時候, 只需要根據(jù)請求信息, 拋數(shù)據(jù)給外界

在這個里面做3件事情

?*/

- (BOOL)resourceLoader:(AVAssetResourceLoader*)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest*)loadingRequest{
? ? // 1. 填充相應(yīng)的信息頭信息

? ? // 計算總大小

? ? NSURL*url = loadingRequest.request.URL;

? ? long long totalSize = [XMGRemoteAudioFile cacheFileSize:url];

? ? loadingRequest.contentInformationRequest.contentLength = totalSize;

? ? NSString *contentType = [XMGRemoteAudioFile contentType:url];

? ? loadingRequest.contentInformationRequest.contentType = contentType;

? ? loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;


? ? // 2. 相應(yīng)數(shù)據(jù)給外界

? ? NSData *data = [NSData dataWithContentsOfFile:[XMGRemoteAudioFile cacheFilePath:url] options:NSDataReadingMappedIfSafe error:nil];


? ? longlongrequestOffset = loadingRequest.dataRequest.requestedOffset;

? ? NSIntegerrequestLength = loadingRequest.dataRequest.requestedLength;


? ? NSData*subData = [datasubdataWithRange:NSMakeRange(requestOffset, requestLength)];


? ? [loadingRequest.dataRequestrespondWithData:subData];


? ? // 3. 完成本次請求(一旦,所有的數(shù)據(jù)都給完了, 才能調(diào)用完成請求方法)

? ? [loadingRequestfinishLoading];

}

/** 取消請求*/

- (void)resourceLoader:(AVAssetResourceLoader*)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest*)loadingRequest


四:動態(tài)下載,緩存數(shù)據(jù)

4.1創(chuàng)建一個管理文件的類,方便文件的操作,要先把下載中的文件放在temp文件夾,當他的下載大小和響應(yīng)頭中返回給我們的資源總大小一致的時候我們要把他移動到cache文件夾下保存.


用來執(zhí)行一些文件夾的操作.


就這寫相關(guān)操作吧.

文件夾操作實現(xiàn)就不寫了

4.2創(chuàng)建下載的類,主要用于下載文件,并且將文件以輸出流的方式輸出到指定目錄下,寫一個代理,將告訴外界已經(jīng)在下載了,然后由資源的代理在下載代理的視線中開始處理音頻播放的相關(guān)操作.從而實現(xiàn)了下載和播放的操作,自己要弄一個可變數(shù)組來存儲不斷返回來的loadingRequest,因為loadingRequest是一段一段的數(shù)據(jù)流.


MLAudioDownLoader的一些屬性和方法.

1>創(chuàng)建session對象

session

2>實現(xiàn)-(void)downloadWithUrl:(NSURL*)url offset:(longlong)offset方法

下載方法,下載的是一段數(shù)據(jù).

3>實現(xiàn)session的3個代理方法


需要自己創(chuàng)建一個輸出流


? ?在MLRemoteResourceLoaderDelegate中創(chuàng)建一個下載器downloader,delegate = self.實現(xiàn)代理方法,在代理方法中調(diào)用處理資源handeAllLoading的方法.

? 拿到資源的URL地址?

? NSURL*url = [loadingRequest.request.URLHTTPUrl];

請求的偏移量和當前偏移量

1>在資源返回的代理方法中判斷是否有本地數(shù)據(jù);

判斷本地是否存在

2>判斷是否有正在下載的數(shù)據(jù)

requestOffset是從哪里開始下載

3>判斷當前的資源是否需要重新下載

3.1>當資源請求, 開始點 < 下載的開始點

3.2>?當資源的請求, 開始點 > 下載的開始點 + 下載的長度 + 一個你自己想要的緩存值


4>開始處理資源請求 (在下載過程當中, 也要不斷的判斷)

處理請求的方法.

4.3注意事項:假如在創(chuàng)建player的時候需要緩存,?NSURLComponents *components 的scheme需要修改成sreaming的流模式.自己寫一個URL分類,修改一下.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖抱究,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠肾,死亡現(xiàn)場離奇詭異关炼,居然都是意外死亡涩笤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門锰瘸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刽严,“玉大人,你說我怎么就攤上這事避凝∥杼眩” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵管削,是天一觀的道長倒脓。 經(jīng)常有香客問我,道長含思,這世上最難降的妖魔是什么崎弃? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮含潘,結(jié)果婚禮上饲做,老公的妹妹穿的比我還像新娘。我一直安慰自己遏弱,他們只是感情好盆均,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腾窝,像睡著了一般缀踪。 火紅的嫁衣襯著肌膚如雪居砖。 梳的紋絲不亂的頭發(fā)上虹脯,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音奏候,去河邊找鬼循集。 笑死,一個胖子當著我的面吹牛蔗草,可吹牛的內(nèi)容都是我干的咒彤。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼咒精,長吁一口氣:“原來是場噩夢啊……” “哼镶柱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起模叙,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤歇拆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體故觅,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡厂庇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了输吏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片权旷。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贯溅,靈堂內(nèi)的尸體忽然破棺而出拄氯,到底是詐尸還是另有隱情,我是刑警寧澤它浅,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布坤邪,位于F島的核電站,受9級特大地震影響罚缕,放射性物質(zhì)發(fā)生泄漏艇纺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一邮弹、第九天 我趴在偏房一處隱蔽的房頂上張望黔衡。 院中可真熱鬧,春花似錦腌乡、人聲如沸盟劫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侣签。三九已至,卻和暖如春急迂,著一層夾襖步出監(jiān)牢的瞬間影所,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工僚碎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猴娩,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓勺阐,卻偏偏與公主長得像卷中,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子渊抽,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容