iOS 音視頻技術(shù) 視頻錄制

前言

伴隨著大火的短視頻應(yīng)用,正好自己也有點時間恩掷,就稍微學習了一下視頻相關(guān)的內(nèi)容倡鲸。

這種多媒體技術(shù)并沒有想象的那么簡單,這算是一個技術(shù)方向了黄娘。我把這些視頻相關(guān)的技術(shù)分為了兩部分峭状,暫且叫做應(yīng)用層面和底層技術(shù)層面(自己取得名字并不準確)。

應(yīng)用層面可以理解為調(diào)用一些系統(tǒng)的api或者使用一些三方的框架逼争,完成項目中的需求优床。從一個視頻類app的流程來說,可能就要包括視頻的錄制誓焦,視頻的處理(多段合成一段胆敞,添加背景音樂等),視頻的播放等杂伟,當然了還包括一些濾鏡效果移层,美顏效果,甚至是一些特效赫粥。

底層技術(shù)呢观话,就包括視頻如何編碼解碼,相機濾鏡美顏特效的一些實現(xiàn)越平。

坦白的說频蛔,從這兩個方面來說,我都很菜秦叛,這段時間的學習就算是這方面一個進階的過程吧晦溪。首先先從應(yīng)用的角度來入手,畢竟有項目驅(qū)動的話挣跋,首先咱得先把某些效果給實現(xiàn)了三圆,然后再考慮他們底層一些的技術(shù)。

視頻入門

視頻實質(zhì):
純粹的視頻(不包括音頻)實質(zhì)上就是一組幀圖片,經(jīng)過視頻編碼成為視頻(video)文件再把音頻(audio)文件有些還有字幕文件組裝在一起成為我們看到的視頻(movie)文件嫌术。1秒內(nèi)出現(xiàn)的圖片數(shù)就是幀率哀澈,圖片間隔越小畫面就越流暢,所以幀率越高效果就越好度气,需要的存儲空間也就越多割按。

視頻格式:
MP4、MOV磷籍、AVI适荣、RMVB這些播放格式其實都是封裝格式,除了RMVB比較特殊外院领,其他格式內(nèi)封裝的視頻編碼格式都是H264弛矛,H264以高壓縮率聞名于世,壓縮效率比MEPG-2提升一倍多比然,但是世上沒有兩全其美的事丈氓,H264的解碼難度提高了3倍多。

這兩個概念就足以為我自己掃盲了强法。我們之前接觸到的視頻文件万俗,其實我們不能單一把它當做一個文件,其實他是一種封裝饮怯。它包括了純粹的視頻闰歪,也就是一連串的圖片,包括音頻蓖墅,還可能包括了字幕库倘。

視頻錄制

我上網(wǎng)看了很多的文章,總結(jié)起來實現(xiàn)視頻的錄制有三種方法可以用论矾。

  1. UIImagePickerController
  2. AVCaptureSession + AVCaptureMovieFileOutput
  3. AVCaptureSession + AVAssetWriter

下面我們來分別說一下這三種方式的教翩。

第一種:UIImagePickerController是使用起來最簡單的,當然可定制化也是最低的贪壳,只能設(shè)置一些簡單的參數(shù)來實現(xiàn)基本的視頻錄制的效果迂曲。如果你想自定義錄制界面的UI,那你就只能拋棄這個簡單的方法了寥袭。

第二、三兩種方式要使用AVFoundation框架关霸。
在AVFoundation框架中传黄,關(guān)于視頻錄制的是要的類是AVCaptureSession,他負責調(diào)配輸入和輸出队寇,算是總的管理膘掰。單獨管理輸入的是AVCaptureDeviceInput這個類。

AVFoundation中類很多,一個類會有各種屬性识埋,用起來比較麻煩凡伊。我們第一次使用就先著重了解這個整體流程和主要的那幾個類。

第二種方法中使用了AVCaptureMovieFileOutput來作為輸出窒舟,這是一個需要很少配置就可以直接輸出視頻的類系忙,什么意思呢,也就是使用第二種AVCaptureSession + AVCaptureMovieFileOutput的方式錄制視頻惠豺,在你結(jié)束錄制之后银还,AVCaptureMovieFileOutput會幫你直接生成一個視頻文件到你指定的路徑下,好處就是便捷洁墙,直接輸出了視頻文件蛹疯。

第三種方法我個人覺得是最麻煩的,因為它處理的最原始的數(shù)據(jù)热监,而且視頻數(shù)據(jù)和音頻數(shù)據(jù)是分開處理捺弦,同時這也提高了這種方法的可定制性。

這種方法是通過AVCaptureVideoDataOutput和AVCaptureAudioDataOutput 分別拿到原始的視頻和音頻的數(shù)據(jù)孝扛,再進行處理列吼。我們拿到這些原始的數(shù)據(jù)流可以來為設(shè)置很多參數(shù),也可以添加背景音樂水印等疗琉。然后通過AVAssetWriter把這些數(shù)據(jù)流處理合成視頻文件冈欢。

