推流項目的ffmpeg配置和流程重點總結一下

????????

????????ffmpeg的初始化配置,在合成工作都是根據這個ffmpeg的配置來做的,是和成ts流還是flv,是推動遠端還是保存到本地,?FFmpeg 的核心數據結構,負責協調編碼、封裝和寫入操作。它相當于推流的“總指揮”。

? ? ? ? 先來看一下ffmpeg的推流器配置。


typedef struct
{AVStream *stream;    // 輸出流AVCodecContext *enc; // 編碼器int64_t next_timestamp; //下一個時間戳int samples_count;     // 采樣數AVPacket *packet;   // 編碼數據包
} OutputStream;typedef struct
{unsigned int config_id; //用與多路碼流int protocol_type; //流媒體TYPEchar network_addr[NETWORK_ADDR_LENGTH];//流媒體地址enum AVCodecID video_codec; //視頻編碼器IDenum AVCodecID audio_codec; //音頻編碼器IDOutputStream video_stream; //VIDEO的STREAM配置OutputStream audio_stream; //AUDIO的STREAM配置AVFormatContext *oc; //是存儲音視頻封裝格式中包含的信息的結構體,也是FFmpeg中統領全局的結構體,對文件的封裝、編碼操作從這里開始。
} RKMEDIA_FFMPEG_CONFIG; //FFMPEG配置

? ? ? ? 定義了我們流媒體的地址,和復合流是ts/flv等等。?

????????在使用 FFmpeg 實現推流的過程中,每個步驟都有其特定的作用,這些步驟是基于音視頻處理和網絡傳輸的基本原理設計的。以下是對每個主要步驟的詳細解釋,以及它們為什么必不可少:

1. 初始化網絡模塊 (avformat_network_init)

????????作用: 初始化 FFmpeg 的網絡功能,支持像 RTMP、HTTP 這樣的網絡協議。

????????為什么需要: FFmpeg 默認不加載網絡相關模塊,此步驟啟用網絡支持,確保推流到遠程服務器(如 RTMP 服務器)時能夠正確建立連接。如果不初始化,推流會因為缺少網絡協議支持而失敗。

????????原理: FFmpeg 的網絡功能依賴底層庫(如 librtmp 或內置的 TCP/UDP 實現),初始化會加載這些模塊并注冊相關協議。



2. 分配輸出格式上下文 (avformat_alloc_output_context2)

    //FLV_PROTOCOL is RTMP TCPif (ffmpeg_config->protocol_type == FLV_PROTOCOL){//初始化一個FLV的AVFormatContextret = avformat_alloc_output_context2(&ffmpeg_config->oc, NULL, "flv", ffmpeg_config->network_addr); if (ret < 0){return -1;}}//TS_PROTOCOL is SRT UDP RTSPelse if (ffmpeg_config->protocol_type == TS_PROTOCOL){//初始化一個TS的AVFormatContextret = avformat_alloc_output_context2(&ffmpeg_config->oc, NULL, "mpegts", ffmpeg_config->network_addr);if (ret < 0){return -1;}}

????????作用: 創建一個用于輸出的容器對象(AVFormatContext),并指定輸出格式(FLV/)。

????????為什么需要: 推流需要將音視頻數據封裝成某種格式(比如 FLV 是 RTMP 的常用容器格式),這個上下文對象管理流的元數據、格式信息和輸出目標。如果沒有這個對象,FFmpeg 無法知道數據要以什么形式輸出到哪里。
????????原理: 輸出格式上下文是 FFmpeg 的核心數據結構,負責協調編碼、封裝和寫入操作。它相當于推流的“總指揮”。


