AVFoundation框架是ios中很重要的框架,所有與視頻音頻相關(guān)的軟硬件控制都在這個框架里面,接下來這幾篇就主要對這個框架進(jìn)行介紹和講解。
便于讀者查閱這個AVFoundation框架系列,在此提供目錄直通車。
AVFoundation框架解析目錄
AVFoundation框架解析目錄
AVFoundation框架解析目錄
本章導(dǎo)讀
AVFoundation框架下的視頻功能基本都跟AVAssetExportSession相關(guān),AVAssetExportSession可以以指定導(dǎo)出預(yù)設(shè)所描述的形式從現(xiàn)有AVAsset的內(nèi)容創(chuàng)建新的定時媒體資源。
本章將首先介紹AVAssetExportSession,以及基于AVAssetExportSession實現(xiàn)轉(zhuǎn)碼和壓縮視頻等應(yīng)用場景。

AVAssetExportSession數(shù)據(jù)結(jié)構(gòu).png
- AVAssetExportSession.Status
public enum Status : Int {
case unknown
case waiting
case exporting
case completed
case failed
case cancelled
}
- AVAssetExportSession 屬性
返回指定源資源和預(yù)設(shè)的AVAssetExportSession實例。
- AVAssetExportSession 方法
初始化方法
/*
asset: 用于導(dǎo)出的AVAsset對象。
presetName: NSString,指定導(dǎo)出的預(yù)設(shè)模板的名稱。
*/
public init?(asset: AVAsset, presetName: String)
其中presetName為以下類型:
//下面這些export選項可用于生成視頻大小適合設(shè)備的視頻文件。export不會從較小的尺寸縮放較大尺寸的視頻。視頻將使用H.264壓縮和音頻將使用AAC進(jìn)行壓縮。
public let AVAssetExportPresetLowQuality: String
public let AVAssetExportPresetMediumQuality: String
public let AVAssetExportPresetHighestQuality: String
//下面這個export(導(dǎo)出)方式視頻方面使用HEVC壓縮和音頻方面將使用AAC進(jìn)行壓縮。有些設(shè)備可能無法支持某些尺寸。
public let AVAssetExportPresetHEVCHighestQuality: String
public let AVAssetExportPresetHEVCHighestQualityWithAlpha: String
//下面的導(dǎo)出方式視頻采用HEVC壓縮,音頻采用AAC壓縮。有些設(shè)備可能無法支持某些尺寸。
public let AVAssetExportPreset640x480: String
public let AVAssetExportPreset960x540: String
public let AVAssetExportPreset1280x720: String
public let AVAssetExportPreset1920x1080: String
public let AVAssetExportPreset3840x2160: String
下面的導(dǎo)出方式視頻采用HEVC壓縮,音頻采用AAC壓縮。有些設(shè)備可能無法支持某些尺寸。
public let AVAssetExportPresetHEVC1920x1080: String
public let AVAssetExportPresetHEVC1920x1080WithAlpha: String
public let AVAssetExportPresetHEVC3840x2160: String
public let AVAssetExportPresetHEVC3840x2160WithAlpha: String
下面的導(dǎo)出選項將生成僅具有音頻的.m4a文件,其中包含適當(dāng)?shù)膇Tunes無間隙播放數(shù)據(jù)
public let AVAssetExportPresetAppleM4A: String
//下面的導(dǎo)出選項將使所有軌道的媒體完全按照存儲在源資源中的方式傳遞到output,除了通道無法通過的軌道,通常是由于指定的outputFileType指示的容器格式的約束。
此選項不包含在-allExportPresets和-exportPresetsCompatibleWithAsset返回的數(shù)組中。
public let AVAssetExportPresetPassthrough: String
應(yīng)用場景:
視頻轉(zhuǎn)碼,以MOV轉(zhuǎn)碼MP4為例
typealias TranscodingVideoBlock = (URL?) -> () //轉(zhuǎn)碼視頻回調(diào)
/*
轉(zhuǎn)碼視頻
asset: 需要轉(zhuǎn)碼的視頻
presetName: 視頻轉(zhuǎn)碼質(zhì)量,默認(rèn)為高清
outputName: 轉(zhuǎn)碼后視頻的名稱
completedBlock: 轉(zhuǎn)碼完成后的回調(diào)
*/
class func transcodingVideo(asset: AVURLAsset, presetName: String = AVAssetExportPresetMediumQuality, outputName: String, completedBlock: @escaping TranscodingVideoBlock) {
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: asset)
if !compatiblePresets.contains(presetName) {
print("不支持的轉(zhuǎn)碼 presetName")
return
}
guard let documentsDir = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {
return
}
guard let fileURL = URL(string: outputName, relativeTo: documentsDir) else {
return
}
do {
try FileManager.default.removeItem(at:fileURL)
} catch {
}
guard let exportSession = AVAssetExportSession(asset: asset, presetName: presetName) else {
return
}
exportSession.outputURL = fileURL
exportSession.outputFileType = .mp4
exportSession.shouldOptimizeForNetworkUse = true
exportSession.exportAsynchronously {
switch exportSession.status {
case .completed:
completedBlock(fileURL)
default:
completedBlock(nil)
}
}
}
裁剪視頻,默認(rèn)輸出格式為MP4
/*
typealias TailoringVideoBlock = (URL?) -> () //裁剪視頻回調(diào)
asset: 需要裁剪的視頻
outputName: 裁剪后視頻的名稱
startTime: 起始時間
durationTime: 裁剪時長
completedBlock: 裁剪完成后的回調(diào)
*/
class func tailoringVideo(asset: AVURLAsset, outputName: String, startTime: CMTime, durationTime: CMTime, completedBlock: @escaping TailoringVideoBlock) {
guard let documentsDir = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {
return
}
guard let fileURL = URL(string: outputName, relativeTo: documentsDir) else {
return
}
do {
try FileManager.default.removeItem(at:fileURL)
} catch {
}
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
return
}
exportSession.outputURL = fileURL
exportSession.outputFileType = .mp4
let timeRange = CMTimeRange(start: startTime, duration: durationTime)
exportSession.timeRange = timeRange
exportSession.exportAsynchronously {
switch exportSession.status {
case .completed:
completedBlock(fileURL)
default:
completedBlock(nil)
}
}
}