當然了,第二和三兩種方法中盈简,我們還需要AVCaptureVideoPreviewLayer來實時預(yù)覽攝像頭的畫面凑耻。(也就是說我們攝像頭捕獲的畫面,是通過這個類來管理展示的)

代碼示例和DEMO

這部分具體的操作邏輯就是上面描述的這個樣子柠贤,主要的東西都在代碼上香浩。每個功能類的初始化,各種屬性配置臼勉,使用AVAssetWriter時數(shù)據(jù)時如何寫入的邻吭,這都是一個個麻煩的點。還好我從網(wǎng)上發(fā)現(xiàn)了一份特別棒的代碼宴霸,然后照著大神的代碼敲了一遍囱晴,然后針對我想實現(xiàn)的功能做了一點點修改,我把改后的代碼放到百度網(wǎng)盤了瓢谢。

這是我的DEMO畸写,大家可以下載來看

下面是第二種方法里面的一段代碼,從中可以看出整個流程來

#pragma mark - 主要過程
- (void)setUpWithType:(VideoViewType)type {
    /// -1. 提前異步創(chuàng)建存儲路徑 
    dispatch_async(dispatch_get_main_queue(), ^{
        [self videoFold];
    });
    
    ///0. 初始化捕捉會話氓扛,數(shù)據(jù)的采集都在會話中處理
    [self setUpInit];
    
    ///1. 設(shè)置視頻的輸入
    [self setUpVideo];
    
    ///2. 設(shè)置音頻的輸入
    [self setUpAudio];
    
    ///3.添加寫入文件的fileoutput
    [self setUpFileOut];
    
    ///4. 視頻的預(yù)覽層
    [self setUpPreviewLayerWithType:type];
    
    ///5. 開始采集畫面
    [self.session startRunning];
    
    
}

這個地方要聲明一下枯芬,那個第-1步提前異步創(chuàng)建存儲路徑是我加上的,之前代碼里面沒有,為什么要加這一步呢千所?

再點擊了開始錄制按鈕之后呢狂魔,會出現(xiàn)短暫的卡頓然后才開始錄制,我分析了一下可能是在第3步的時候有創(chuàng)建路徑的操作淫痰,大家都知道最楷,都文件的操作是比較耗時的,所以我才在最開始就先異步把路徑提前創(chuàng)建好了黑界,然后正真開始錄制的時候就會免去這一步耗時的操作管嬉,體驗好一些,當然這是我的想法朗鸠。

視頻錄制的細節(jié)功能

我們從項目開始講起吧 ~

項目結(jié)構(gòu)

這是項目結(jié)構(gòu)蚯撩,我提前聲明一下,那個RecordVideo文件中我是照著大神的FileOut文件中的代碼敲得(也就是視頻錄制的第二種方法)烛占,里面有一些小改動胎挎。然后針對第三種方法的代碼修改我都是直接在AVAssetWriter這個文件中直接改的。

下面是重點

原來這份代碼只是從三個方面實現(xiàn)了視頻錄制的功能忆家,三種方法實現(xiàn)的效果都是一樣的犹菇,就是簡單的視頻錄制。

但是在實際的項目中芽卿,我們有時候會遇到這么一個需求揭芍,那就是在錄制的過程中暫停,然后恢復錄制卸例。

我從網(wǎng)上看了一下称杨,找到了兩種實現(xiàn)方法。一種是通過暫停時候的時間偏移量計算來實現(xiàn)筷转,第二種是多段視頻拼接姑原。第一種我暫時還沒能深入的了解,所以我通過修改AVAssetWriter這個文件中的代碼呜舒,來實現(xiàn)一下多段視頻拼接的思路锭汛。

我的修改是這樣的:

  1. 點擊開始錄制是開始錄制第一段視頻,點擊停止的時候就停止錄制并生成第一段視頻 (之前是點擊了停止生成視頻直接跳到下一級頁面播放了)
  2. 再一次點擊開始錄制的時候袭蝗,開始錄制第二段唤殴,點擊停止時停止錄制并生成第二段。
  3. 以此類推
  4. 在view上我添加了一個錄制完成的button到腥,點擊這個button就開始把之前的多段視頻合成一段眨八。(點擊button之后注意看xcode的打印臺)
  5. 合成完成之后。直接跳轉(zhuǎn)到下一個頁面預(yù)覽我們生成的視頻文件左电。
示例頁面

視頻合成的代碼可以去FMWVideoView這個類中的下面方法中看,我給了很多注釋。

//////////////// 視頻合成////////////
- (void)showFiles{}

上面方法的代碼也有很多不足的地方篓足,比如說如果給整個視頻錄制規(guī)定一個最大時間長度段誊,上面實現(xiàn)的分段錄制并沒有收到這個最大時間的限制,這都是要進一步完善的地方栈拖,重點在于這個分段錄制合成的思路连舍。