3. 創建輸出流 (avformat_new_stream)

    //是否指定了視頻編解碼器。if (fmt->video_codec != AV_CODEC_ID_NONE){// 添加一個流(如視頻流或音頻流),并為其分配編碼參數。ret = add_stream(&ffmpeg_config->video_stream, ffmpeg_config->oc, &video_codec, fmt->video_codec);if (ret < 0){avcodec_free_context(&ffmpeg_config->video_stream.enc);free_stream(ffmpeg_config->oc, &ffmpeg_config->video_stream);avformat_free_context(ffmpeg_config->oc);return -1;}ret = open_video(ffmpeg_config->oc, video_codec, &ffmpeg_config->video_stream, NULL);if (ret < 0){avformat_free_context(ffmpeg_config->oc);}}//是否指定了音頻編解碼器。if (fmt->audio_codec != AV_CODEC_ID_NONE){//添加一路視頻流ret = add_stream(&ffmpeg_config->audio_stream, ffmpeg_config->oc, &audio_codec, fmt->audio_codec);if (ret < 0){avcodec_free_context(&ffmpeg_config->audio_stream.enc);free_stream(ffmpeg_config->oc, &ffmpeg_config->audio_stream);avformat_free_context(ffmpeg_config->oc);return -1;}ret = open_audio(ffmpeg_config->oc, audio_codec, &ffmpeg_config->audio_stream, NULL);if (ret < 0){avformat_free_context(ffmpeg_config->oc);}}

?????????作用: 在輸出格式上下文中添加一個流(如視頻流或音頻流),并為其分配編碼參數。

????????為什么需要: 推流通常包含視頻和音頻兩種數據,每種數據需要獨立的流來承載。創建流是為了定義這些數據的結構(如分辨率、幀率、采樣率等),否則 FFmpeg 無法組織數據。

????????原理: 流(AVStream)是容器中的獨立軌道,推流時服務器和客戶端會根據流信息解碼數據

