AVFoundation框架解析看這里(6)- AVAssetExportSession

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)
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容