Kakapos全平臺視頻導出并添加濾鏡工具

Kakapos 是一個視頻添加過濾器工具环肘,支持網絡和本地網址以及相冊視頻欲虚。

同時可以簡單的支持多種濾鏡庫,例如Harbeth悔雹、GPUImage苍在、MetalPetal、CoreImage等等荠商。

反正核心其實就是對CVPixelBuffer進行注入濾鏡處理寂恬,然后再導出視頻即可。

支持全平臺系統(tǒng)莱没,macOS初肉、iOS、tvOS饰躲、watchOS


演示Demo

這邊已經提供關于macOS和iOS兩個端的演示Demo牙咏,需要的朋友請移步GitHub下載即可。

框架介紹

該架構主要涵蓋4個文件:

  • Exporter:主要的轉換文件嘹裂,注入濾鏡后導出視頻妄壶。
/// 設置導出文件質量
public var presetName: String = AVAssetExportPresetHighestQuality {
    didSet {
        if !AVAssetExportSession.allExportPresets().contains(presetName) {
            presetName = AVAssetExportPresetMediumQuality
        }
    }
}
/// 根據(jù)視頻鏈接初始化
public init(videoURL: URL, delegate: ExporterDelegate) {
    self.init(asset: AVAsset(url: videoURL), delegate: delegate)
}
/// 根據(jù)AVAsset初始化
public init(asset: AVAsset, delegate: ExporterDelegate) {
    self.asset = asset
    self.delegate = delegate
}
/// 添加濾鏡然后導出視頻,主要在`filtering`當中對`buffer`添加濾鏡寄狼,最后協(xié)議反饋結果丁寄。
public func export(outputURL: URL, optimizeForNetworkUse: Bool = true, filtering: @escaping PixelBufferCallback) {
    ...
}
  • ExporterDelegate:導出協(xié)議,包括成功和失敗兩個協(xié)議方法泊愧。
public protocol ExporterDelegate: NSObjectProtocol {
    
    /// 導出成功的視頻網址伊磺,相當于outputURL。
    func export(_ exporter: Exporter, success videoURL: URL)
    
    /// 視頻導出失敗删咱。
    func export(_ exporter: Exporter, failed error: Exporter.Error)
}
  • Compositor:對視頻幀進行處理屑埋,對緩沖進入注入濾鏡處理,最后再還原回去finish(withComposedVideoFrame:)即可痰滋。
func startRequest(_ request: AVAsynchronousVideoCompositionRequest) {
    self.renderQueue.sync {
        guard let instruction = request.videoCompositionInstruction as? CompositionInstruction,
              let pixels = request.sourceFrame(byTrackID: instruction.trackID) else {
            return
        }
        let buffer = instruction.bufferCallback(pixels) ?? pixels
        request.finish(withComposedVideoFrame: buffer)
    }
}
  • CompositionInstruction:表示一個指令摘能,決定每個timeRange內每個軌道的狀態(tài)续崖,配置視頻組合的渲染尺寸、縮放团搞、幀時長等袜刷,定義時間范圍信息,以及每一幀的層級莺丑。
/// 接收回調信息著蟹,方便后續(xù)轉換處理。
init(trackID: CMPersistentTrackID, bufferCallback: @escaping Exporter.PixelBufferCallback) {
    self.trackID = trackID
    self.bufferCallback = bufferCallback
    super.init()
    self.enablePostProcessing = true
}

關于AVMutableVideoCompositionInstruction更多介紹

參考:https://www.codersrc.com/archives/11663.html

該類還能拿來 完成對媒體裁剪 / 縮放 / 轉場 / 過渡等操作梢莽。

如何使用萧豆?

  • 設置轉換視頻存儲沙盒鏈接。
/// 創(chuàng)建臨時路徑以保存轉換的視頻
let outputURL: URL = {
    let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let outputURL = documents.appendingPathComponent("condy_exporter_video.mp4")
    
    // Check if the file already exists then remove the previous file
    if FileManager.default.fileExists(atPath: outputURL.path) {
        do {
            try FileManager.default.removeItem(at: outputURL)
        } catch {
            //completionHandler(nil, error)
        }
    }
    return outputURL
}()
  • 創(chuàng)建視頻導出器exporter實例昏名。
