IOS音視頻(一)AVFoundation核心類 1. AVFoundation框架架構簡介 1.1 AVFoundation框架 1.2 AVFoundation 之 Assets 1.3 AVFoundation 之 視頻播放 1.3.1 AVPlayer 1.3.2 播放不同類型的資源 1.3.3 播放控制 1.3.4 自定義播放--音頻 1.3.4.1 AVAudioMix 1.3.4.2 AVMutableAudioMix 1.3.4.3 AVAudioMixInputParameters 1.3.4.4 AVMutableAudioMixInputParameters 1.3.5 自定義播放--視頻 1.3.5.1 AVVideoComposition 1.3.5.2 AVMutableVideoComposition 1.3.5.3 AVVideoCompositionInstruction 1.3.5.4 AVMutableVideoCompositionInstruction 1.3.5.5 AVVideoCompositionLayerInstruction 1.3.5.6 AVMutableVideoCompositionLayerInstruction 1.3.5.7 AVVideoCompositionCoreAnimationTool 1.3.5.8 AVVideoCompositionValidationHandling 1.3.5.9 AVVideoCompositionValidationHandling 1.4 AVFoundation 之 視音頻編輯 1.4.1 AVAssetExportSession 1.4.2 AVComposition 1.4.3 AVMutableComposition 1.4.4 AVCompositionTrack 1.4.5 AVMutableCompositionTrack 1.4.6 AVAssetTrackSegment 1.4.7 AVCompositionTrackSegment 1.5 AVFoundation 之 視音頻媒體捕獲 1.5.1 AVCaptureSession 1.5.2 AVCaptureDevice 1.5.3 AVCaptureDeviceInput 1.5.4 AVCaptureOutput 1.5.5 AVCaptureFileOutput 1.5.6 AVCaptureFileOutputRecordingDelegate 1.5.7 AVCaptureFileOutputDelegate 1.5.8 AVCaptureAudioFileOutput 1.5.9 AVCaptureVideoDataOutput 1.5.10 AVCaptureVideoDataOutputSampleBufferDelegate 1.5.11 AVCaptureVideoPreviewLayer 1.5.12 AVCaptureAudioDataOutput 1.5.13 AVCaptureAudioDataOutputSampleBufferDelegate 1.5.14 AVAssetImageGenerator 1.6 AVFoundation 之媒體流輸出 1.6.1 AVAssetReader 1.6.2 AVAssetReaderOutput 1.6.3 AVAssetReaderTrackOutput 1.6.4 AVAssetReaderAudioMixOutput 1.6.5 AVAssetReaderVideoCompositionOutput 1.7 AVFoundation 之媒體的時間和數據
做音視頻開發是個很復雜的工作,需要我們理解很多有關素材的知識:聲學和視覺相關的科學理論,數的程序開發技術和有AVFoundation框架而引出的其他框架的知識,比如:Core Media, Core Video, Core Image, Core Audio, Media Player 和 VideoToolbox 等等。
要做IOS音視頻相關的開發,肯定要熟悉AVFoundation框架。學習框架最好的方式就是研究蘋果官方文檔:蘋果官方AVFoundation框架介紹
AVFoundation 是 Objective-C 中創建及編輯視聽媒體文件的幾個框架之一,其提供了檢查、創建、編輯或重新編碼媒體文件的接口,也使得從設備獲取的視頻實時數據可操縱。但是,通常情況,簡單的播放或者錄像,直接使用 AVKit 框架或者 UIImagePickerController 類即可。另外,值得注意的是,在 AVFoundation 框架中使用的基本數據結構,如時間相關的或描述媒體數據的數據結構都聲明在 CoreMedia 框架中。
AVFoundation 是 OSX 系統和 iOS 系統中用于處理基于時間的媒體數據的高級 objectivec 框架,其設計過程高度依賴多線程機制,充分利用了多核硬件優勢,大量使用 Block 和 GCD 機制。AVFoundation 能與高層級框架無縫銜接,也能提供低層級框架的功能和性能。
1. AVFoundation框架架構簡介
Core Audio是OS X和IOS系統上處理所有音頻 事件的框架。Core Audio是有多高框架整合在一起的總稱,為音頻和MIDI內容的錄制,播放和處理提供相應的接口。Core Audio也提供高級的接口,比如通過Audio Queue Services框架所提供的那些接口,主要處理基本的音頻播放和錄音相關功能。同時還會提供相對低層級的接口,尤其是Audio Units接口,它們提供了針對音頻信號進行完全控制的功能,并通過Audio Units讓你能夠構建一些復雜的音頻處理模式,就像通過蘋果公司的Logic Pro X和Avid’s Pro Tolls工具所實現的功能一樣。
Core Video是OS X 和IOS系統上針對數字視頻所提供的管道模式。Core Video為其相對的Core Media提供圖片緩存和緩存支持,提供了一個能夠對數字視頻逐幀訪問的接口。該框架通過像素格式之間的轉換并管理同步事項時的復雜的工作得到了有效簡化。
Core Media 是AV Foundation所用到的低層級媒體管道的一部分。它提供針對音頻樣本和視頻幀處理所需的低層級數據類型和接口。Core Media還提供了AV Foundation用的的基于CMTime數據類型的時間模型。CMTime及其相關數據類型一般在AV Foundation處理基于時間的操作時使用。
Core Animation時OS X和 iOS 提供的合成及動畫相關框架。主要功能就是提供蘋果平臺所具有的美觀,流暢的動畫效果。提供了一個簡單,聲明行的編程模式,并已經封裝了支持OpenGL 和OpenGL ES 功能的基于Object-C的各種類。使用Core Animation時,對于食品內容的播放和視頻捕獲這兩個動作,AVFoundation 提供了硬件加速機制來對整個流程進行優化。AVFoundation 還可以利用Core Animation讓開發者能夠在視頻編輯和播放過程中添加動畫標題和圖片效果。
蘋果提供了AVFoundation框架,可以用來檢測,編輯,創建,重新編碼媒體文件,還可以實時獲取設備的流媒體數據,實時操作這些被捕獲的視頻流數據。 蘋果推薦我們盡可能的使用高度抽象的接口:
如果只是簡單播放視頻文件,使用AVKit框架即可。 如果只是想簡單錄制視頻,使用UIKit框架里的UIImagePickerController既可以實現。
AVFoundation 框架包含視頻相關的接口以及音頻相關的接口,與音頻相關的類有 AVAudioPlayer、AVAudioRecorder、AVAudioSession。
1.1 AVFoundation框架
AVFoundation 提供的核心功能如下所示
音頻播放和記錄——AVAudioPlayer 和 AVAudioRecorder 媒體文件檢查——AVMetadataItem 視頻播放——AVPlayer 和 AVPlayerItem 媒體捕捉——AVCaptureSession 媒體編輯 媒體處理——AVAssetReader、AVAssetWriter
AVFoundation 框架中最基本的類是 AVAsset ,它是一個或者多個媒體數據的集合,描述的是整個集合的屬性,如標題、時長、大小等,并且沒有特定的數據格式。集合的每一個媒體數據都是統一的數據類型,稱之為 track。簡單的情況是一種數據是音頻數據,一種是視頻數據,而較復雜的情況是一種數據交織著音頻和視頻數據,并且 AVAsset 是可能有元數據的。 另外,需要明白的是在 AVFoundation 中,初始化了 asset 及 track 后,并不意味著資源已經可用,因為若資源本身并不攜帶自身信息時,那么系統需要自己計算相關信息,這個過程會阻塞線程,所以應該使用異步方式進行獲取資源信息后的操作。
AVFoundation 中可以使用 compositions 將多個媒體數據(video/audio tracks)合成為一個 asset ,這個過程中,可以添加或移除 tracks ,調整它們的順序,或者設置音頻的音量和變化坡度,視頻容量等屬性。這些媒體數據的集合保存在內存中,直到使用 export session 將它導出到本地文件中。另外,還可以使用 asset writer 創建 asset 。
使用 capture session 協調從設備(如相機、麥克風)輸入的數據和輸出目標(如視頻文件)。可以為 session 設置多個輸入和輸出,即使它正在工作,還可以通過它停止數據的流動。另外,還可以使用 preview layer 將相機記錄的影像實時展示給用戶。
在 AVFoundation 中的回調處理并不保證回調任務在某個特定的線程或隊列中執行,其遵循兩個原則,UI 相關的操作在主線程中執行,其他回調需要為其指定調用的隊列。
1.2 AVFoundation 之 Assets
參考蘋果官方介紹
AVAsset 是AVFoundation框架里的一個核心類,主要提供了一種形式獨立的基于時間的視聽數據抽象,例如電影文件或視頻流。
AVAsset 包含需要一起呈現或處理的音軌集合,每個音軌都是統一的媒體類型,包括(但不限于)音頻、視頻、文本、封閉字幕和字幕。asset對象提供關于整個資源的信息,比如它的持續時間或標題,以及表示的提示,比如它的大小。AVAsset 也可以有元數據,由AVMetadataItem的實例表示。
跟蹤由AVAssetTrack的實例表示,在一個典型的簡單例子中,一個軌道表示音頻組件,另一個表示視頻組件;在一個復雜的組合中,音頻和視頻可能會有多個重疊的音軌。
音軌具有許多屬性,例如其類型(視頻或音頻)、可視和/或可聽特征(視情況而定)、元數據和時間軸(以其父資產的形式表示)。磁道也有一組格式說明。數組包含CMFormatDescription對象(參見CMFormatDescriptionRef),每個對象描述曲目引用的媒體樣本的格式。包含統一媒體的磁道(例如,所有使用相同設置編碼的磁道)將提供一個計數為1的數組。
一個磁道本身可以被分割成段,用AVAssetTrackSegment的實例來表示。段是從源到資產跟蹤時間線的時間映射。
CMTime是一個C結構,它將時間表示為一個有理數,具有一個分子(int64_t值)和一個分母(int32_t時間刻度)。從概念上講,時間刻度指定了分子中每個單位所占的秒數。因此,如果時間刻度是4,每個單元代表四分之一秒;如果時間刻度是10,每個單元表示十分之一秒,以此類推。您經常使用600的時間刻度,因為這是幾種常用幀率的倍數:24幀用于電影,30幀用于NTSC(用于北美和日本的電視),25幀用于PAL(用于歐洲的電視)。使用600的時間刻度,您可以精確地表示這些系統中的任意數量的幀。除了簡單的時間值之外,CMTime結構還可以表示非數值:+∞、-∞和不定。它還可以指示時間是否在某個點被四舍五入,并保持一個歷元數。
您可以使用CMTimeMake或CMTimeMakeWithSeconds等相關函數之一創建時間(該函數允許您使用浮點值創建時間并指定首選時間刻度)。有幾個函數用于基于時間的算術和比較時間,如下例所示:
CMTime time1
= CMTimeMake ( 200 , 2 ) ;
CMTime time2
= CMTimeMake ( 400 , 4 ) ;
if ( CMTimeCompare ( time1
, time2
) == 0 ) { NSLog ( @
"time1 and time2 are the same" ) ;
} Float64 float64Seconds
= 200.0 / 3 ;
CMTime time3
= CMTimeMakeWithSeconds ( float64Seconds
, 3 ) ;
time3
= CMTimeMultiply ( time3
, 3 ) ;
time3
= CMTimeSubtract ( time3
, time1
) ;
CMTimeShow ( time3
) ; if ( CMTIME_COMPARE_INLINE ( time2
, == , time3
) ) { NSLog ( @
"time2 and time3 are the same" ) ;
}
AVFoundation 提供了多種方法來創建 asset ,可以簡單的重編碼已經存在的 asset ,這個過程可以使用 export session 或者使用 asset reader 和 asset writer 。 若要生成視頻的縮略圖,可以使用 asset 初始化一個 AVAssetImageGenerator 實例對象,它會使用默認可用的視頻 tracks 來生成圖片。 創建 AVAsset 或其子類 AVURLAsset 時,需要提供資源的位置,方法如下:
NSURL * url
= < #視聽資源的
URL ,可以是本地文件地址,也可以是網頁媒體鏈接#
> ;
AVURLAsset * anAsset
= [ [ AVURLAsset alloc
] initWithURL
: url options
: nil ] ;
上述方法的第二個參數是創建對象時的選擇項,其中可能包含的選擇項如下:
AVURLAssetPreferPreciseDurationAndTimingKey 是否需要資源的準確時長,及訪問資源各個準確的時間點 AVURLAssetReferenceRestrictionsKey 鏈接其他資源的約束 AVURLAssetHTTPCookiesKey 添加資源能夠訪問的 HTTP cookies AVURLAssetAllowsCellularAccessKey 是否能夠使用蜂窩網絡
創建并初始化一個 AVAsset 實例對象后,并不意味著該對象的所有屬性都可以獲取使用了,因為其中的一些屬性需要額外的計算才能夠得到,那么當獲取這些屬性時,可能會阻塞當前線程,所以需要異步獲取這些屬性。 AVAsset 與 AVAssetTrack 都遵循 AVAsynchronousKeyValueLoading 協議,這個協議中有以下兩個方法:
- ( AVKeyValueStatus ) statusOfValueForKey
: ( NSString * ) key error
: ( NSError * _Nullable
* _Nullable
) outError
;
- ( void
) loadValuesAsynchronouslyForKeys
: ( NSArray < NSString * > * ) keys completionHandler
: ( nullable void
( ^ ) ( void
) ) handler
;
通常,我們使用上述第二個方法異步加載想要的屬性,而后在加載完成的回調 block 中使用第一個方法判斷屬性是否加載成功,然后訪問想要的屬性,執行自己的操作,如下代碼:
NSURL * url
= < #資源路徑#
> ;
AVURLAsset * anAsset
= [ [ AVURLAsset alloc
] initWithURL
: url options
: nil ] ;
NSArray * keys
= @
[ @
"duration" , @
"tracks" ] ; [ asset loadValuesAsynchronouslyForKeys
: keys completionHandler
: ^ ( ) { NSError * error
= nil ; AVKeyValueStatus tracksStatus
= [ asset statusOfValueForKey
: @
"tracks" error
: & error
] ; switch ( tracksStatus
) { case AVKeyValueStatusUnknown : break ; case AVKeyValueStatusLoading : break ; case AVKeyValueStatusLoaded : break ; case AVKeyValueStatusFailed : break ; case AVKeyValueStatusCancelled : break ; }
} ] ;
1.3 AVFoundation 之 視頻播放
1.3.1 AVPlayer
具體可以參考蘋果官方介紹的Playback章節
要控制媒體資源的回放,可以使用AVPlayer對象。在回放期間,您可以使用AVPlayerItem實例來管理整個Asset的表示狀態,使用AVPlayerItemTrack對象來管理單個曲目的表示狀態。要顯示視頻,可以使用AVPlayerLayer對象。
player是一個控制器對象,您可以使用它來管理資產的回放,例如啟動和停止回放,以及查找特定的時間。您使用AVPlayer實例來播放單個資產。您可以使用AVQueuePlayer對象按順序播放許多項(AVQueuePlayer是AVPlayer的子類)。在OS X上,你可以選擇使用AVKit框架的AVPlayerView類來回放視圖中的內容。
播放器向您提供有關播放狀態的信息,因此,如果需要,您可以將用戶界面與播放器的狀態同步。通常將播放器的輸出定向到特定的核心動畫層(AVPlayerLayer或AVSynchronizedLayer的實例)。有關層的更多信息,請參見Core Animation Programming Guide。
盡管最終你想要播放資產,但你不能直接提供資產給AVPlayer 對象。而是提供AVPlayerItem的一個實例。播放器項管理與其相關聯的資產的表示狀態。播放器項包含播放器項跟蹤—avplayeritemtrack的實例—對應于資產中的跟蹤。各對象之間的關系如圖所示:
這種抽象意味著您可以同時使用不同的玩家來玩給定的資產,但是每個玩家呈現的方式不同。圖2-2顯示了一種可能性,即兩個不同的玩家使用不同的設置來玩相同的資產。例如,使用項曲目,您可以在回放期間禁用特定的曲目(例如,您可能不想播放聲音組件)。
您可以使用現有資產初始化播放器項,也可以直接從URL初始化播放器項,以便在特定位置播放資源(AVPlayerItem將隨后為資源創建和配置資產)。不過,與AVAsset一樣,簡單地初始化播放器項并不一定意味著它可以立即播放。您可以觀察(使用鍵值觀察)一個項目的狀態屬性來確定它是否準備好了,以及何時準備好了。
使用一個 AVPlayer 類實例可以管理一個 asset 資源,但是它的屬性 currentItem 才是 asset 的實際管理者。currentItem 是 AVPlayerItem 類的實例,而它的屬性 tracks 包含著的 AVPlayerItemTracker 實例對應著 asset 中的各個 track 。
那么,為了控制 asset 的播放,可以使用 AVPlayer 類,在播放的過程中,可以使用 AVPlayerItem 實例管理整個 asset 的狀態,使用 AVPlayerItemTracker 對象管理 asset 中每個 track 的狀態。另外,還可以使用 AVPlayerLayer 類來顯示播放的內容。
所以,在創建 AVPlayer 實例對象時,除了可以直接傳遞資源文件的路徑進行創建外,還可以傳遞 AVPlayerItem 的實例對象,如下方法:
+ ( instancetype
) playerWithURL
: ( NSURL * ) URL ;
+ ( instancetype
) playerWithPlayerItem
: ( nullable
AVPlayerItem * ) item
;
- ( instancetype
) initWithURL
: ( NSURL * ) URL ;
- ( instancetype
) initWithPlayerItem
: ( nullable
AVPlayerItem * ) item
;
創建后,并不是可以直接使用,還要對它的狀態進行檢查,只有 status 的值為 AVPlayerStatusReadyToPlay 時,才能進行播放,所以這里需要使用 KVO 模式對該狀態進行監控,以決定何時可以進行播放。 若要管理多個資源的播放,則應使用 AVPlayer 的子類 AVQueuePlayer ,這個子類擁有的多個 AVPlayerItem 同各個資源相對應。
1.3.2 播放不同類型的資源
對于播放不同類型的資源,需要進行的準備工作有所不同,這主要取決于資源的來源。資源數據可能來自本地設備上文件的讀取,也可能來自網絡上數據流。 對于本地文件,可以使用文件地址創建 AVAsset 對象,而后使用該對象創建 AVPlayerItem 對象,最后將這個 item 對象與 AVPlayer 對象相關聯。之后,便是等待 status 的狀態變為 AVPlayerStatusReadyToPlay ,便可以進行播放了。 對于網絡數據的播放,不能使用地址創建 AVAsset 對象了,而是直接創建 AVPlayerItem 對象,將其同 AVPlayer 對象相關聯,當 status 狀態變為 AVPlayerStatusReadyToPlay 后,AVAsset 和 AVAssetTrack 對象將由 item 對象創建。
1.3.3 播放控制
通過調用 player 的 play 、pause 、setRate: 方法,可以控制 item 的播放,這些方法都會改變 player 的屬性 rate 的值,該值為 1 表示 item 按正常速率播放,為 0 表示 item 暫停播放,0~1 表示低速播放,大于 1 表示高速播放,小于 0 表示從后向前播放。 item 的屬性 timeControlStatus 的值表示當前 item 的狀態,有下面 3 個值:
AVPlayerTimeControlStatusPaused 暫停 AVPlayerTimeControlStatusPlaying 播放 AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate 等待按指定速率播放狀態,該狀態是當 rate 的值設置為非 0 值時,而 item 因某些原因還無法播放的情況,而無法播放的原因,可依通過 item 的 reasonForWaitingToPlay 屬性值查看。
item 的屬性 actionAtItemEnd 的值表示當前 item 播放結束后的動作,有下面 3 個值:
AVPlayerActionAtItemEndAdvance 只適用于 AVQueuePlayer 類,表示播放隊列中的下一個 item AVPlayerActionAtItemEndPause 表示暫停 AVPlayerActionAtItemEndNone 表示無操作,當前 item 的 currentTime 屬性值仍然按 rate 的值改變 item 的 currentTime 屬性值表示當前 item 的播放時間,可以調用下面的方法指定 item 從何處進行播放。
- ( void
) seekToDate
: ( NSDate * ) date
;
- ( void
) seekToTime
: ( CMTime ) time toleranceBefore
: ( CMTime ) toleranceBefore toleranceAfter
: ( CMTime ) toleranceAfter
; ( tolerance
: 公差,前后公差
)
- ( void
) seekToTime
: ( CMTime ) time completionHandler
: ( void
( ^ ) ( BOOL finished
) ) completionHandler
NS_AVAILABLE ( 10_7 , 5_0 ) ;
- ( void
) seekToTime
: ( CMTime ) time toleranceBefore
: ( CMTime ) toleranceBefore toleranceAfter
: ( CMTime ) toleranceAfter completionHandler
: ( void
( ^ ) ( BOOL finished
) ) completionHandler
NS_AVAILABLE ( 10_7 , 5_0 ) ;
使用 AVQueuePlayer 管理多個 item 的播放,仍然可以通過調用 play 開始依次播放 item,調用 advanceToNextItem 方法播放下一個 item ,還可以通過下面的方法添加或移除 item 。
- ( BOOL ) canInsertItem
: ( AVPlayerItem * ) item afterItem
: ( nullable
AVPlayerItem * ) afterItem
;
- ( void
) insertItem
: ( AVPlayerItem * ) item afterItem
: ( nullable
AVPlayerItem * ) afterItem
;
- ( void
) removeItem
: ( AVPlayerItem * ) item
;
- ( void
) removeAllItems
;
可以使用下面的方法監聽播放時間的變化,需要強引用這兩個方法返回的監聽者。
- ( id
) addPeriodicTimeObserverForInterval
: ( CMTime ) interval queue
: ( nullable dispatch_queue_t
) queue usingBlock
: ( void
( ^ ) ( CMTime time
) ) block
;
- ( id
) addBoundaryTimeObserverForTimes
: ( NSArray < NSValue * > * ) times queue
: ( nullable dispatch_queue_t
) queue usingBlock
: ( void
( ^ ) ( void
) ) block
;
用上面的方法每注冊一個監聽者,就需要對應的使用下面的方法進行注銷,并且在注銷之前,要確保沒有 block 被執行。- (void)removeTimeObserver:(id)observer; 當 item 播放結束后,再次調用 player 的方法 play 不會使 item 重新播放,要實現重播,可以注冊一個 AVPlayerItemDidPlayToEndTimeNotification 通知,當接收到這個通知時,可以調 seekToTime: 方法,傳入 kCMTimeZero 參數,將 player 的播放時間重置。
1.3.4 自定義播放–音頻
要在媒體資源播放的過程中實現音頻的自定義播放,需要用 AVMutableAudioMix 對不同的音頻進行編輯。這個類的實例對象的屬性 inputParameters 是音量描述對象的集合,每個對象都是對一個 audio track 的音量變化的描述,如下:
AVMutableAudioMix * mutableAudioMix
= [ AVMutableAudioMix audioMix
] ; AVMutableAudioMixInputParameters * mixParameters1
= [ AVMutableAudioMixInputParameters audioMixInputParametersWithTrack
: compositionAudioTrack1
] ;
[ mixParameters1 setVolumeRampFromStartVolume
: 1 . f toEndVolume
: 0 . f timeRange
: CMTimeRangeMake ( kCMTimeZero , mutableComposition
. duration
/ 2 ) ] ;
[ mixParameters1 setVolumeRampFromStartVolume
: 0 . f toEndVolume
: 1 . f timeRange
: CMTimeRangeMake ( mutableComposition
. duration
/ 2 , mutableComposition
. duration
) ] ; AVMutableAudioMixInputParameters * mixParameters2
= [ AVMutableAudioMixInputParameters audioMixInputParametersWithTrack
: compositionAudioTrack2
] ;
[ mixParameters2 setVolumeRampFromStartVolume
: 1 . f toEndVolume
: 0 . f timeRange
: CMTimeRangeMake ( kCMTimeZero , mutableComposition
. duration
) ] ; mutableAudioMix
. inputParameters
= @
[ mixParameters1
, mixParameters2
] ;
1.3.4.1 AVAudioMix
該類中有一個屬性 inputParameters ,它是 AVAudioMixInputParameters 實例對象的集合,每個實例都是對音頻播放方式的描述。可見,AVAudioMix 并不直接改變音頻播放的方式,其只是存儲了音頻播放的方式。
1.3.4.2 AVMutableAudioMix
AVMutableAudioMix 是 AVAudioMix 的子類,它的方法 audioMix 返回一個 inputParameters 屬性為空的實例。
1.3.4.3 AVAudioMixInputParameters
這個類是音量變化的描述類,它同一個音頻的 track 相關聯,并設置音量隨時間變化的算法,其獲取音量變化的方法如下:
- ( BOOL ) getVolumeRampForTime
: ( CMTime ) time startVolume
: ( nullable float
* ) startVolume endVolume
: ( nullable float
* ) endVolume timeRange
: ( nullable
CMTimeRange * ) timeRange
;
1.3.4.4 AVMutableAudioMixInputParameters
AVMutableAudioMixInputParameters 是 AVAudioMixInputParameters 的子類,它提供了直接設置某個時刻或時間段的音量的方法。
+ ( instancetype
) audioMixInputParametersWithTrack
: ( nullable
AVAssetTrack * ) track
;
+ ( instancetype
) audioMixInputParameters
;
- ( void
) setVolumeRampFromStartVolume
: ( float
) startVolume toEndVolume
: ( float
) endVolume timeRange
: ( CMTimeRange ) timeRange
;
- ( void
) setVolume
: ( float
) volume atTime
: ( CMTime ) time
;
1.3.5 自定義播放–視頻
同音頻的自定義播放一樣,要實現視頻的自定義播放,僅僅將視頻資源集合到一起是不夠的,需要使用 AVMutableVideoComposition 類來定義不同的視頻資源在不同的時間范圍內的播放方式。
1.3.5.1 AVVideoComposition
AVVideoComposition 是 AVMutableVideoComposition 的父類,它的主要屬性和方法如下:
@property
( nonatomic
, readonly
, nullable
) Class < AVVideoCompositing > customVideoCompositorClass
NS_AVAILABLE ( 10_9 , 7_0 ) ;
@property
( nonatomic
, readonly
) CMTime frameDuration
;
@property
( nonatomic
, readonly
) CGSize renderSize
;
@property
( nonatomic
, readonly
) float renderScale
;
@property
( nonatomic
, readonly
, copy
) NSArray < id
< AVVideoCompositionInstruction > > * instructions
;
@property
( nonatomic
, readonly
, retain
, nullable
) AVVideoCompositionCoreAnimationTool * animationTool
;
+ ( AVVideoComposition * ) videoCompositionWithPropertiesOfAsset
: ( AVAsset * ) asset
NS_AVAILABLE ( 10_9 , 6_0 ) ;
@property
( nonatomic
, readonly
, nullable
) NSString * colorPrimaries
NS_AVAILABLE ( 10_12 , 10_0 ) ;
@property
( nonatomic
, readonly
, nullable
) NSString * colorYCbCrMatrix
NS_AVAILABLE ( 10_12 , 10_0 ) ;
@property
( nonatomic
, readonly
, nullable
) NSString * colorTransferFunction
NS_AVAILABLE ( 10_12 , 10_0 ) ;
+ ( AVVideoComposition * ) videoCompositionWithAsset
: ( AVAsset * ) assetapplyingCIFiltersWithHandler
: ( void
( ^ ) ( AVAsynchronousCIImageFilteringRequest * request
) ) applier
NS_AVAILABLE ( 10_11 , 9_0 ) ;
1.3.5.2 AVMutableVideoComposition
AVMutableVideoComposition 是 AVVideoComposition 的可變子類,它繼承父類的屬性可以改變,并且新增了下面的創建方法。
+ ( AVMutableVideoComposition * ) videoComposition
;
1.3.5.3 AVVideoCompositionInstruction
在上述的兩個類中,真正包含有視頻播放方式信息的是 instructions 屬性,這個集合中的對象都遵循 AVVideoCompositionInstruction 協議,若不使用自定義的類,那么可以使用 AVFoundation 框架中的 AVVideoCompositionInstruction 類。 該類的相關屬性如下:
@property
( nonatomic
, readonly
) CMTimeRange timeRange
;
@property
( nonatomic
, readonly
, retain
, nullable
) __attribute__ ( ( NSObject ) ) CGColorRef backgroundColor
;
@property
( nonatomic
, readonly
, copy
) NSArray < AVVideoCompositionLayerInstruction * > * layerInstructions
;
@property
( nonatomic
, readonly
) BOOL enablePostProcessing
;
@property
( nonatomic
, readonly
) NSArray < NSValue * > * requiredSourceTrackIDs
NS_AVAILABLE ( 10_9 , 7_0 ) ;
@property
( nonatomic
, readonly
) CMPersistentTrackID passthroughTrackID
NS_AVAILABLE ( 10_9 , 7_0 ) ;
1.3.5.4 AVMutableVideoCompositionInstruction
AVMutableVideoCompositionInstruction 是 AVVideoCompositionInstruction 的子類,其繼承的父類的屬性可進行修改,并且提供了創建屬性值為 nil 或無效的實例的方法。
+ ( instancetype
) videoCompositionInstruction
;
1.3.5.5 AVVideoCompositionLayerInstruction
AVVideoCompositionLayerInstruction 是對給定的視頻資源的不同播放方式進行描述的類,通過下面的方法,可以獲取仿射變化、透明度變化、裁剪區域變化的梯度信息。
- ( BOOL ) getTransformRampForTime
: ( CMTime ) time startTransform
: ( nullable
CGAffineTransform * ) startTransform endTransform
: ( nullable
CGAffineTransform * ) endTransform timeRange
: ( nullable
CMTimeRange * ) timeRange
;
- ( BOOL ) getOpacityRampForTime
: ( CMTime ) time startOpacity
: ( nullable float
* ) startOpacity endOpacity
: ( nullable float
* ) endOpacity timeRange
: ( nullable
CMTimeRange * ) timeRange
;
- ( BOOL ) getCropRectangleRampForTime
: ( CMTime ) time startCropRectangle
: ( nullable
CGRect * ) startCropRectangle endCropRectangle
: ( nullable
CGRect * ) endCropRectangle timeRange
: ( nullable
CMTimeRange * ) timeRange
NS_AVAILABLE ( 10_9 , 7_0 ) ;
1.3.5.6 AVMutableVideoCompositionLayerInstruction
+ ( instancetype
) videoCompositionLayerInstructionWithAssetTrack
: ( AVAssetTrack * ) track
;
+ ( instancetype
) videoCompositionLayerInstruction
;
該類的屬性表示 instruction 所作用的 track 的 ID:
@property
( nonatomic
, assign
) CMPersistentTrackID trackID
;
設置了 trackID 后,通過下面的方法,進行剃度信息的設置:
- ( void
) setTransformRampFromStartTransform
: ( CGAffineTransform ) startTransform toEndTransform
: ( CGAffineTransform ) endTransform timeRange
: ( CMTimeRange ) timeRange
;
- ( void
) setTransform
: ( CGAffineTransform ) transform atTime
: ( CMTime ) time
;
- ( void
) setOpacityRampFromStartOpacity
: ( float
) startOpacity toEndOpacity
: ( float
) endOpacity timeRange
: ( CMTimeRange ) timeRange
;
- ( void
) setOpacity
: ( float
) opacity atTime
: ( CMTime ) time
;
- ( void
) setCropRectangleRampFromStartCropRectangle
: ( CGRect ) startCropRectangle toEndCropRectangle
: ( CGRect ) endCropRectangle timeRange
: ( CMTimeRange ) timeRange
NS_AVAILABLE ( 10_9 , 7_0 ) ;
- ( void
) setCropRectangle
: ( CGRect ) cropRectangle atTime
: ( CMTime ) time
NS_AVAILABLE ( 10_9 , 7_0 ) ;
1.3.5.7 AVVideoCompositionCoreAnimationTool
在自定義視頻播放時,可能需要添加水印、標題或者其他的動畫效果,需要使用該類。該類通常用來協調離線視頻中圖層與動畫圖層的組合(如使用 AVAssetExportSession 和 AVAssetReader 、AVAssetReader 類導出視頻文件或讀取視頻文件時),而若是在線實時的視頻播放,應使用 AVSynchronizedLayer 類來同步視頻的播放與動畫的效果。
在使用該類時,注意動畫在整個視頻的時間線上均可以被修改,所以,動畫的開始時間應該設置為 AVCoreAnimationBeginTimeAtZero ,這個值其實比 0 大,屬性值 removedOnCompletion 應該置為 NO,以防當動畫執行結束后被移除,并且不應使用與任何的 UIView 相關聯的圖層。
作為視頻組合的后期處理工具類,主要方法如下:
+ ( instancetype
) videoCompositionCoreAnimationToolWithAdditionalLayer
: ( CALayer * ) layer asTrackID
: ( CMPersistentTrackID ) trackID
;
+ ( instancetype
) videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer
: ( CALayer * ) videoLayer inLayer
: ( CALayer * ) animationLayer
;
+ ( instancetype
) videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayers
: ( NSArray < CALayer * > * ) videoLayers inLayer
: ( CALayer * ) animationLayer
NS_AVAILABLE ( 10_9 , 7_0 ) ;
1.3.5.8 AVVideoCompositionValidationHandling
當我們經過編輯后得到一個視頻資源 asset ,并且為該資源設置了自定義播放信息 video composition ,需要驗證對于這個 asset 而言,video composition 是否有效,可以調用 AVVideoComposition 的校驗方法。
- ( BOOL ) isValidForAsset
: ( nullable
AVAsset * ) asset timeRange
: ( CMTimeRange ) timeRange validationDelegate
: ( nullable id
< AVVideoCompositionValidationHandling > ) validationDelegate
NS_AVAILABLE ( 10_8 , 5_0 ) ;
- ( BOOL ) videoComposition
: ( AVVideoComposition * ) videoComposition shouldContinueValidatingAfterFindingInvalidValueForKey
: ( NSString * ) key
NS_AVAILABLE ( 10_8 , 5_0 ) ;
- ( BOOL ) videoComposition
: ( AVVideoComposition * ) videoComposition shouldContinueValidatingAfterFindingEmptyTimeRange
: ( CMTimeRange ) timeRange
NS_AVAILABLE ( 10_8 , 5_0 ) ;
- ( BOOL ) videoComposition
: ( AVVideoComposition * ) videoComposition shouldContinueValidatingAfterFindingInvalidTimeRangeInInstruction
: ( id
< AVVideoCompositionInstruction > ) videoCompositionInstruction
NS_AVAILABLE ( 10_8 , 5_0 ) ;
- ( BOOL ) videoComposition
: ( AVVideoComposition * ) videoComposition shouldContinueValidatingAfterFindingInvalidTrackIDInInstruction
: ( id
< AVVideoCompositionInstruction > ) videoCompositionInstruction layerInstruction
: ( AVVideoCompositionLayerInstruction * ) layerInstruction asset
: ( AVAsset * ) asset
NS_AVAILABLE ( 10_8 , 5_0 ) ;
1.3.5.9 AVVideoCompositionValidationHandling
1.4 AVFoundation 之 視音頻編輯
詳情可以參考蘋果官方文檔:Editing章節 AVFoundation使用組合從現有的媒體片段(通常是一個或多個視頻和音頻軌道)創建新資產。您可以使用可變組合來添加和刪除軌跡,并調整它們的時間順序。你也可以設置音軌的相對音量和傾斜;設置視頻軌跡的不透明度和不透明度坡道。合成是存儲在內存中的媒體片段的集合。當您使用導出會話導出一個組合時,它會折疊成一個文件。您還可以使用資產寫入器從媒體(例如示例緩沖區或靜態圖像)創建資產。 AVFoundation 框架中提供了豐富的接口用于視聽資源的編輯,其中的關鍵是 composition ,它將不同的 asset 相結合并形成一個新的 asset 。使用 AVMutableComposition 類可以增刪 asset 來將指定的 asset 集合到一起。除此之外,若想將集合到一起的視聽資源以自定義的方式進行播放,需要使用 AVMutableAudioMix 和 AVMutableVideoComposition類對其中的資源進行協調管理。最終要使用 AVAssetExportSession 類將編輯的內容保存到文件中。 AVFoundation框架提供了一組功能豐富的類,以方便編輯視聽資產。AVFoundation編輯API的核心是復合。組合就是來自一個或多個不同媒體資產的音軌集合。AVMutableComposition類提供了一個接口,用于插入和刪除軌跡,以及管理它們的時間順序。圖3-1顯示了如何將現有資產組合拼湊成新資產。如果您想做的只是將多個資產按順序合并到一個文件中,那么這就是您所需要的全部細節。如果你想在你的作曲中對音軌進行任何自定義音頻或視頻處理,你需要分別合并一個音頻混合或一個視頻合成。
使用AVMutableAudioMix類,您可以在組合中的音頻軌道上執行自定義音頻處理,如圖3-2所示。目前,您可以為音軌指定最大音量或設置音量斜坡。
您可以使用AVMutableVideoComposition類來直接編輯合成中的視頻軌跡,如圖3-3所示。對于單個視頻合成,您可以為輸出視頻指定所需的渲染大小和比例以及幀持續時間。通過視頻合成的指令(由AVMutableVideoCompositionInstruction類表示),您可以修改視頻的背景顏色并應用層指令。這些層指令(由AVMutableVideoCompositionLayerInstruction類表示)可用于對組合中的視頻軌道應用轉換、轉換坡道、不透明度和不透明度坡道。video composition類還允許您使用animationTool屬性將核心動畫框架的效果引入到視頻中。
要將組合與音頻和視頻組合組合在一起,可以使用AVAssetExportSession對象,如圖3-4所示。使用組合初始化導出會話,然后分別將音頻混合和視頻組合分配給audioMix和videoComposition屬性。
1.4.1 AVAssetExportSession
使用 AVAssetExportSession 類對視頻進行裁剪及轉碼,即將一個 AVAsset 類實例修改后保存為另一個 AVAsset 類實例,最后保存到文件中。 在修改資源之前,為避免不兼容帶來的錯誤,可以先調用下面的方法,檢查預設置是否合理。
+ ( NSArray < NSString * > * ) exportPresetsCompatibleWithAsset
: ( AVAsset * ) asset
;
+ ( void
) determineCompatibilityOfExportPreset
: ( NSString * ) presetName withAsset
: ( AVAsset * ) asset outputFileType
: ( nullable
NSString * ) outputFileType completionHandler
: ( void
( ^ ) ( BOOL compatible
) ) handler
NS_AVAILABLE ( 10_9 , 6_0 ) ;
除了設置文件類型外,還可以設置文件的大小、時長、范圍等屬性,一切準備就緒后,調用方法:- (void)exportAsynchronouslyWithCompletionHandler:(void (^)(void))handler;
進行文件的導出,導出結束后,會調用 handler 回調,在回調中應該檢查 AVAssetExportSession 的 status 屬性查看導出是否成功,若指定的文件保存地址在沙盒外,或在導出的過程中有電話打入都會導致文件保存失敗,如下:
- ( void
) exportVideo
: ( NSURL * ) url
{ AVAsset * anAsset
= [ AVAsset assetWithURL
: url
] ; [ AVAssetExportSession determineCompatibilityOfExportPreset
: AVAssetExportPresetHighestQuality withAsset
: anAssetoutputFileType
: AVFileTypeMPEG4 completionHandler
: ^ ( BOOL compatible
) { if ( compatible
) { AVAssetExportSession * exportSession
= [ [ AVAssetExportSession alloc
] initWithAsset
: anAssetpresetName
: AVAssetExportPresetHighestQuality ] ; exportSession
. outputFileType
= AVFileTypeMPEG4 ; CMTime start
= CMTimeMakeWithSeconds ( 1.0 , 600 ) ; CMTime duration
= CMTimeMakeWithSeconds ( 3.0 , 600 ) ; CMTimeRange range
= CMTimeRangeMake ( start
, duration
) ; exportSession
. timeRange
= range
; [ exportSession exportAsynchronouslyWithCompletionHandler
: ^ { switch ( [ exportSession status
] ) { case AVAssetExportSessionStatusCompleted : NSLog ( @
"completed" ) ; break ; case AVAssetExportSessionStatusFailed : NSLog ( @
"failed" ) ; break ; case AVAssetExportSessionStatusCancelled : NSLog ( @
"canceled" ) ; break ; default : break ; } } ] ; } } ] ;
}
1.4.2 AVComposition
@property
( nonatomic
, readonly
) NSArray < AVCompositionTrack * > * tracks
;
@property
( nonatomic
, readonly
) CGSize naturalSize
;
@property
( nonatomic
, readonly
, copy
) NSDictionary < NSString * , id
> * URLAssetInitializationOptions NS_AVAILABLE ( 10_11 , 9_0 ) ;
- ( nullable
AVCompositionTrack * ) trackWithTrackID
: ( CMPersistentTrackID ) trackID
;
- ( NSArray < AVCompositionTrack * > * ) tracksWithMediaType
: ( NSString * ) mediaType
;
- ( NSArray < AVCompositionTrack * > * ) tracksWithMediaCharacteristic
: ( NSString * ) mediaCharacteristic
;
值得注意的是 AVComposition 類中并沒有提供初始化方法,一般我們使用它的子類 AVMutableComposition ,進行各種操作后,再生成 AVComposition 實例以供查詢,如下:
AVMutableComposition * mutableComposition
= [ AVMutableComposition composition
] ;
< #····#
>
AVComposition * composition
= [ myMutableComposition copy
] ;
AVPlayerItem * playerItem
= [ [ AVPlayerItem alloc
] initWithAsset
: composition
] ;
1.4.3 AVMutableComposition
AVMutableComposition 是 AVComposition 的子類,其包含的 tracks 則是 AVCompositionTrack 的子類 AVMutableCompositionTrack 。 AVMutableComposition 中提供了兩個類方法用來獲取一個空的 AVMutableComposition 實例對象。
+ ( instancetype
) composition
;
+ ( instancetype
) compositionWithURLAssetInitializationOptions
: ( nullable
NSDictionary < NSString * , id
> * ) URLAssetInitializationOptions NS_AVAILABLE ( 10_11 , 9_0 ) ;
對整個 composition 中的 tracks 的修改方法如下:
- ( BOOL ) insertTimeRange
: ( CMTimeRange ) timeRange ofAsset
: ( AVAsset * ) asset atTime
: ( CMTime ) startTime error
: ( NSError * _Nullable
* _Nullable
) outError
;
- ( void
) insertEmptyTimeRange
: ( CMTimeRange ) timeRange
;
- ( void
) removeTimeRange
: ( CMTimeRange ) timeRange
;
- ( void
) scaleTimeRange
: ( CMTimeRange ) timeRange toDuration
: ( CMTime ) duration
;
從 composition 中獲取 track 或向其中添加/移除 track 方法如下:
- ( AVMutableCompositionTrack * ) addMutableTrackWithMediaType
: ( NSString * ) mediaType preferredTrackID
: ( CMPersistentTrackID ) preferredTrackID
;
- ( void
) removeTrack
: ( AVCompositionTrack * ) track
;
- ( nullable
AVMutableCompositionTrack * ) mutableTrackCompatibleWithTrack
: ( AVAssetTrack * ) track
;
AVMutableComposition 中也提供了過濾AVMutableCompositionTrack 的接口:
- ( nullable
AVMutableCompositionTrack * ) trackWithTrackID
: ( CMPersistentTrackID ) trackID
;
- ( NSArray < AVMutableCompositionTrack * > * ) tracksWithMediaType
: ( NSString * ) mediaType
;
- ( NSArray < AVMutableCompositionTrack * > * ) tracksWithMediaCharacteristic
: ( NSString * ) mediaCharacteristic
;
1.4.4 AVCompositionTrack
AVCompositionTrack 類同其父類 AVAssetTrack 一樣是媒體資源的管理者,它實際是媒體資源數據的集合,它的屬性 segments 是 AVCompositionTrackSegment 類的實例對象集合,每個對象描述一個媒體數據片段。類 AVCompositionTrack 并不常用,通常使用的是它的子類 AVMutableCompositionTrack 。
1.4.5 AVMutableCompositionTrack
AVMutableCompositionTrack 中提供的屬性如下:
@property
( nonatomic
) CMTimeScale naturalTimeScale
;
@property
( nonatomic
, copy
, nullable
) NSString * languageCode
;
@property
( nonatomic
, copy
, nullable
) NSString * extendedLanguageTag
;
@property
( nonatomic
) CGAffineTransform preferredTransform
;
@property
( nonatomic
) float preferredVolume
;
@property
( nonatomic
, copy
, null_resettable
) NSArray < AVCompositionTrackSegment * > * segments
;
當我們獲取了一個 AVMutableCompositionTrack 實例對象后,便可以通過以下方法對其進行添加或移除數據片段:
- ( BOOL ) insertTimeRange
: ( CMTimeRange ) timeRange ofTrack
: ( AVAssetTrack * ) track atTime
: ( CMTime ) startTime error
: ( NSError * _Nullable
* _Nullable
) outError
;
- ( BOOL ) insertTimeRanges
: ( NSArray < NSValue * > * ) timeRanges ofTracks
: ( NSArray < AVAssetTrack * > * ) tracks atTime
: ( CMTime ) startTime error
: ( NSError * _Nullable
* _Nullable
) outError
NS_AVAILABLE ( 10_8 , 5_0 ) ;
- ( void
) insertEmptyTimeRange
: ( CMTimeRange ) timeRange
;
- ( void
) removeTimeRange
: ( CMTimeRange ) timeRange
;
- ( void
) scaleTimeRange
: ( CMTimeRange ) timeRange toDuration
: ( CMTime ) duration
;
- ( BOOL ) validateTrackSegments
: ( NSArray < AVCompositionTrackSegment * > * ) trackSegments error
: ( NSError * _Nullable
* _Nullable
) outError
;
1.4.6 AVAssetTrackSegment
媒體資源 AVAsset 中的集合 AVAssetTrack 管理著單條時間線上的媒體數據片段,而每個數據片段則由 AVAssetTrackSegment 類進行描述。 AVAssetTrackSegment 有兩個屬性:
timeMapping 描述的是數據片段在整個媒體文件中所處的時間范圍.timeMapping 是一個結構體,擁有兩個成員,對于編輯中的媒體數據片段,它們分別表示數據在源文件中的位置和目標文件中的位置. empty 描述該數據片段是否為空,如果為空,其 timeMapping.source.start 為 kCMTimeInvalid
1.4.7 AVCompositionTrackSegment
在編輯媒體文件時,在描述數據時,使用的是 AVAssetTrackSegment 的子類 AVCompositionTrackSegment ,它的主要屬性和方法如下:
@property
( nonatomic
, readonly
, getter
= isEmpty ) BOOL empty
;
@property
( nonatomic
, readonly
, nullable
) NSURL * sourceURL
;
@property
( nonatomic
, readonly
) CMPersistentTrackID sourceTrackID
;
+ ( instancetype
) compositionTrackSegmentWithURL
: ( NSURL * ) URL trackID
: ( CMPersistentTrackID ) trackID sourceTimeRange
: ( CMTimeRange ) sourceTimeRange targetTimeRange
: ( CMTimeRange ) targetTimeRange
;
- ( instancetype
) initWithURL
: ( NSURL * ) URL trackID
: ( CMPersistentTrackID ) trackID sourceTimeRange
: ( CMTimeRange ) sourceTimeRange targetTimeRange
: ( CMTimeRange ) targetTimeRange
NS_DESIGNATED_INITIALIZER ;
+ ( instancetype
) compositionTrackSegmentWithTimeRange
: ( CMTimeRange ) timeRange
;
- ( instancetype
) initWithTimeRange
: ( CMTimeRange ) timeRange
NS_DESIGNATED_INITIALIZER ;
1.5 AVFoundation 之 視音頻媒體捕獲
將現實世界的模擬信號轉換為能夠被計算機存儲和傳輸的數字信號,需要經過模擬-數字轉換過程,也稱為采樣。數字化采樣有兩種方式,一種是時間采樣,即捕捉一個信號周期內的變化,一種是空間采樣,一般用于圖片數字化和其他可視化媒體內容數字化上,它對一個圖片在一定分辨率下捕捉其亮度和色度,進而創建出由該圖片的像素點數據所構成的數字化結果。視頻既有空間屬性又有時間屬性,所以數字化時都可以使用。
對于一個音頻,麥克風負責將物理振動轉化為相同頻率和振幅的電流信號,之后通過線性脈沖編碼調制(LPCM)進行編碼。LPCM 采樣或測量一個固定的音頻信號,其周期率被稱為采樣率。采樣頻率達到奈奎斯特頻率(采樣對象最高頻率的 2 倍)時即可準確表現原始信號的信息。另一方面編碼字節數(也稱位元深度)表現了采樣精度,如位元深度為 8 位的編碼能夠提供 256 個離散級別的數據,CD 音質位元深度為 16
攝像機和麥克風的記錄輸入由捕獲會話管理。捕獲會話協調從輸入設備到輸出(如電影文件)的數據流。您可以為單個會話配置多個輸入和輸出,甚至在會話運行時也是如此。向會話發送消息以啟動和停止數據流。此外,您可以使用預覽層的實例向用戶顯示攝像機正在錄制的內容。
更多關于視頻捕獲的詳情可以參考蘋果官方文檔:Still and Video Media Capture章節
要管理來自攝像機或麥克風等設備的捕獲,您需要組裝對象來表示輸入和輸出,并使用AVCaptureSession實例來協調它們之間的數據流。你需要最低限度:
表示輸入設備的AVCaptureDevice實例,如攝像機或麥克風 AVCaptureInput的一個具體子類的實例,用于配置來自輸入設備的端口 AVCaptureOutput的一個具體子類的實例,用于管理電影文件或靜態圖像的輸出 AVCaptureSession的一個實例,用于協調從輸入到輸出的數據流
要向用戶顯示攝像機記錄內容的預覽,可以使用AVCaptureVideoPreviewLayer的一個實例(CALayer的一個子類)。
您可以配置多個輸入和輸出,由單個會話進行協調,如圖4-1所示:
對于許多應用程序,這是您需要的盡可能多的細節。但是,對于某些操作(例如,如果希望監視音頻通道中的功率級別),需要考慮如何表示輸入設備的各個端口,以及如何將這些端口連接到輸出。
捕獲會話中的捕獲輸入和捕獲輸出之間的連接由AVCaptureConnection對象表示。捕獲輸入(AVCaptureInput的實例)有一個或多個輸入端口(AVCaptureInputPort的實例)。捕獲輸出(AVCaptureOutput的實例)可以接受來自一個或多個源的數據(例如,AVCaptureMovieFileOutput對象同時接受視頻和音頻數據)。
當您將輸入或輸出添加到會話時,會話將在所有兼容的捕獲輸入端口和捕獲輸出之間形成連接,如圖4-2所示。捕獲輸入和捕獲輸出之間的連接由AVCaptureConnection對象表示。
您可以使用捕獲連接來啟用或禁用來自給定輸入或到給定輸出的數據流。您還可以使用連接來監視音頻通道中的平均和峰值功率級別。
通過麥克風、攝像機等設備,可以捕獲外界的聲音和影像。要處理設備捕獲的數據,需要使用 AVCaptureDevice 類描述設備,使用 AVCaptureInput 配置數據從設備的輸入,使用 AVCaptureOutput 類管理數據到文件的寫入,而數據的輸入到寫出,需要使用 AVCaptureSession 類進行協調。此外,可以使用 AVCaptureVideoPreviewLayer 類顯示相機正在拍攝的畫面。
一個設備可以有多個輸入,使用 AVCaptureInputPort 類描述這些輸入,用 AVCaptureConnection 類描述具體類型的輸入與輸出的關系,可以實現更精細的數據處理。
1.5.1 AVCaptureSession
`AVCaptureSession 是捕獲視聽數據的核心類,它協調數據的輸入和輸出。創建一個 AVCaptureSession 類的對象時,可以指定最終得到的視聽數據的質量,當然這個質量與設備也有關系,通常在設置之前,可以調用方法判斷 session 是否支持要設置的質量。
AVCaptureSession 類實例可設置的數據質量有 AVCaptureSessionPresetHigh 、AVCaptureSessionPresetMedium 、AVCaptureSessionPresetLow 、AVCaptureSessionPreset320x240 等。在進行設置之前,可以調用 AVCaptureSession 中的方法進行校驗。
- ( BOOL ) canSetSessionPreset
: ( NSString * ) preset
;
設置好對象后,可調用下面的方法,添加、移除輸入、輸出。
- ( BOOL ) canAddInput
: ( AVCaptureInput * ) input
;
- ( void
) addInput
: ( AVCaptureInput * ) input
;
- ( void
) removeInput
: ( AVCaptureInput * ) input
; - ( BOOL ) canAddOutput
: ( AVCaptureOutput * ) output
;
- ( void
) addOutput
: ( AVCaptureOutput * ) output
;
- ( void
) removeOutput
: ( AVCaptureOutput * ) output
; - ( void
) addInputWithNoConnections
: ( AVCaptureInput * ) input
NS_AVAILABLE ( 10_7 , 8_0 ) ;
- ( void
) addOutputWithNoConnections
: ( AVCaptureOutput * ) output
NS_AVAILABLE ( 10_7 , 8_0 ) ; - ( BOOL ) canAddConnection
: ( AVCaptureConnection * ) connection
NS_AVAILABLE ( 10_7 , 8_0 ) ;
- ( void
) addConnection
: ( AVCaptureConnection * ) connection
NS_AVAILABLE ( 10_7 , 8_0 ) ;
- ( void
) removeConnection
: ( AVCaptureConnection * ) connection
NS_AVAILABLE ( 10_7 , 8_0 ) ;
開始執行 session 或者結束執行,調用下面的方法:
- ( void
) startRunning
;
- ( void
) stopRunning
;
對于正在執行中的 session ,要對其進行改變,所作出的改變,應放在下面兩個方法之間。
- ( void
) beginConfiguration
;
- ( void
) commitConfiguration
;
AVCaptureSession 開始執行、結束執行、執行過程中出錯或被打斷時,都會發出通知,通過注冊下面的通知,可以獲取我們感興趣的信息。
VCaptureSessionRuntimeErrorNotification 通過 AVCaptureSessionErrorKey 可以獲取出錯的原因 AVCaptureSessionDidStartRunningNotification 開始 session AVCaptureSessionDidStopRunningNotification 結束 session AVCaptureSessionWasInterruptedNotification 通過 AVCaptureSessionInterruptionReasonKey 可以獲取被打斷的原因 AVCaptureSessionInterruptionEndedNotification 打斷結束,session 重新開始
1.5.2 AVCaptureDevice
AVCaptureDevice是用來描述設備屬性的類,要捕獲視聽數據,需要獲取相應的設備,使用該類獲取有效的設備資源。這個設備資源列表是隨時變動的,其在變動時,會發送AVCaptureDeviceWasConnectedNotification 或 AVCaptureDeviceWasDisconnectedNotification 通知,以告知有設備連接或斷開。
在獲取設備之前,要先確定要獲取的設備的類型 AVCaptureDeviceType ,設備的位置 AVCaptureDevicePosition ,也可以通過要獲取的媒體數據類型進行設備的選擇。
獲取設備后,可以保存它的唯一標識、模型標識、名稱等信息,以待下次用來獲取設備。
+ ( NSArray * ) devices
;
+ ( NSArray * ) devicesWithMediaType
: ( NSString * ) mediaType
;
+ ( AVCaptureDevice * ) defaultDeviceWithMediaType
: ( NSString * ) mediaType
;
+ ( AVCaptureDevice * ) deviceWithUniqueID
: ( NSString * ) deviceUniqueID
; @
property ( nonatomic
, readonly
) NSString * uniqueID
;
@
property ( nonatomic
, readonly
) NSString * modelID
;
@
property ( nonatomic
, readonly
) NSString * localizedName
;
- ( BOOL ) hasMediaType
: ( NSString * ) mediaType
;
- ( BOOL ) supportsAVCaptureSessionPreset
: ( NSString * ) preset
;
獲取一個設備后,可以通過修改它的屬性來滿足自己的需要。
flashMode 閃光燈的模式(AVCaptureFlashModeOff 、AVCaptureFlashModeOn 、AVCaptureFlashModeAuto) torchMode 手電筒的模式(AVCaptureTorchModeOff 、AVCaptureTorchModeOn 、AVCaptureTorchModeAuto) torchLevel 手電筒的亮度(0~1) focusMode 聚焦模式(AVCaptureFocusModeLocked 、AVCaptureFocusModeAutoFocus 、AVCaptureFocusModeContinuousAutoFocus) exposureMode 曝光模式(AVCaptureExposureModeLocked 、AVCaptureExposureModeAutoExpose 、AVCaptureExposureModeContinuousAutoExposure 、AVCaptureExposureModeCustom) whiteBalanceMode 白平衡模式(AVCaptureWhiteBalanceModeLocked 、AVCaptureWhiteBalanceModeAutoWhiteBalance 、AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance)
在修改這些屬性時,應先判斷當前設備是否支持要設置的屬性值,并且所有的屬性修改都要放在下面兩個方法之間,以保證屬性能夠被正確設置。
- ( BOOL ) lockForConfiguration
: ( NSError * * ) outError
;
- ( void
) unlockForConfiguration
;
在調用硬件設備之前,應先判斷應用是否擁有相應的權限,其權限分為以下幾種:
AVAuthorizationStatusNotDetermined 未定義 AVAuthorizationStatusRestricted 無權限(因某些原因,系統拒絕權限) AVAuthorizationStatusDenied 無權限(用戶拒絕) AVAuthorizationStatusAuthorized 有權限
+ ( AVAuthorizationStatus ) authorizationStatusForMediaType
: ( NSString * ) mediaType
NS_AVAILABLE_IOS ( 7_0 ) ;
+ ( void
) requestAccessForMediaType
: ( NSString * ) mediaType completionHandler
: ( void
( ^ ) ( BOOL granted
) ) handler
NS_AVAILABLE_IOS ( 7_0 ) ;
1.5.3 AVCaptureDeviceInput
AVCaptureDeviceInput 是 AVCaptureInput 的子類,使用一個 AVCaptureDevice 類實例創建該類的實例,其管理設備的輸入。 在創建了實例對象后,將其添加到 session 中。
NSError * error
;
AVCaptureDeviceInput * input
= [ AVCaptureDeviceInput deviceInputWithDevice
: device error
: & error
] ;
if ( input
&& [ session canAddInput
: input
] ) { [ captureSession addInput
: captureDeviceInput
] ;
}
1.5.4 AVCaptureOutput
AVCaptureOutput 是一個抽象類,通常使用的是它的子類
AVCaptureMovieFileOutput 用來生成一個影視文件 AVCaptureVideoDataOutput 用來處理輸入的視頻的幀 AVCaptureAudioDataOutput 用來處理音頻數據 AVCaptureStillImageOutput 用來獲取圖片
在創建了具體的子類后,將它添加到 session 中
AVCaptureMovieFileOutput * movieOutput
= [ [ AVCaptureMovieFileOutput alloc
] init ] ;
if ( [ session canAddOutput
: movieOutput
] ) { [ session addOutput
: movieOutput
] ;
}
1.5.5 AVCaptureFileOutput
AVCaptureFileOutput 是 AVCaptureOutput 的子類,是 AVCaptureMovieFileOutput 、AVCaptureAudioFileOutput 的父類。這個類中定義了文件輸出時的地址、時長、容量等屬性。
@
property ( nonatomic
, readonly
) NSURL * outputFileURL
;
- ( void
) startRecordingToOutputFileURL
: ( NSURL * ) outputFileURL recordingDelegate
: ( id
< AVCaptureFileOutputRecordingDelegate > ) delegate
;
- ( void
) stopRecording
;
@
property ( nonatomic
, readonly
, getter
= isRecording
) BOOL recording
;
@
property ( nonatomic
, readonly
) CMTime recordedDuration
;
@
property ( nonatomic
, readonly
) int64_t recordedFileSize
;
@
property ( nonatomic
) CMTime maxRecordedDuration
;
@
property ( nonatomic
) int64_t maxRecordedFileSize
;
@
property ( nonatomic
) int64_t minFreeDiskSpaceLimit
;
@
property ( nonatomic
, assign
) id
< AVCaptureFileOutputDelegate > delegate
NS_AVAILABLE ( 10_7 , NA ) ;
@
property ( nonatomic
, readonly
, getter
= isRecordingPaused
) BOOL recordingPaused
NS_AVAILABLE ( 10_7 , NA ) ;
- ( void
) pauseRecording
NS_AVAILABLE ( 10_7 , NA ) ;
- ( void
) resumeRecording
NS_AVAILABLE ( 10_7 , NA ) ;
1.5.6 AVCaptureFileOutputRecordingDelegate
AVCaptureFileOutputRecordingDelegate 是文件記錄過程中需要用到的協議,它通常的作用是告知代理對象文件記錄結束了。
- ( void
) captureOutput
: ( AVCaptureFileOutput * ) captureOutput didFinishRecordingToOutputFileAtURL
: ( NSURL * ) outputFileURL fromConnections
: ( NSArray * ) connections error
: ( NSError * ) error
;
- ( void
) captureOutput
: ( AVCaptureFileOutput * ) captureOutput didStartRecordingToOutputFileAtURL
: ( NSURL * ) fileURL fromConnections
: ( NSArray * ) connections
;
- ( void
) captureOutput
: ( AVCaptureFileOutput * ) captureOutput didPauseRecordingToOutputFileAtURL
: ( NSURL * ) fileURL fromConnections
: ( NSArray * ) connections
NS_AVAILABLE ( 10_7 , NA ) ;
- ( void
) captureOutput
: ( AVCaptureFileOutput * ) captureOutput didResumeRecordingToOutputFileAtURL
: ( NSURL * ) fileURL fromConnections
: ( NSArray * ) connections
NS_AVAILABLE ( 10_7 , NA ) ;
- ( void
) captureOutput
: ( AVCaptureFileOutput * ) captureOutput willFinishRecordingToOutputFileAtURL
: ( NSURL * ) fileURL fromConnections
: ( NSArray * ) connections error
: ( NSError * ) error
NS_AVAILABLE ( 10_7 , NA ) ;
1.5.7 AVCaptureFileOutputDelegate
AVCaptureFileOutputDelegate 這個協議只用于 Mac OS X 系統下,它給了客戶端精準操控數據的機會。
- ( BOOL ) captureOutputShouldProvideSampleAccurateRecordingStart
: ( AVCaptureOutput * ) captureOutput
NS_AVAILABLE ( 10_8 , NA ) ;
- ( void
) captureOutput
: ( AVCaptureFileOutput * ) captureOutput didOutputSampleBuffer
: ( CMSampleBufferRef ) sampleBuffer fromConnection
: ( AVCaptureConnection * ) connection
NS_AVAILABLE ( 10_7 , NA ) ;
1.5.8 AVCaptureAudioFileOutput
AVCaptureAudioFileOutput 是 AVCaptureFileOutput 的子類,該類用于將媒體數據記錄為一個音頻文件。
+ ( NSArray * ) availableOutputFileTypes
;
- ( void
) startRecordingToOutputFileURL
: ( NSURL * ) outputFileURL outputFileType
: ( NSString * ) fileType recordingDelegate
: ( id
< AVCaptureFileOutputRecordingDelegate > ) delegate
;
@
property ( nonatomic
, copy
) NSArray * metadata
;
@
property ( nonatomic
, copy
) NSDictionary * audioSettings
;
1.5.9 AVCaptureVideoDataOutput
AVCaptureVideoDataOutput 是 AVCaptureOutput 的子類,該類可以用來處理捕獲的每一個視頻幀數據。創建一個該類的實例對象后,要調用下面的方法設置一個代理對象,及調用代理對象所實現的協議方法的隊列。
- ( void
) setSampleBufferDelegate
: ( id
< AVCaptureVideoDataOutputSampleBufferDelegate > ) sampleBufferDelegate queue
: ( dispatch_queue_t
) sampleBufferCallbackQueue
;
指定的隊列 sampleBufferCallbackQueue 必需是串行隊列以保證傳遞的幀是按記錄時間先后傳遞的。
@
property ( nonatomic
, copy
) NSDictionary * videoSettings
;
@
property ( nonatomic
, readonly
) NSArray * availableVideoCVPixelFormatTypes
NS_AVAILABLE ( 10_7 , 5_0 ) ;
@
property ( nonatomic
, readonly
) NSArray * availableVideoCodecTypes
NS_AVAILABLE ( 10_7 , 5_0 ) ;
@
property ( nonatomic
) BOOL alwaysDiscardsLateVideoFrames
;
1.5.10 AVCaptureVideoDataOutputSampleBufferDelegate
該協議用來處理接收的每一個幀數據,或者提示客戶端有幀數據被丟棄。
- ( void
) captureOutput
: ( AVCaptureOutput * ) captureOutput didOutputSampleBuffer
: ( CMSampleBufferRef ) sampleBuffer fromConnection
: ( AVCaptureConnection * ) connection
;
- ( void
) captureOutput
: ( AVCaptureOutput * ) captureOutput didDropSampleBuffer
: ( CMSampleBufferRef ) sampleBuffer fromConnection
: ( AVCaptureConnection * ) connection
NS_AVAILABLE ( 10_7 , 6_0 ) ;
1.5.11 AVCaptureVideoPreviewLayer
AVCaptureVideoPreviewLayer 是 CALayer 的子類,使用該類可以實現捕獲視頻的顯示。使用一個 session 創建一個該類對象,而后將該類對象插入到圖層樹中,從而顯示捕獲的視頻。
+ ( instancetype
) layerWithSession
: ( AVCaptureSession * ) session
;
- ( instancetype
) initWithSession
: ( AVCaptureSession * ) session
;
修改 AVCaptureVideoPreviewLayer 的屬性 videoGravity 值,可以選擇顯示捕獲視頻時的界面大小變化方式,它有以下可選值:
AVLayerVideoGravityResize 默認值,直接鋪滿屏幕,及時畫面變形 AVLayerVideoGravityResizeAspect 保持畫面的橫縱比,不鋪滿屏幕,多余的空間顯示黑色 AVLayerVideoGravityResizeAspectFill 保持畫面的橫縱比,鋪滿屏幕,多余的畫面進行裁剪
1.5.12 AVCaptureAudioDataOutput
AVCaptureAudioDataOutput 是 AVCaptureOutput 的子類,該類可以處理接收到的音頻數據。同 AVCaptureVideoDataOutput 類似,該類也提供了一個方法,用于設置代理對象,以及調用代理對象實現的協議方法時的隊列。
- ( void
) setSampleBufferDelegate
: ( id
< AVCaptureAudioDataOutputSampleBufferDelegate > ) sampleBufferDelegate queue
: ( dispatch_queue_t
) sampleBufferCallbackQueue
;
1.5.13 AVCaptureAudioDataOutputSampleBufferDelegate
該協議提供了一個方法,用來實現對音頻數據的接收處理。
- ( void
) captureOutput
: ( AVCaptureOutput * ) captureOutput didOutputSampleBuffer
: ( CMSampleBufferRef ) sampleBuffer fromConnection
: ( AVCaptureConnection * ) connection
;
1.5.14 AVAssetImageGenerator
使用 AVAssetImageGenerator 生成視頻資源的縮略圖,使用 AVAsset 對象創建 AVAssetImageGenerator 對象,可以使用類方法或實例方法,如下:
+ ( instancetype
) assetImageGeneratorWithAsset
: ( AVAsset * ) asset
;
- ( instancetype
) initWithAsset
: ( AVAsset * ) asset
NS_DESIGNATED_INITIALIZER ;
當然,在此之前,最好調用 AVAsset 中的方法 - (NSArray<AVAssetTrack *> *)tracksWithMediaCharacteristic:(NSString *)mediaCharacteristic; 來判斷 asset 中是否有可視媒體數據。如果有,那么再創建 AVAssetImageGenerator 對象,而后再調用下面的方法,來獲取一張或多張圖片。
- ( nullable
CGImageRef ) copyCGImageAtTime
: ( CMTime ) requestedTime actualTime
: ( nullable
CMTime * ) actualTime error
: ( NSError * _Nullable
* _Nullable
) outError
CF_RETURNS_RETAINED ;
- ( void
) generateCGImagesAsynchronouslyForTimes
: ( NSArray < NSValue * > * ) requestedTimes completionHandler
: ( AVAssetImageGeneratorCompletionHandler ) handler
;
typedef void
( ^ AVAssetImageGeneratorCompletionHandler ) ( CMTime requestedTime
, CGImageRef _Nullable image
, CMTime actualTime
, AVAssetImageGeneratorResult result
, NSError * _Nullable error
) ;
1.6 AVFoundation 之媒體流輸出
對媒體數據資源進行簡單的轉碼或裁剪,使用 AVAssetExportSession 類便足夠了,但是更深層次的修改媒體資源,便需要用到 AVAssetReader 類和 AVAssetWriter 類。 AVAssetReader 只能與一個資源 asset 相關聯,且不能用來讀取實時數據,在開始讀取數據之前,需要為 reader 添加 AVAssetReaderOutput 的實例對象。這個實例對象描述的是待讀取的數據資源來源類型,通常使用 AVAssetReaderAudioMixOutput 、AVAssetReaderTrackOutput 、AVAssetReaderVideoCompositionOutput 三種子類。 AVAssetWriter 可以將來自多個數據源的數據以指定的格式寫入到一個指定的文件中,且其只能對應一個文件。在寫文件之前,需要用每一個 AVAssetWriterInput 類實例對象來描述相應的數據源。每一個 AVAssetWriterInput 實例對象接收的數據都應是 CMSampleBufferRef 類型的變量。如果使用 AVAssetWriterInputPixelBufferAdaptor 類也可以直接將 CVPixelBufferRef 類型的變量數據添加到 writer input 中。 AVAssetReader 與 AVAssetWriter 結合起來使用,便可以對讀取的數據進行相應的編輯修改,而后寫入到一個文件中并保存。
1.6.1 AVAssetReader
使用該類讀取媒體資源,其提供的初始化方法與一個 asset 相關聯。
+ ( nullable instancetype
) assetReaderWithAsset
: ( AVAsset * ) asset error
: ( NSError * _Nullable
* _Nullable
) outError
;
- ( nullable instancetype
) initWithAsset
: ( AVAsset * ) asset error
: ( NSError * _Nullable
* _Nullable
) outError
NS_DESIGNATED_INITIALIZER ;
AVAssetReaderStatusCompleted 、
AVAssetReaderStatusFailed 、
AVAssetReaderStatusCancelled
@property
( readonly
) AVAssetReaderStatus status
;
@property
( readonly
, nullable
) NSError * error
;
@property
( nonatomic
) CMTimeRange timeRange
;
- ( BOOL ) canAddOutput
: ( AVAssetReaderOutput * ) output
;
- ( void
) addOutput
: ( AVAssetReaderOutput * ) output
;
- ( BOOL ) startReading
;
- ( void
) cancelReading
;
1.6.2 AVAssetReaderOutput
AVAssetReaderOutput 是用來描述待讀取的數據的抽象類,讀取資源時,應創建該類的對象,并添加到相應的 AVAssetReader 實例對象中去。
@property
( nonatomic
, readonly
) NSString * mediaType
;
@property
( nonatomic
) BOOL alwaysCopiesSampleData
NS_AVAILABLE ( 10_8 , 5_0 ) ;
- ( nullable
CMSampleBufferRef ) copyNextSampleBuffer
CF_RETURNS_RETAINED ;
@property
( nonatomic
) BOOL supportsRandomAccess
NS_AVAILABLE ( 10_10 , 8_0 ) ;
- ( void
) resetForReadingTimeRanges
: ( NSArray < NSValue * > * ) timeRanges
NS_AVAILABLE ( 10_10 , 8_0 ) ;
- ( void
) markConfigurationAsFinal
NS_AVAILABLE ( 10_10 , 8_0 ) ;
1.6.3 AVAssetReaderTrackOutput
AVAssetReaderTrackOutput 是 AVAssetReaderOutput 的子類,它用來描述待讀取的數據來自 asset track ,在讀取前,還可以對數據的格式進行修改。
+ ( instancetype
) assetReaderTrackOutputWithTrack
: ( AVAssetTrack * ) track outputSettings
: ( nullable
NSDictionary < NSString * , id
> * ) outputSettings
;
- ( instancetype
) initWithTrack
: ( AVAssetTrack * ) track outputSettings
: ( nullable
NSDictionary < NSString * , id
> * ) outputSettings
NS_DESIGNATED_INITIALIZER ;
@property
( nonatomic
, copy
) NSString * audioTimePitchAlgorithm
NS_AVAILABLE ( 10_9 , 7_0 ) ;
1.6.4 AVAssetReaderAudioMixOutput
AVAssetReaderAudioMixOutput 是 AVAssetReaderOutput 的子類,它用來描述待讀取的數據來自音頻組合數據。創建該類實例對象提供的參數 audioTracks 集合中的每一個 asset track 都屬于相應的 reader 中的 asset 實例對象,且類型為 AVMediaTypeAudio 。 參數 audioSettings 給出了音頻數據的格式設置。
+ ( instancetype
) assetReaderAudioMixOutputWithAudioTracks
: ( NSArray < AVAssetTrack * > * ) audioTracks audioSettings
: ( nullable
NSDictionary < NSString * , id
> * ) audioSettings
;
- ( instancetype
) initWithAudioTracks
: ( NSArray < AVAssetTrack * > * ) audioTracks audioSettings
: ( nullable
NSDictionary < NSString * , id
> * ) audioSettings
NS_DESIGNATED_INITIALIZER
此外,該類的 audioMix 屬性,描述了從多個 track 中讀取的音頻的音量變化情況:@property (nonatomic, copy, nullable) AVAudioMix *audioMix;
1.6.5 AVAssetReaderVideoCompositionOutput
AVAssetReaderVideoCompositionOutput 是 AVAssetReaderOutput 的子類,該類用來表示要讀取的類是組合的視頻數據。 同 AVAssetReaderAudioMixOutput 類似,該類也提供了兩個創建實例的方法,需要提供的參數的 videoTracks 集合中每一個 track 都是 與 reader 相關聯的 asset 中的 track 。
+ ( instancetype
) assetReaderVideoCompositionOutputWithVideoTracks
: ( NSArray < AVAssetTrack * > * ) videoTracks videoSettings
: ( nullable
NSDictionary < NSString * , id
> * ) videoSettings
;
- ( instancetype
) initWithVideoTracks
: ( NSArray < AVAssetTrack * > * ) videoTracks videoSettings
: ( nullable
NSDictionary < NSString * , id
> * ) videoSettings
NS_DESIGNATED_INITIALIZER ;
該類的屬性 videoComposition 同樣描述了每個 track 的幀的顯示方式。
@property
( nonatomic
, copy
, nullable
) AVVideoComposition * videoComposition
;
1.7 AVFoundation 之媒體的時間和數據
總結
以上是生活随笔 為你收集整理的IOS音视频(一)AVFoundation核心类 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。