AVPlayer緩存相關(guān)學(xué)習(xí)
AVAssetResourceLoader
AVAssetResourceLoader使用一個(gè)你提供的delegate來(lái)傳達(dá)來(lái)自AVURLAsset的request。當(dāng)一個(gè)request到達(dá)找田,resource loader將詢(xún)問(wèn)delegate号醉,它是否能處理倔撞,然后將結(jié)果返回給asset簸淀。
Overview
不用自己創(chuàng)建resource loader對(duì)象描睦,而是從AVURLAsset的resourceLoader屬性來(lái)取得一個(gè)resource loader宿接,然后使用它分配自定義的delegate對(duì)象宫峦。
delegate對(duì)象必須實(shí)現(xiàn)AVAssetResourceLoaderDelegate協(xié)議
AVURLAsset
AVURLAsset是AVAsset的一個(gè)具體的子類(lèi),用來(lái)通過(guò)一個(gè)本地或者遠(yuǎn)程的URL來(lái)初始化一個(gè)asset荷荤。
AVAsset
AVAsset是一個(gè)抽象的退渗、不可變的類(lèi),用來(lái)表示一個(gè)視頻或者音頻蕴纳。一個(gè)asset可能包含一個(gè)或者多個(gè)想一起呈現(xiàn)的track会油,每一個(gè)media類(lèi)型,包括但不限于音頻古毛、視頻翻翩、文本、閉合字幕稻薇、副標(biāo)題嫂冻。
Overview
AVAsset定義了一個(gè)構(gòu)成asset的track的屬性全集。(你可以access表示track集合的AVAssetTrack實(shí)例颖低,然后有需要的話(huà)絮吵,你可以獨(dú)立的檢查他們)
一般弧烤,你會(huì)用AVURLAsset來(lái)實(shí)例化一個(gè)asset忱屑,AVURLAsset是一個(gè)AVAsset的具體的子類(lèi)蹬敲,它包含一個(gè)指向音視頻資源的URL,資源包括:streams(包含了http live stream)莺戒,QuickTime movie文件伴嗡,MP3文件以及其他類(lèi)型的文件。也可以用其他具體的子類(lèi)實(shí)例化一個(gè)asset从铲,比如用于時(shí)間編輯的AVComposition瘪校。
AVAsset定義了全部的asset的屬性,另外表示track的AVAssetTrack可以被獲取到名段,可以用戶(hù)獨(dú)立去檢查每個(gè)Track阱扬。
由于音視頻媒體的時(shí)間相關(guān)的特性,在成功初始化的時(shí)候伸辟,asset的一些或者全部屬性可能你不會(huì)立刻可用麻惶。對(duì)于任何key的value,可以在任何時(shí)刻請(qǐng)求信夫,然后asset會(huì)以同步的方式返回value窃蹋,所以會(huì)阻塞當(dāng)前調(diào)用的線(xiàn)程。為了避免阻塞静稻,可以注冊(cè)感興趣的key警没,然后當(dāng)value可用時(shí)會(huì)有通知,具體可以查看AVAsynchronousKeyValueLoading振湾。
播放一個(gè)AVAsset杀迹,可以用asset創(chuàng)建一個(gè)AVPlayerItem實(shí)例,使用playerItem來(lái)創(chuàng)建它的展示狀態(tài)(比如是否只有一段有效時(shí)間可以被播放)押搪,然后將player item提供給AVPlayer佛南。
你可以在AVMutableComposition中插入一個(gè)AVAsset,將一個(gè)或者多個(gè)asset資源進(jìn)行整合嵌言。
AVPlayerItem
AVPlayerItem模擬了AVPlayer播放一個(gè)asset的時(shí)間和展示狀態(tài)嗅回。它提供了seek、展示大小摧茴、確定當(dāng)前時(shí)間等功能绵载。
Overview
AVPlayerItem存儲(chǔ)了一個(gè)AVAsset的引用,AVAsset表示一個(gè)待播放的媒體苛白。將這個(gè)媒體入播放隊(duì)列之前娃豹,如果你需要獲得這個(gè)asset的一些信息的話(huà),可以使用AVAsynchronousKeyValueLoading來(lái)獲取你需要的value购裙《妫或者AVPlayerItem可以自動(dòng)讀取需要的asset數(shù)據(jù),只要把希望獲取的key的集合傳遞給它的init(asset:automaticallyLoadedAssetKeys:) 方法躏率。當(dāng)一個(gè)player item準(zhǔn)備好播放的時(shí)候躯畴,這些asset屬性就會(huì)被加載好并且可用民鼓。
AVPlayerItem是一個(gè)動(dòng)態(tài)的對(duì)象。除了它的屬性值都可以被修改之外蓬抄,很多read-only屬性值可以在準(zhǔn)備階段和播放階段丰嘉,被關(guān)聯(lián)的AVPlayer修改。還可以使用KVO來(lái)觀測(cè)狀態(tài)的改變嚷缭。狀態(tài)表明了item是否已經(jīng)準(zhǔn)備好要播放饮亏,是否已經(jīng)可用。第一次創(chuàng)建palyer item阅爽,它的狀態(tài)值是unknown路幸,表明媒體資源還沒(méi)有被加載以及還沒(méi)有被放到播放隊(duì)列里。當(dāng)AVPlayer和player item關(guān)聯(lián)的時(shí)候付翁,item立刻被放入了播放隊(duì)列劝赔,并且準(zhǔn)備播放,但是你需要等待狀態(tài)變?yōu)椤皉eadyToPlay”才可以使用胆敞。下面這段代碼表明了如何注冊(cè)和檢測(cè)狀態(tài)改變着帽。
- (void)prepareToPlay {
NSURL *url = <#Asset URL#>
// Create asset to be played
asset = [AVAsset assetWithURL:url];
NSArray *assetKeys = @[@"playable", @"hasProtectedContent"];
// Create a new AVPlayerItem with the asset and an
// array of asset keys to be automatically loaded
playerItem = [AVPlayerItem playerItemWithAsset:asset
automaticallyLoadedAssetKeys:assetKeys];
NSKeyValueObservingOptions options =
NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew;
// Register as an observer of the player item's status property
[playerItem addObserver:self
forKeyPath:@"status"
options:options
context:&PlayerItemContext];
// Associate the player item with the player
player = [AVPlayer playerWithPlayerItem:playerItem];
}
prepareToPlay方法使用了addObserver:forKeyPath:options:context:來(lái)觀察player item的狀態(tài)變化。這個(gè)方法應(yīng)該在關(guān)聯(lián)player之前調(diào)用移层,以確保你可以抓取到所有的狀態(tài)改變仍翰。
為了接受到狀態(tài)改變的通知,需要實(shí)現(xiàn)observeValueForKeyPath:ofObject:change:context:方法观话。這個(gè)方法在每次狀態(tài)改變的時(shí)候都會(huì)被調(diào)用予借,然后可以采取相應(yīng)的動(dòng)作。
代碼如下:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context {
// Only handle observations for the PlayerItemContext
if (context != &PlayerItemContext) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if ([keyPath isEqualToString:@"status"]) {
AVPlayerItemStatus status = AVPlayerItemStatusUnknown;
// Get the status change from the change dictionary
NSNumber *statusNumber = change[NSKeyValueChangeNewKey];
if ([statusNumber isKindOfClass:[NSNumber class]]) {
status = statusNumber.integerValue;
}
// Switch over the status
switch (status) {
case AVPlayerItemStatusReadyToPlay:
// Ready to Play
break;
case AVPlayerItemStatusFailed:
// Failed. Examine AVPlayerItem.error
break;
case AVPlayerItemStatusUnknown:
// Not ready
break;
}
}
}
這個(gè)例子频蛔,取到了變化字典中的新?tīng)顟B(tài)灵迫,如果player item的狀態(tài)是AVPlayerItemStatusReadyToPlay,那么它就已經(jīng)可以使用晦溪。如果加載資源出錯(cuò)瀑粥,狀態(tài)將會(huì)變成AVPlayerItemStatusFailed。如果你查詢(xún)錯(cuò)誤的屬性三圆,會(huì)得到一個(gè)提供詳細(xì)錯(cuò)誤信息的NSError對(duì)象狞换。
AVPlayer
AVPlayer是一個(gè)用來(lái)管理媒體資源播放和時(shí)間的控制器對(duì)象。它提供了一些控制播放器行為的接口:play舟肉、pause修噪、改變播放速率、seek路媚』魄恚可以使用AVPlayer播放本地和遠(yuǎn)程的資源文件,比如QuickTIme movies和MP3音頻文件整慎,還有HTTP live流的媒體脏款。
Overview
Note
AVPlayer用來(lái)在一個(gè)時(shí)間點(diǎn)播放一個(gè)單獨(dú)的媒體資源围苫。通過(guò)replaceCurrentItem(with:) 方法,player實(shí)例可以復(fù)用弛矛,播放另一個(gè)media asset够吩”热唬框架中還提供了一個(gè)AVPlayer的子類(lèi)丈氓,叫做>AVQueuePlayer,你可以使用它來(lái)創(chuàng)建和管理一個(gè)用于播放一系列媒體資源的隊(duì)列强法。
你可以使用AVPlayer來(lái)播放media assets(AVAsset)万俗,AVAsset只是media的一些靜態(tài)部分的model,比如視頻長(zhǎng)度饮怯、創(chuàng)建時(shí)間闰歪。就其本身而言,不適合直接使用AVPlayer播放蓖墅。為了播放一個(gè)asset库倘,需要先創(chuàng)建一個(gè)asset的動(dòng)態(tài)配對(duì)AVPlayerItem。這個(gè)對(duì)象模擬了一個(gè)asse在AVPlayer播放的時(shí)候的時(shí)間和展示狀態(tài)论矾。
AVPlayer是一個(gè)狀態(tài)不停改變的動(dòng)態(tài)的對(duì)象教翩,有兩種方法來(lái)監(jiān)測(cè)player的狀態(tài)改變
通用的狀態(tài)觀察:使用KVO來(lái)監(jiān)測(cè)player的許多動(dòng)態(tài)屬性的改變,比如當(dāng)前播放item(currentItem)或者它的播放速率贪壳。你需要在主線(xiàn)程注冊(cè)和解除綁定KVO饱亿。這樣可以避免當(dāng)改變來(lái)自其他thread時(shí),只接收到部分通知闰靴。AV Foundation 在主線(xiàn)程調(diào)用observeValue(forKeyPath:of:change:context:)彪笼,即使改變操作發(fā)生在其他線(xiàn)程。
-
時(shí)間狀態(tài)觀察:在通常的狀態(tài)觀察中蚂且,KVO效果不錯(cuò)配猫,但是對(duì)于持續(xù)改變的狀態(tài),比如player的時(shí)間杏死,就不是很好用了章姓。AVPlayer提供了兩個(gè)方法來(lái)觀察時(shí)間的改變:
addPeriodicTimeObserver(forInterval:queue:using:) addBoundaryTimeObserver(forTimes:queue:using:) 這些方法使得你可以周期性的或者邊界性的,觀察時(shí)間的改變识埋。當(dāng)改變發(fā)生時(shí)凡伊,你提供的callback block會(huì)被調(diào)用,你可以再里面做一些響應(yīng)操作窒舟,比如更新用戶(hù)界面的狀態(tài)系忙。
AVPlayer和AVPlayerItem是不可見(jiàn)的對(duì)象,意味著只靠他們自己無(wú)法再屏幕上傳呈現(xiàn)視頻惠豺。你有兩種主要的方法來(lái)呈現(xiàn)視頻:
AVKit:呈現(xiàn)視頻最好的方法就是在iOS和tvOS上使用AVKit框架的AVPlayerViewController或者在macOS上使用AVPlayerView银还。這些類(lèi)提供了視頻內(nèi)容风宁,以及播放控件和其他的媒體特性,給你一個(gè)功能全面的播放體驗(yàn)蛹疯。
AVPlayerLayer:如果你想自己實(shí)現(xiàn)播放界面戒财,你可以使用AVFoundation提供的一個(gè)CALayer的子類(lèi):AVPlayerLayer。player layer可以放在view的layer上或者可以直接加入到layer的層級(jí)當(dāng)中捺弦。不像AVPlayerView和AVPlayerViewController饮寞,player layer并沒(méi)有提供播放控件,但是再屏幕上呈現(xiàn)了視頻內(nèi)容列吼,控制play幽崩、pause、seek的播放控件全部都取決于你自己寞钥。
使用AVKit和AVPlayerLayer的同時(shí)慌申,你可以使用AVSynchronizedLayer來(lái)展現(xiàn)和player的時(shí)間同步的animated content(不明白指什么)。它是一個(gè)特殊的CoreAnimation CALayer的子類(lèi)理郑,that is used to confer the current player timing onto its layer subtree(不明白這句)蹄溉。你可以使用AVSynchronizedLayer來(lái)創(chuàng)建一些自定義的core animation的效果,比如下三分之一動(dòng)畫(huà)或者視頻轉(zhuǎn)場(chǎng)您炉,并且在player播放當(dāng)前AVPlayerItem的同時(shí)柒爵,異步播放。
外部播放模式
Apple TV 相關(guān)邻吭,用不到先不翻譯了餐弱。