你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 使用 AVFoundation 實現視頻倒序

使用 AVFoundation 實現視頻倒序

編輯:IOS開發基礎

作者:黃凱

背景

最近在做一個視頻類的APP,在視頻的編輯模塊有一個視頻倒序文件的需求,這個和倒序播放的需求不一樣,要求的是生成新的倒序視頻文件

研究過程

一開始原本以為這個需求很簡單,但是實現的時候遇到了各種麻煩,在最初,本以為可以直接使用AVMutableComposition對Track直接反轉的操作就可以實現視頻的倒序了(看來我真是Too Naive了),然後發現AVFoundation沒有提供這樣的接口。後面通過各種Google、StackOverflow,還是讓我找到了一些實現的思路,謝謝下面倆哥們的實現思路給了我極大的啟發 https://github.com/mikaelhellqvist/ReverseClip https://github.com/whydna/ReverseAVAsset

先講一下視頻倒序的實現原理: 視頻文件如果除去哪些雜七雜八的元數據,那剩下的就是一幀幀的視頻圖片了(視頻幀的分類這裡不展開討論),簡單的來講,就是把視頻文件裡的每一幀按照相反的方向去排列就可以讓視頻倒著播放了。

大體的實現思路如下: 

blob.png

把一個視頻拆分成多個AVAssetTrack,這樣做的原因是因為,使用AVAssetReader讀取每一幀SampleBuffer的數據是需要把數據加載到內存裡面去的,如果直接把整個視頻的SampleBuffer加載到內存,會造成閃退

拆分成多個AVAssetTrack之後,使用AVAssetReader從最後一個AVAssetTrack讀取SampleBuffer,這樣我們可以從後往前獲取視頻的幀數據

獲取數據之後通過AVAssetWriterInputPixelBufferAdaptor的- appendPixelBuffer:withPresentationTime:方法來把我們獲取到的SampleBuffer倒序寫入一個文件

問題

  1. 經過一番折騰,驚喜的發現Demo已經可以Run起來,並且可以輸出倒序的視頻文件,但是發現最後的時間總是不對,會少了一截,因為加載AVAsset的時候並沒有把准確的視頻長度信息加載進來,所以我們在加載AVAsset的時候需要調用loadValuesAsynchronouslyForKeys方法來獲取准確的視頻信息。

  2. 但是對於我的需求卻並未滿足,因為我們在上面說到,我們獲取的時候是一個原始的視頻文件,這個視頻文件沒有經過任何的編輯,所以一切看起來都沒啥問題,但是有時候我們需要對視頻進行一些編輯,比如合成,比如剪切,比如對視頻做一些Transform等等的一些編輯操作,水印,動畫等等,但是這些操作只是生成了一個新的AVMutableComposition,並沒有生成新的視頻文件,這個時候如果我們想要直接在經過編輯的文件來生成一個倒序的視頻怎麼辦?在網上找了很久資料,還是沒有找到實現的辦法,最後翻閱了官方文檔之後看到了AVAssetReaderOutput有一個子類AVAssetReaderVideoCompositionOutput,這個子類有一個屬性videoComposition,可以賦值一個AVVideoComposition指令容器,這樣我們就可以通過這個屬性來准確的加載被編輯過的視頻的編輯指令了。但是指令有一個timeRange屬性,我們直接生成的一組AVAssetTrack和原來的AVVideoComposition並不匹配,這個時候我用到了一個Trick的方法來對應

blob.png

解決辦法

我在分割AVAsset的時候,在生成一個新的AVComposition的實例時使用insertTimeRange方法插入的時間並非是kCMTimeZero,而是每一個AVAssetTrack在原來的AVAsset對應的開始和結束位置,這樣使用AVAssetReaderVideoCompositionOutput來配置videoComposition,Reader就可以准確的讀取包含了編輯指令每一幀的SampleBuffer了,然後再按照上面的方法來倒序寫入SampleBuffer即可

經驗總結

  • appendPixelBuffer:withPresentationTime:方法不能從後往前寫,如果你這樣做,會寫入失敗

  • 兼顧了編輯指令的實現方法會對性能有一定的浪費,因為我們不在kCMTimeZero時間點生成的AVAssetTrack會在Reader讀取的時候獲取的都是黑幀,隨著視頻的分割段數越多,視頻的時間越長,倒序生成的時間也就越長

  • 目前分割的段數是以每段視頻長度最長為1s來分割,如果來操作很長很大的視頻,可能需要耗費很長的時間

  • 分割視頻的時候目前沒有對編輯過和沒有編輯過的視頻作為區分,如果只針對原視頻倒序輸出,可以把每個AVAssetTrack的開始時間設置為kCMTimeZero,這樣性能會有很大的提升

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved