FFmpeg 音视频倍速控制
網上關于FFmpeg音視頻倍速控制的資料不多,大部分都是講通過FFmpeg命令去做音視頻文件的倍速處理,通過FFmpeg api去 處理倍速的資料少之又少。
本文除了會講到通過命令行處理倍速,還會講到通過FFmpeg api的方式去處理音頻倍速和視頻倍速,進而合并成支持倍速的音視頻發布成rtmp或者存成flv文件。
介紹FFmpeg的filter工具
音視頻的倍速處理少不了filter這個工具,filter可以翻譯成過濾器和濾波器。
按照處理數據的類型還可分為音頻filter、視頻filter、字幕filter,FFmpeg可以通過filter將音視頻實現出非常多不同的filter效果,視頻可以實現縮放、合并、裁剪、旋轉、水印添加、倍速等效果,音頻可以實現回聲、延遲、去噪、混音、音量調節、變速等效果。
我們可以通過filter不同方式的組合去定制出我們想要的音視頻特效
介紹FFmpeg命令行倍速
1、視頻的倍速主要是通過控制filter中的setpts來實現,setpts是視頻濾波器通過改變每一個pts時間戳來實現倍速的效果,如下只要把PTS縮小一半就可以實現2倍速,相反的是PTS增加一倍就達到2倍慢放的效果。
ffmpeg?-i?in.mp4?-filter:v?"setpts=0.5*PTS"?out.mp4 ffmpeg?-i?in.mp4?-filter:v?"setpts=2.0*PTS"?out.mp42、音頻的倍速則是通過控制filter的atempo來實現,atempo的配置區間在0.5和2.0之間,如果需要更高倍速,則需要多個atempo串一起,下面是2、4倍速的實現命令。
ffmpeg?-i?in.mp4?-filter:"atempo=2.0"?-vn?out.mp4 ffmpeg?-i?in.mp4?-filter:"atempo=2.0,atempo=2.0"?-vn?out.mp43、同時對音視頻進行2倍速。
ffmpeg?-i?in.mp4?-filter_complex?"[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]"?-map?"[v]"?-map?"[a]"?out.mp4視頻倍速
視頻倍速可以通過filter的setpts來更改視頻的倍速,但是filter只對未編碼的原始視頻數據進行倍速處理。
我這邊對于視頻的處理是將H264進行格式封裝,如果使用filter的話,我還需要先對H264解碼,再做倍速轉換,再重新編碼成H264,這樣將會消耗相當多的資源。
我這邊對視頻倍速就沒必要用filter進行處理。其實視頻倍速只需要改變封裝格式時設置的時間戳就可以,所以我這邊只要改變video_tempo這個參數的值即可,1000是正常倍速、2000是2倍速,依次疊加。
if?(tempo?!=?video_tempo?&&?(tempo?>=?1000?&&?tempo?<=?16000))?{video_tempo?=?tempo;Logger::Info("video_tempo?=?%d",?video_tempo); }AVRational?time_base?=?{?1,?video_tempo};pkt.pts?=?av_rescale_q((ptsInc++)?*?2,?time_base,?ost->st->time_base);pkt.dts?=?av_rescale_q_rnd(pkt.dts,?ost->st->time_base,?ost->st->time_base,?(AVRounding)(AV_ROUND_NEAR_INF?|?AV_ROUND_PASS_MINMAX));pkt.duration?=?av_rescale_q(pkt.duration,?ost->st->time_base,?ost->st->time_base);音頻倍速
音頻倍速就需要用到filter進行處理了,我這邊對音頻的處理是,先解碼音頻,然后用filter進行倍速處理,對處理后的音頻數據進行重采樣再編碼成AAC的音頻格式。
如果只是對音頻做處理,不做音視頻封裝,可以直接把filter處理后的數據存成PCM,即可驗證音頻的倍速。
初始化filter的abuffer,aformat,abuffersink濾波器,abuffer用于接收輸入frame,形成待處理的數據緩存,abuffersink用于傳出輸出Frame,aformat過濾器約束最終的輸出格式(采樣率,聲道數,存儲位數等),而中間的其他過濾器可以串聯多個filter,如volume(音量調節),atempo(變速)等。
注冊所有過濾器
使用過濾器 將解碼后的AVFrame通過av_buffersrc_add_frame(in_ctx, pFrameAudio)加入到輸入過濾器上下文in_ctx中,通過av_buffersink_get_frame(out_ctx, pFrameAudio)獲取處理完成的pFrameAudio。pFrameAudio就可以直接存成PCM或者再編碼封裝音視頻格式。
動態修改倍速說明
本文由于封裝音視頻倍速的時候,視頻倍速處理是沒有通過filter去做的,只是改變視頻幀封裝的時間戳達到倍速效果.如果最開始是以正常速度的倍速推流,過程中再去修改倍速參數,就會導致要寫進的視頻時間戳大于之前的時間戳,進而出錯。
所以本文講的ffmpeg的API控制音視頻倍速是沒辦法通過動態調整倍速的。必須一開始就設置好倍速,后續就不能再改動。如果單獨對音頻進行動態修改倍速,則是沒問題的。
作者:RzzZ
來源:https://blog.csdn.net/qq_22633333/article/details/104967304
一個音視頻領域專業問答的小圈子!
推薦閱讀:
音視頻開發工作經驗分享 || 視頻版
OpenGL ES 學習資源分享
開通專輯 | 細數那些年寫過的技術文章專輯
Android NDK 免費視頻在線學習!!!
你想要的音視頻開發資料庫來了
推薦幾個堪稱教科書級別的 Android 音視頻入門項目
覺得不錯,點個在看唄~
總結
以上是生活随笔為你收集整理的FFmpeg 音视频倍速控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES-endpoint
- 下一篇: 长庆油田2021年油气当量突破6000万