日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FFmpeg 音视频倍速控制

發布時間:2024/1/1 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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.mp4

2、音頻的倍速則是通過控制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.mp4

3、同時對音視頻進行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(變速)等。

  • int?init_atempo_filter(AVFilterGraph?**pGraph,?AVFilterContext?**src,?AVFilterContext?**out,?char?*value) {//初始化AVFilterGraphAVFilterGraph?*graph?=?avfilter_graph_alloc();//獲取abuffer用于接收輸入端const?AVFilter?*abuffer?=?avfilter_get_by_name("abuffer");AVFilterContext?*abuffer_ctx?=?avfilter_graph_alloc_filter(graph,?abuffer,?"src");//設置參數,這里需要匹配原始音頻采樣率8000、數據格式(位數:16)、單聲道if?(avfilter_init_str(abuffer_ctx,?"sample_rate=8000:sample_fmt=s16:channel_layout=mono")?<?0)?{Logger::Error("error?init?abuffer?filter");return?-1;}//初始化atempo?filterconst?AVFilter?*atempo?=?avfilter_get_by_name("atempo");AVFilterContext?*atempo_ctx?=?avfilter_graph_alloc_filter(graph,?atempo,?"atempo");//這里采用av_dict_set設置參數AVDictionary?*args?=?NULL;av_dict_set(&args,?"tempo",?value,?0);//這里傳入外部參數,可以動態修改if?(avfilter_init_dict(atempo_ctx,?&args)?<?0)?{Logger::Error("error?init?atempo?filter");return?-1;}const?AVFilter?*aformat?=?avfilter_get_by_name("aformat");AVFilterContext?*aformat_ctx?=?avfilter_graph_alloc_filter(graph,?aformat,?"aformat");if?(avfilter_init_str(aformat_ctx,?"sample_rates=8000:sample_fmts=s16:channel_layouts=mono")?<?0)?{Logger::Error("error?init?aformat?filter");return?-1;}//初始化sink用于輸出const?AVFilter?*sink?=?avfilter_get_by_name("abuffersink");AVFilterContext?*sink_ctx?=?avfilter_graph_alloc_filter(graph,?sink,?"sink");if?(avfilter_init_str(sink_ctx,?NULL)?<?0)?{//無需參數Logger::Error("error?init?sink?filter");return?-1;}//鏈接各個filter上下文if?(avfilter_link(abuffer_ctx,?0,?atempo_ctx,?0)?!=?0)?{Logger::Error("error?link?to?atempo?filter");return?-1;}if?(avfilter_link(atempo_ctx,?0,?aformat_ctx,?0)?!=?0)?{Logger::Error("error?link?to?aformat?filter");return?-1;}if?(avfilter_link(aformat_ctx,?0,?sink_ctx,?0)?!=?0)?{Logger::Error("error?link?to?sink?filter");return?-1;}if?(avfilter_graph_config(graph,?NULL)?<?0)?{Logger::Error("error?config?filter?graph");return?-1;}*pGraph?=?graph;*src?=?abuffer_ctx;*out?=?sink_ctx;Logger::Info("init?filter?success...");return?0; }
  • 注冊所有過濾器

  • avfilter_register_all();if?(init_atempo_filter(&s_graph,?&in_ctx,?&out_ctx,?"1.0")?!=?0)?{Logger::Error("Codec?not?init?audio?filter");return?-1;}
  • 使用過濾器 將解碼后的AVFrame通過av_buffersrc_add_frame(in_ctx, pFrameAudio)加入到輸入過濾器上下文in_ctx中,通過av_buffersink_get_frame(out_ctx, pFrameAudio)獲取處理完成的pFrameAudio。pFrameAudio就可以直接存成PCM或者再編碼封裝音視頻格式。

  • //將pFrameAudio放入輸入filter上下文if?(av_buffersrc_add_frame(in_ctx,?pFrameAudio)?<?0)?{Logger::Error("error?add?frame");}//從輸出filter上下文中獲取pFrameAudiowhile?(av_buffersink_get_frame(out_ctx,?pFrameAudio)?>=?0)?{break;}

    動態修改倍速說明

    本文由于封裝音視頻倍速的時候,視頻倍速處理是沒有通過filter去做的,只是改變視頻幀封裝的時間戳達到倍速效果.如果最開始是以正常速度的倍速推流,過程中再去修改倍速參數,就會導致要寫進的視頻時間戳大于之前的時間戳,進而出錯。

    所以本文講的ffmpeg的API控制音視頻倍速是沒辦法通過動態調整倍速的。必須一開始就設置好倍速,后續就不能再改動。如果單獨對音頻進行動態修改倍速,則是沒問題的。

    作者:RzzZ

    來源:https://blog.csdn.net/qq_22633333/article/details/104967304

    一個音視頻領域專業問答的小圈子!

    推薦閱讀:

    音視頻開發工作經驗分享 || 視頻版

    OpenGL ES 學習資源分享

    開通專輯 | 細數那些年寫過的技術文章專輯

    Android NDK 免費視頻在線學習!!!

    你想要的音視頻開發資料庫來了

    推薦幾個堪稱教科書級別的 Android 音視頻入門項目

    覺得不錯,點個在看唄~

    總結

    以上是生活随笔為你收集整理的FFmpeg 音视频倍速控制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。