4. 打開輸出 URL (avio_open)

   if (!(fmt->flags & AVFMT_NOFILE)){//第四步:打開輸出文件/*** 作用: * 建立與目標服務器(如 RTMP 服務器)的物理連接。* 為什么需要: * 推流是將數據發送到遠程服務器的過程,必須先打開一個通道(類似于文件句柄或網絡 socket),* 否則數據無法傳輸。如果沒有這一步,程序會因為找不到輸出目標而報錯。* 原理: * avio_open 使用底層 I/O 抽象層(AVIOContext)與服務器通信,支持多種協議(如 RTMP、HLS)。* 對于 RTMP,它會通過 librtmp 初始化連接并完成握手。*/ret = avio_open(&ffmpeg_config->oc->pb, ffmpeg_config->network_addr, AVIO_FLAG_WRITE);if (ret < 0){free_stream(ffmpeg_config->oc, &ffmpeg_config->video_stream);free_stream(ffmpeg_config->oc, &ffmpeg_config->audio_stream);avformat_free_context(ffmpeg_config->oc);return -1;}}

????????作用: 建立與目標服務器(如 RTMP 服務器)的物理連接。

????????為什么需要: 推流是將數據發送到遠程服務器的過程,必須先打開一個通道(類似于文件句柄或網絡 socket),否則數據無法傳輸。如果沒有這一步,程序會因為找不到輸出目標而報錯

????????原理: avio_open 使用底層 I/O 抽象層(AVIOContext)與服務器通信,支持多種協議(如 RTMP、HLS)。對于 RTMP,它會通過 librtmp 初始化連接并完成握手


?

5. 寫入流頭部信息 (avformat_write_header)

    // 第五步:寫入文件頭信息//這行代碼會根據ffmpeg_config->oc中指定的輸出格式(如FLV或TS),//生成并寫入相應的頭部信息到輸出文件或流中。avformat_write_header(ffmpeg_config->oc, NULL);

????????作用: 將流的元數據(比如編碼格式、分辨率、時長等)寫入輸出流的開頭。

????????為什么需要: 接收端(比如直播服務器或播放器)需要這些信息來正確解析后續的數據。如果缺少頭部信息,接收端可能無法識別流格式,導致播放失敗。

????????原理: 頭部信息是容器格式(如 FLV)的標準部分,包含流的描述性數據,類似于文件的“索引”。?


6. 寫入數據 (av_interleaved_write_frame)

int write_ffmpeg_avpacket(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{/*將輸出數據包時間戳值從編解碼器重新調整為流時基 */av_packet_rescale_ts(pkt, *time_base, st->time_base);pkt->stream_index = st->index;/*** 第六步:寫入數據 * 作用: * 將編碼后的音視頻數據(AVPacket)寫入輸出流,發送到服務器。* 為什么需要: * 這是推流的核心步驟,所有的音視頻內容都通過這一步傳輸到目標。* 如果沒有這一步,之前的準備工作就毫無意義,因為數據沒有實際發送。* 原理: * FFmpeg 使用“交錯寫入”(interleaved)方式處理多路流(如視頻和音頻),確保時間戳對齊,符合實時傳輸的要求。* 數據會被封裝為 FLV 標簽(Tag)并通過網絡發送。*/return av_interleaved_write_frame(fmt_ctx, pkt);
}

????????作用: 將編碼后的音視頻數據(AVPacket)寫入輸出流,發送到服務器。

????????為什么需要: 這是推流的核心步驟,所有的音視頻內容都通過這一步傳輸到目標。如果沒有這一步,之前的準備工作就毫無意義,因為數據沒有實際發送。

????????原理: FFmpeg 使用“交錯寫入”(interleaved)方式處理多路流(如視頻和音頻),確保時間戳對齊,符合實時傳輸的要求。數據會被封裝為 FLV 標簽(Tag)并通過網絡發送。



7. 寫入流尾部 (av_write_trailer)

    //第7步: 寫入流尾部 (av_write_trailer)/*** * 作用: 標記流的結束,并寫入必要的結尾信息*/av_write_trailer(ffmpeg_config.oc); // 寫入AVFormatContext的尾巴

????????作用: 標記流的結束,并寫入必要的結尾信息。

????????為什么需要: 某些容器格式需要在結束時添加元數據(如索引表),以確保接收端能正確處理整個流。如果不寫入尾部,流可能會出現不完整或無法播放的問題。

????????原理: 尾部信息是容器格式規范的一部分,對于 FLV 來說,它可能只是簡單地關閉流,但對于其他格式(如 MP4),它可能包含關鍵的索引。


8. 清理資源 (avio_closep, avformat_free_context)

   //第八步:清理資源 (avio_closep, avformat_free_context)/*** * 作用: 關閉網絡連接并釋放內存*/free_stream(ffmpeg_config.oc, &ffmpeg_config.video_stream); // 釋放VIDEO_STREAM的資源free_stream(ffmpeg_config.oc, &ffmpeg_config.audio_stream); // 釋放AUDIO_STREAM的資源avio_closep(&ffmpeg_config.oc->pb);                         // 釋放AVIO資源avformat_free_context(ffmpeg_config.oc);                    // 釋放AVFormatContext資源

????????作用: 關閉網絡連接并釋放內存。
????????為什么需要: 推流結束后,如果不清理資源,會導致內存泄漏或網絡連接未正確關閉,影響程序穩定性。對于長時間運行的推流任務尤其重要。
????????原理: FFmpeg 的上下文對象和 I/O 句柄占用系統資源(如內存和 socket),需要顯式釋放以遵循良好的編程實踐。


整體工作流程的意義,這些步驟共同構成了 FFmpeg 推流的完整工作流,反映了音視頻處理和網絡傳輸的本質:

?? ?1.?? ?準備階段: 初始化環境、定義格式和目標(步驟 1-3)。
?? ?2.?? ?連接階段: 建立與服務器的通信(步驟 4)。
?? ?3.?? ?傳輸階段: 發送元數據和實際數據(步驟 5-6)。
?? ?4.?? ?結束階段: 完成傳輸并清理(步驟 7-8)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72685.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72685.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72685.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大語言模型從理論到實踐(第二版)-學習筆記(緒論)

大語言模型的基本概念 1.理解語言是人工智能算法獲取知識的前提 2.語言模型的目標就是對自然語言的概率分布建模 3.詞匯表 V 上的語言模型&#xff0c;由函數 P(w1w2 wm) 表示&#xff0c;可以形式化地構建為詞序列 w1w2 wm 的概率分布&#xff0c;表示詞序列 w1w2 wm…

strace工具的交叉編譯

1、下載源碼 git clone https://github.com/strace/strace.git cd strace 2、運行 bootstrap 腳本&#xff08;如果需要&#xff09; 如果源碼中沒有 configure 腳本&#xff0c;運行以下命令生成&#xff1a; ./bootstrap 3. 配置編譯參數 運行 configure 腳本&#xff…

Vue 3 組件庫持續集成 (CI) 實戰:GitHub Actions 自動化測試與 Storybook 文檔構建 - 構建高效可靠的組件庫 CI 流程

引言 歡迎再次回到 Vue 3 + 現代前端工程化 系列技術博客! 在昨天的第十篇博客中,我們深入學習了代碼覆蓋率分析,掌握了利用 Jest 代碼覆蓋率報告提升單元測試有效性的方法,進一步鞏固了組件庫的質量防線。 今天,我們將邁向 自動化流程 的構建,聚焦于 持續集成 (Continu…

無穿戴動捕數字人互動方案 | 暢享零束縛、高沉浸的虛實交互體驗

在數字化浪潮席卷而來的當下&#xff0c;虛擬人互動體驗正逐漸成為各領域的新寵。長久以來&#xff0c;虛擬人驅動主要依靠穿戴式動作捕捉設備&#xff0c;用戶需要通過佩戴傳感器或標記點來實現動作捕捉。然而&#xff0c;隨著技術的不斷突破&#xff0c;一種全新的無穿戴動作…

03 HarmonyOS Next儀表盤案例詳解(二):進階篇

溫馨提示&#xff1a;本篇博客的詳細代碼已發布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下載運行哦&#xff01; 文章目錄 前言1. 響應式設計1.1 屏幕適配1.2 彈性布局 2. 數據展示與交互2.1 數據卡片渲染2.2 圖表區域 3. 事件處理機制3.1 點擊事件處理3.2 手勢…

python-leetcode-統計構造好字符串的方案數

2466. 統計構造好字符串的方案數 - 力扣&#xff08;LeetCode&#xff09; 這個問題可以用**動態規劃&#xff08;DP&#xff09;**來解決&#xff0c;思路如下&#xff1a; 思路 1. 定義 DP 數組 設 dp[i] 表示長度為 i 的好字符串的個數。 2. 狀態轉移方程 我們可以在 dp…

MySQL------存儲引擎和用戶和授權

9.存儲引擎 1.兩種引擎 MyISAM和InnoDB 2.兩種區別 1.事務&#xff1a; MyISAM不支持事務 2.存儲文件: innodb : frm、ibd MyISAM: frm、MYD、MYI 3.數據行鎖定: MyISAM不支持 4.全文索引: INNODB不支持&#xff0c;所以MYISAM做select操作速度很快 5.外鍵約束: MyISAM…

題海拾貝:P9241 [藍橋杯 2023 省 B] 飛機降落

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》 歡迎點贊&#xff0c;關注&#xff01; 1、題…

刪除有序數組中的重復項(js實現,LeetCode:26)

給你一個 非嚴格遞增排列 的數組 nums &#xff0c;請你原地刪除重復出現的元素&#xff0c;使每個元素只出現一次&#xff0c;返回刪除后數組的新長度。元素的相對順序應該保持一致。然后返回 nums 中唯一元素的個數。 考慮 nums 的唯一元素的數量為 k &#xff0c;你需要做以…

3-9 WPS JS宏單元格復制、重定位應用(拆分單表到多表)

************************************************************************************************************** 點擊進入 -我要自學網-國內領先的專業視頻教程學習網站 *******************************************************************************************…

大白話react第十六章React 與 WebGL 結合的實戰項目

大白話react第十六章React 與 WebGL 結合的實戰項目 1. 項目簡介 React 是一個構建用戶界面的強大庫&#xff0c;而 WebGL 則允許我們在網頁上實現高性能的 3D 圖形渲染。將它們結合起來&#xff0c;我們可以創建出炫酷的 3D 網頁應用&#xff0c;比如 3D 產品展示、虛擬場景…

【AI賦能】AI 工具生成視頻教材:從創意到成品的全流程指南

AI 工具生成視頻教材&#xff1a;從創意到成品的全流程指南 目標 通過本教材&#xff0c;您將學會如何利用 AI 工具&#xff08;Grok、Sora、Speechify 和 CapCut&#xff09;生成一個完整的視頻&#xff0c;包括腳本生成、視頻片段制作、字幕添加、音頻生成以及最終剪輯合成…

C/C++藍橋杯算法真題打卡(Day2)

一、面試題 08.01. 三步問題 - 力扣&#xff08;LeetCode&#xff09; 算法代碼&#xff1a; class Solution { public:const int MOD 1e9 7;int waysToStep(int n) {// 1. 創建 dp 表// 2. 初始化// 3. 填表// 4. 返回// 處理邊界情況if (n 1 || n 2)return n;if (n 3)r…

騰訊云物聯網平臺(IoT Explorer)設備端使用

1、直接看圖流程 2、跑起來demo,修改產品id,設備名稱,設備秘鑰。 3、連接部分 4、修改默認地址和端口 sdk里面的地址默認是帶著產品ID拼接的,咱們現在中鐵沒有泛域名解析,要改下這里。把+productID都去掉,然后地址里的.也去掉。

GStreamer —— 2.13、Windows下Qt加載GStreamer庫后運行 - “教程13:播放控制“(附:完整源碼)

運行效果(音頻) 簡介 上一個教程演示了GStreamer工具。本教程介紹視頻播放控制。快進、反向播放和慢動作都是技術 統稱為 Trick Modes&#xff0c;它們都有一個共同點 修改 Normal playback rate。本教程介紹如何實現 這些效果并在交易中添加了幀步進。特別是&#xff0c;它 顯…

Dify+DeepSeek | Excel數據一鍵可視化(創建步驟案例)(echarts助手.yml)(文檔表格轉圖表、根據表格繪制圖表、Excel繪制圖表)

Dify部署參考&#xff1a;Dify Rag部署并集成在線Deepseek教程&#xff08;Windows、部署Rag、安裝Ragan安裝、安裝Dify安裝、安裝ollama安裝&#xff09; DifyDeepSeek - Excel數據一鍵可視化&#xff08;創建步驟案例&#xff09;-DSL工程文件&#xff08;可直接導入&#x…

vscode mac版本 配置git

首先使用 type -a git查看git的安裝目錄 然后在vscode中找到settings配置文件&#xff0c;修改git.path

JVM與性能調優詳解

以下是關于 JVM與性能調優 的詳細解析&#xff0c;結合理論、實踐及常見問題&#xff0c;分多個維度展開&#xff1a; 一、JVM性能調優的核心目標 性能調優的核心目標是通過優化內存管理、垃圾回收&#xff08;GC&#xff09;策略和線程管理&#xff0c;實現以下平衡&#xff…

Vue23Web 基礎性拉滿的面試題(2025版)還沒更新完...

Vue2&3 基礎性1. 關於Vue2和Vue3生命週期的差別2. Vue2&3組件之間傳參不同點Vue2 傳遞與接收Vue3 傳遞與接收 (使用script setup語法糖)Vue3 傳遞與接收 (不使用script setup語法糖) 3. Vue2&3 keep-alive 組件Vue2 keep-aliveVue3 keep-alive 進階性爲什麼POST請求…

基于SpringBoot實現旅游酒店平臺功能一

一、前言介紹&#xff1a; 1.1 項目摘要 隨著社會的快速發展和人民生活水平的不斷提高&#xff0c;旅游已經成為人們休閑娛樂的重要方式之一。人們越來越注重生活的品質和精神文化的追求&#xff0c;旅游需求呈現出爆發式增長。這種增長不僅體現在旅游人數的增加上&#xff0…