let exporter = Exporter.init(videoURL: ``URL Link``, delegate: self)

或者

let exporter = Exporter.init(asset: ``AVAsset``, delegate: self)
  • 實現(xiàn)視頻導出結果協(xié)議ExporterDelegate涮雷。
/// Video export successed.
/// - Parameters:
///   - exporter: VideoExporter
///   - videoURL: Export the successful video url, Be equivalent to outputURL.
func export(_ exporter: Kakapos.Exporter, success videoURL: URL) {
    self.view.hideAllToasts()
    let player = AVPlayer(url: videoURL)
    let vc = AVPlayerViewController()
    vc.player = player
    self.present(vc, animated: true) {
        vc.player?.play()
    }
}

/// Video export failure.
/// - Parameters:
///   - exporter: VideoExporter
///   - error: Failure error message.
func export(_ exporter: Kakapos.Exporter, failed error: Kakapos.Exporter.Error) {
    // do someing..
}
  • 轉換視頻緩沖區(qū)CVPixelBuffer并添加過濾器。
let filters: [C7FilterProtocol] = [
    C7Flip(horizontal: true, vertical: false),
    C7ColorConvert(with: .gray),
    C7SoulOut(soul: 0.3),
    MPSGaussianBlur(radius: 5),
]
let exporter = Exporter.init(videoURL: ``URL Link``, delegate: self)
exporter.export(outputURL: outputURL) {
    let dest = BoxxIO(element: $0, filters: filters)
    return try? dest.output()
}

或者

let martix = C7ColorMatrix4x4(matrix: Matrix4x4.Color.gray)
let screen = C7SplitScreen(type: .two)

let exporter = Exporter.init(videoURL: ``URL Link``, delegate: self)
exporter.export(outputURL: outputURL) { $0 ->> martix ->> screen }

最后

  • 再附上一個Metal濾鏡庫HarbethDemo地址轻局,目前包含100+種濾鏡洪鸭,同時也支持CoreImage混合使用。
  • 再附上一個開發(fā)加速庫KJCategoriesDemo地址
  • 再附上一個網絡基礎庫RxNetworksDemo地址
  • 喜歡的老板們可以點個星??仑扑,謝謝各位老板@谰簟!镇饮!

??.

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末蜓竹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子储藐,更是在濱河造成了極大的恐慌俱济,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钙勃,死亡現(xiàn)場離奇詭異蛛碌,居然都是意外死亡,警方通過查閱死者的電腦和手機辖源,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門蔚携,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人同木,你說我怎么就攤上這事浮梢□耸” “怎么了彤路?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芥映。 經常有香客問我洲尊,道長远豺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任坞嘀,我火速辦了婚禮躯护,結果婚禮上,老公的妹妹穿的比我還像新娘丽涩。我一直安慰自己棺滞,他們只是感情好,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布矢渊。 她就那樣靜靜地躺著继准,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矮男。 梳的紋絲不亂的頭發(fā)上移必,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音毡鉴,去河邊找鬼崔泵。 笑死,一個胖子當著我的面吹牛猪瞬,可吹牛的內容都是我干的憎瘸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼陈瘦,長吁一口氣:“原來是場噩夢啊……” “哼含思!你這毒婦竟也來了?” 一聲冷哼從身側響起甘晤,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤含潘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后线婚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遏弱,經...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年塞弊,在試婚紗的時候發(fā)現(xiàn)自己被綠了漱逸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡游沿,死狀恐怖饰抒,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情诀黍,我是刑警寧澤袋坑,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站眯勾,受9級特大地震影響枣宫,放射性物質發(fā)生泄漏婆誓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一也颤、第九天 我趴在偏房一處隱蔽的房頂上張望洋幻。 院中可真熱鬧,春花似錦翅娶、人聲如沸文留。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厂庇。三九已至,卻和暖如春输吏,著一層夾襖步出監(jiān)牢的瞬間权旷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工贯溅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拄氯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓它浅,卻偏偏與公主長得像译柏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姐霍,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內容