AVPlayer緩存相關學習


AVAssetResourceLoader

AVAssetResourceLoader使用一個你提供的delegate來傳達來自AVURLAsset的request。當一個request到達,resource loader將詢問delegate,它是否能處理,然后將結果返回給asset。

Overview

不用自己創建resource loader對象,而是從AVURLAsset的resourceLoader屬性來取得一個resource loader,然后使用它分配自定義的delegate對象。
delegate對象必須實現AVAssetResourceLoaderDelegate協議

AVURLAsset

AVURLAsset是AVAsset的一個具體的子類,用來通過一個本地或者遠程的URL來初始化一個asset。

AVAsset

AVAsset是一個抽象的、不可變的類,用來表示一個視頻或者音頻。一個asset可能包含一個或者多個想一起呈現的track,每一個media類型,包括但不限於音頻、視頻、文本、閉合字幕、副標題。

Overview

AVAsset定義了一個構成asset的track的屬性全集。(你可以access表示track集合的AVAssetTrack實例,然后有需要的話,你可以獨立的檢查他們)
一般,你會用AVURLAsset來實例化一個asset,AVURLAsset是一個AVAsset的具體的子類,它包含一個指向音視頻資源的URL,資源包括:streams(包含了http live stream),QuickTime movie文件,MP3文件以及其他類型的文件。也可以用其他具體的子類實例化一個asset,比如用於時間編輯的AVComposition。

AVAsset定義了全部的asset的屬性,另外表示track的AVAssetTrack可以被獲取到,可以用戶獨立去檢查每個Track。

由於音視頻媒體的時間相關的特性,在成功初始化的時候,asset的一些或者全部屬性可能你不會立刻可用。對於任何key的value,可以在任何時刻請求,然后asset會以同步的方式返回value,所以會阻塞當前調用的線程。為了避免阻塞,可以注冊感興趣的key,然后當value可用時會有通知,具體可以查看AVAsynchronousKeyValueLoading。

播放一個AVAsset,可以用asset創建一個AVPlayerItem實例,使用playerItem來創建它的展示狀態(比如是否只有一段有效時間可以被播放),然后將player item提供給AVPlayer。

你可以在AVMutableComposition中插入一個AVAsset,將一個或者多個asset資源進行整合。

AVPlayerItem

AVPlayerItem模擬了AVPlayer播放一個asset的時間和展示狀態。它提供了seek、展示大小、確定當前時間等功能。

Overview

AVPlayerItem存儲了一個AVAsset的引用,AVAsset表示一個待播放的媒體。將這個媒體入播放隊列之前,如果你需要獲得這個asset的一些信息的話,可以使用AVAsynchronousKeyValueLoading來獲取你需要的value。或者AVPlayerItem可以自動讀取需要的asset數據,只要把希望獲取的key的集合傳遞給它的init(asset:automaticallyLoadedAssetKeys:) 方法。當一個player item准備好播放的時候,這些asset屬性就會被加載好並且可用。

AVPlayerItem是一個動態的對象。除了它的屬性值都可以被修改之外,很多read-only屬性值可以在准備階段和播放階段,被關聯的AVPlayer修改。還可以使用KVO來觀測狀態的改變。狀態表明了item是否已經准備好要播放,是否已經可用。第一次創建palyer item,它的狀態值是unknown,表明媒體資源還沒有被加載以及還沒有被放到播放隊列里。當AVPlayer和player item關聯的時候,item立刻被放入了播放隊列,並且准備播放,但是你需要等待狀態變為“readyToPlay”才可以使用。下面這段代碼表明了如何注冊和檢測狀態改變。

- (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:來觀察player item的狀態變化。這個方法應該在關聯player之前調用,以確保你可以抓取到所有的狀態改變。

為了接受到狀態改變的通知,需要實現observeValueForKeyPath:ofObject:change:context:方法。這個方法在每次狀態改變的時候都會被調用,然后可以采取相應的動作。
代碼如下:

- (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;
        }
    }
}