兩點補充

  1. 使用AVAssetWriter完成視頻錄制

    在用AVAssetWriter實現(xiàn)錄制的時候,視頻數(shù)據(jù)和音頻數(shù)據(jù)分別是使用AVCaptureVideoDataOutput和AVCaptureAudioDataOutput來進行輸出涩哟,他與之前的AVCaptureMovieFileOutput輸出不同的是索赏,AVCaptureMovieFileOutput會直接輸出來視頻文件,但是AVCaptureVideoDataOutput和AVCaptureAudioDataOutput輸出的是原始的數(shù)據(jù)贴彼,再結(jié)合AVAssetWriter的把原始數(shù)據(jù)寫成文件的能力來實現(xiàn)整個錄制過程潜腻。

    AVAssetWriter實現(xiàn)錄制視頻相對來說麻煩一點,具體麻煩在把采集到的數(shù)據(jù)寫成文件的這個過程器仗。其實具體的實現(xiàn)流程并沒有什么難懂融涣,關(guān)鍵是這寫類的用法問題。還有在寫入文件時精钮,視頻和音頻是分開處理的威鹿。具體的用法,代碼寫的很清楚轨香,大家可以看一下忽你。

  2. 關(guān)于視頻更改背景音樂的思考

    上面說到兩個視頻合成一個視頻的例子,其實更改背景音樂用到的就是這種方法臂容。

    舉個例子說科雳,就像我們說過的,我們要把A和B兩個視頻合成一個新的視頻策橘,我們會創(chuàng)建一個視頻軌道一個音頻軌道炸渡,然后把A和B的視頻部分提取出來加到視頻軌道中,音頻部分提取出來加到音頻軌道中丽已,然后用這兩個軌道合成一個文件蚌堵。我們在更改背景音樂的時候,就是要處理這個音頻軌道沛婴,在這個音頻軌道中吼畏,我們不再是添加之前文件的音頻部分,而且把我們需要的那個背景音樂添加到音頻軌道中嘁灯,用添加了背景音樂的音頻軌道和視頻軌道合成視頻文件泻蚊。

    當然了,這里面還涉及一些是否保留原音丑婿,或者或者跟范圍有關(guān)的一些問題性雄,大家可以自己再研究一下没卸。

接下來學習

濾鏡效果。

特別感謝

特別感謝大神的代碼秒旋,不勝感激约计,附上大神的github主頁。
https://github.com/suifengqjn

參考文章

https://www.cnblogs.com/zy1987/p/4520118.html

http://gcblog.github.io/2017/03/22/iOS%E4%B8%89%E7%A7%8D%E5%BD%95%E5%88%B6%E8%A7%86%E9%A2%91%E6%96%B9%E5%BC%8F%E8%AF%A6%E7%BB%86%E5%AF%B9%E6%AF%94/

http://ios.jobbole.com/85069/

http://www.reibang.com/p/174bb4f539cc

音視頻相關(guān)的東西太多太多迁筛,我們一邊學習煤蚌,一邊領(lǐng)悟吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末细卧,一起剝皮案震驚了整個濱河市尉桩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贪庙,老刑警劉巖蜘犁,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異插勤,居然都是意外死亡沽瘦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門农尖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來析恋,“玉大人,你說我怎么就攤上這事盛卡≈恚” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵滑沧,是天一觀的道長并村。 經(jīng)常有香客問我,道長滓技,這世上最難降的妖魔是什么哩牍? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮令漂,結(jié)果婚禮上膝昆,老公的妹妹穿的比我還像新娘。我一直安慰自己叠必,他們只是感情好荚孵,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著纬朝,像睡著了一般收叶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上共苛,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天判没,我揣著相機與錄音蜓萄,去河邊找鬼。 笑死哆致,一個胖子當著我的面吹牛绕德,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摊阀,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼踪蹬!你這毒婦竟也來了胞此?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤跃捣,失蹤者是張志新(化名)和其女友劉穎漱牵,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疚漆,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡酣胀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了娶聘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闻镶。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖丸升,靈堂內(nèi)的尸體忽然破棺而出铆农,到底是詐尸還是另有隱情,我是刑警寧澤狡耻,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布墩剖,位于F島的核電站,受9級特大地震影響夷狰,放射性物質(zhì)發(fā)生泄漏岭皂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一沼头、第九天 我趴在偏房一處隱蔽的房頂上張望爷绘。 院中可真熱鬧,春花似錦瘫证、人聲如沸揉阎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毙籽。三九已至,卻和暖如春毡庆,著一層夾襖步出監(jiān)牢的瞬間坑赡,已是汗流浹背烙如。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毅否,地道東北人亚铁。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像螟加,于是被迫代替她去往敵國和親徘溢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355