AVFoundation 簡單入門二

發表於2016-11-05

在上兩篇文章的基礎上,我們初步認識了AV Foundation框架,並且可以利用它完成一些特定的需求,今天,繼續我們的小小的研究。日進一步,不求速成。

通過了解我們知道,AV Foundation可以用來播放和建立基於時間的音視訊資源,並可以精確的處理基於時間的音視訊媒體資料(查詢、建立、編輯及二次編碼),當然也可以在硬體裝置上獲取實時的視訊輸入流或視訊回放等。AV Foundation可以滿足您對媒體資料的大部分處理。

在處理之前,我們需要大致的瞭解下媒體工程軟體裡的相關類。一個工程檔案中有很多軌道,如音訊軌道1,音訊軌道2 …,視訊軌道1,視訊軌道2等,每個軌道里有許多素材,對於每個視訊素材,它可以進行縮放、旋轉等操作,素材庫中的視訊拖到軌道中會分為視訊軌和音訊軌兩個軌道。大致分為以下幾個:

AVAsset:素材庫裡的素材;
AVAssetTrack:素材的軌道;
AVMutableComposition :一個用來合成視訊的工程檔案;
AVMutableCompositionTrack :工程檔案中的軌道,有音訊軌、視訊軌等,裡面可以插入各種對應的素材;
AVMutableVideoCompositionLayerInstruction:視訊軌道中的一個視訊,可以縮放、旋轉等;
AVMutableVideoCompositionInstruction:一個視訊軌道,包含了這個軌道上的所有視訊素材;
AVMutableVideoComposition:管理所有視訊軌道,可以決定最終視訊的尺寸,裁剪需要在這裡進行;
AVAssetExportSession:配置渲染引數並渲染。

AVAsset

AVFoundation使用AVAsset類來表示一個媒體資源,一個AVAsset例項是一個或多個音視訊媒體資料的集合,是一個抽象類。可以使用子類用URL來建立一個asset物件,也可以基於現有的媒體資源創造一個新的媒體資源。下面是AVAsset中的一些屬性,分別對應著視訊的基本資訊,如時長,建立時間等。

程式碼是最好的老師,建立一個AVAsset:

為了建立一個由URL標識的代表任何資源的assert物件,可以使用AVURLAssert,最簡單的是從檔案裡建立一個assert物件:

AVURLAsset初始化方法的第二個引數使用一個dictionary,這個dictionary裡的唯一一個key是 AVURLAssetPreferPreciseDurationAndTimingKey,它的value是一個boolean型別(用NSValue包裝的物件),這個值表示asset是否提供一個精確的duration。

AVURLAssetPreferPreciseDurationAndTimingKey值為NO(不傳預設為NO),duration會取一個估計值,計算量比較小。反之如果為YES,duration需要返回一個精確值,計算量會比較大,耗時比較長。使用一個預估的duration效率比較高並且對播放來說足夠。如果你想要播放asset,初始化方法傳nil就行了,而不是一個dictionry,或者傳一個以AVURLAssetPreferPreciseDurationAndTimingKeydictionary為key,值為NO的一個dictionary;如果你想把asset加到一個composition中,你需要一個精確的訪問許可權,這時你可以傳一個dictionary,這個dictionary的一組鍵值對為AVURLAssetPreferPreciseDurationAndTimingKey和YES。

從asset中獲取靜態圖片(比如說縮圖),你可以用AVAssetImageGenerator物件。可以用asset初始化一個AVAssetImageGenerator物件,即使asset在初始化的時候沒有可見的track也能成功,所以需要使用tracksWithMediaCharacteristic檢測asset是否有track。generateCGImagesAsynchronouslyForTimes:completionHandler: 方法可以生成一系列圖片,第一個引數是一個包含NSValue型別的陣列,陣列裡每一個物件都是CMTime結構體,表示你想要生成的圖片在視訊中的時間點,第二個引數是一個block,每生成一張圖片都會回撥這個block,這個block提供一個result的引數告訴你圖片是否成功生成或者圖片生成操作是否取消。

AVAssetTrack

一般的視訊至少有2個軌道,一個播放聲音,一個播放畫面。在AVAsset中,可以通過trackId,獲得特定的track。

除了通過trackID獲得track之外,AVAsset中還提供了其他3中方式獲得track:

tracks中包含了當前Asset中的所有track,通過遍歷我們可以獲得想要的track。

-tracksWithMediaType:方法會根據指定的媒體型別返回一個track陣列,陣列中包含著Asset中所有指定媒體型別的track。如果Asset中沒有這個媒體型別的track,返回一個空陣列。AVMediaFormat中一共定義了8種媒體型別: AVMediaTypeVideo、AVMediaTypeAudio、AVMediaTypeText、AVMediaTypeClosedCaption、AVMediaTypeSubtitle、AVMediaTypeTimecode、AVMediaTypeMetadata、AVMediaTypeMuxed。

-tracksWithMediaCharacteristic:方法會根據指定的媒體特徵返回track陣列,陣列的特性與-tracksWithMediaType:類似,如果Asset中沒有這個媒體特徵的track,返回一個空陣列。AVMediaFormat中一共定義了15種媒體特徵: AVMediaTypeMetadataObject、AVMediaCharacteristicVisual、AVMediaCharacteristicAudible、AVMediaCharacteristicLegible、AVMediaCharacteristicFrameBased、AVMediaCharacteristicIsMainProgramContent、AVMediaCharacteristicIsAuxiliaryContent、AVMediaCharacteristicContainsOnlyForcedSubtitles、AVMediaCharacteristicTranscribesSpokenDialogForAccessibility、AVMediaCharacteristicDescribesMusicAndSoundForAccessibility、AVMediaCharacteristicEasyToRead、AVMediaCharacteristicDescribesVideoForAccessibility、AVMediaCharacteristicLanguageTranslation、AVMediaCharacteristicDubbedTranslation、AVMediaCharacteristicVoiceOverTranslation。

程式碼實現:


下面看一個小例:

補充上篇錄製視訊的示例:

相關文章