這個例子,取到了變化字典中的新狀態,如果player item的狀態是AVPlayerItemStatusReadyToPlay,那么它就已經可以使用。如果加載資源出錯,狀態將會變成AVPlayerItemStatusFailed。如果你查詢錯誤的屬性,會得到一個提供詳細錯誤信息的NSError對象。

AVPlayer

AVPlayer是一個用來管理媒體資源播放和時間的控制器對象。它提供了一些控制播放器行為的接口:play、pause、改變播放速率、seek。可以使用AVPlayer播放本地和遠程的資源文件,比如QuickTIme movies和MP3音頻文件,還有HTTP live流的媒體。

Overview

Note
AVPlayer用來在一個時間點播放一個單獨的媒體資源。通過replaceCurrentItem(with:) 方法,player實例可以復用,播放另一個media asset。框架中還提供了一個AVPlayer的子類,叫做>AVQueuePlayer,你可以使用它來創建和管理一個用於播放一系列媒體資源的隊列。

你可以使用AVPlayer來播放media assets(AVAsset),AVAsset只是media的一些靜態部分的model,比如視頻長度、創建時間。就其本身而言,不適合直接使用AVPlayer播放。為了播放一個asset,需要先創建一個asset的動態配對AVPlayerItem。這個對象模擬了一個asse在AVPlayer播放的時候的時間和展示狀態。

AVPlayer是一個狀態不停改變的動態的對象,有兩種方法來監測player的狀態改變

  • 通用的狀態觀察:使用KVO來監測player的許多動態屬性的改變,比如當前播放item(currentItem)或者它的播放速率。你需要在主線程注冊和解除綁定KVO。這樣可以避免當改變來自其他thread時,只接收到部分通知。AV Foundation 在主線程調用observeValue(forKeyPath:of:change:context:),即使改變操作發生在其他線程。

  • 時間狀態觀察:在通常的狀態觀察中,KVO效果不錯,但是對於持續改變的狀態,比如player的時間,就不是很好用了。AVPlayer提供了兩個方法來觀察時間的改變:

      addPeriodicTimeObserver(forInterval:queue:using:)
      addBoundaryTimeObserver(forTimes:queue:using:)
      這些方法使得你可以周期性的或者邊界性的,觀察時間的改變。當改變發生時,你提供的callback block會被調用,你可以再里面做一些響應操作,比如更新用戶界面的狀態。
    

AVPlayer和AVPlayerItem是不可見的對象,意味着只靠他們自己無法再屏幕上傳呈現視頻。你有兩種主要的方法來呈現視頻:

AVKit:呈現視頻最好的方法就是在iOS和tvOS上使用AVKit框架的AVPlayerViewController或者在macOS上使用AVPlayerView。這些類提供了視頻內容,以及播放控件和其他的媒體特性,給你一個功能全面的播放體驗。

AVPlayerLayer:如果你想自己實現播放界面,你可以使用AVFoundation提供的一個CALayer的子類:AVPlayerLayer。player layer可以放在view的layer上或者可以直接加入到layer的層級當中。不像AVPlayerView和AVPlayerViewController,player layer並沒有提供播放控件,但是再屏幕上呈現了視頻內容,控制play、pause、seek的播放控件全部都取決於你自己。

使用AVKit和AVPlayerLayer的同時,你可以使用AVSynchronizedLayer來展現和player的時間同步的animated content(不明白指什么)。它是一個特殊的CoreAnimation CALayer的子類,that is used to confer the current player timing onto its layer subtree(不明白這句)。你可以使用AVSynchronizedLayer來創建一些自定義的core animation的效果,比如下三分之一動畫或者視頻轉場,並且在player播放當前AVPlayerItem的同時,異步播放。

外部播放模式

Apple TV 相關,用不到先不翻譯了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM