【FFmpeg 快速入門】本地播放器 項目

目錄

🌈前言🌈 ? ?

📁 整體架構 +?詳細流程

📁 數據流向?

📁 隊列設計?編輯

📁 線程設計

?📁 音視頻同步

📁 音頻輸出設計

📁 視頻輸出設計

📁 總結


🌈前言🌈 ? ?

? ? ? ? 這篇文章是我在學習FFmpeg時,看到一位UP主的開源項目。我認為還是比較好認,通過和這個項目可以快速入門FFmpeg 7。

? ? ? ? 因為種種原因,目前網上關于FFmpeg 7.x?版本相關介紹太少,并且相較于之前版本,接口有很大變化,學習途中可能有很大困惱。因此,我希望通過這個項目和我的理解,帶大家快速入門FFmpeg以及7版本以上的接口使用流程。

? ? ? ? 這篇文章的圖片和源碼均來自B站UP主:程序員老廖音視頻入門必備項目-最新FFmpeg7.1播放器開發_嗶哩嗶哩_bilibili。

????????我也將該項目做了一遍,并且將源碼上傳至Gitee,大家可以直接進行下載。

AVPlayer: 本地音樂播放器(FFmpeg + SDL)

📁 整體架構 +?詳細流程

1. 初始化:創建并初始化必要的隊列、線程和組件。

2. 媒體處理:

? ? ? ? i. 解復用線程從文件讀取數據包。

? ? ? ?ii. 解碼線程將數據包解碼為幀。

? ? ? iii. 音視頻輸出模塊將幀渲染輸出。

3. 用戶交互: 處理用戶事件,如暫停、退出等。

4.? 資源釋放: 程序結束時按照正確的順序釋放資源,避免內存泄露

📁 數據流向

1. 解復用階段:
????????DemuxThread讀取媒體文件
????????分離音視頻數據包
????????將音視頻包放入對應的AVPacketQueue
2. 解碼階段:
????????DecodeThread從AVPacketQueue獲取數據包
????????使用FFmpeg解碼器解碼數據包
????????生成音視頻幀并放入AVFrameQueue
3. 渲染階段:
????????AudioOutput/VideoOutput從AVFrameQueue獲取幀
????????處理幀數據(重采樣、格式轉換等)
????????通過SDL渲染到輸出設備

📁 隊列設計

1. 模板設計:使用C++模板實現通用隊列結構,提高代碼復用率

2. 線程安全:使用互斥鎖和條件變量保證多線程環境下的數據一致性

3. 特化實現:為AVPacket和AVFrame提供特化隊列,處理FFmpeg資源的引用計數

4. 終止機制:通過abort標志控制隊列終止,實現優雅退出

5. 資源管理:

????????AVPacketQueue負責管理AVPacket資源,使用av_packet_free釋放
????????AVFrameQueue負責管理AVFrame資源,使用av_frame_free釋放

? ? ? ? 在Queue中加鎖解鎖的操作會用到兩個管理類 (當然可以都使用第二個):

std::lock_guard (簡單鎖):?
?? ??? ?1. 輕量級, 性能更高, 無額外開銷
?? ??? ?2. 嚴格作用域鎖: 不能手動控制
?? ??? ?3. 不可轉移所有權
?? ??? ?4. 不支持條件變量

std::unique_lock (靈活鎖):
?? ??? ?1. 功能更強大, 有額外的狀態存儲
?? ??? ?2. 支持手動的加鎖解鎖
?? ??? ?3. 支持所有權轉移
?? ??? ?4. 支持條件變量

📁 線程設計

1. 基類封裝:Thread基類封裝線程創建,啟動和停止的通用邏輯

2. 虛函數機制:通過純虛函數Run要求派生類實現具體的業務邏輯

3. 狀態控制:使用abort控制線程循環狀態,實現退出

4. 資源管理:

????????DemuxThread管理文件讀取和格式解析資源(AVFormatContext)
????????DecodeThread管理解碼器資源(AVCodecContext)

5. 線程協作

? ? ? ? 通過隊列實現線程間數據傳遞,解耦生產者和消費者

?📁 音視頻同步

1. 主時鐘選擇:
? ? ? ? i. 使用音頻PTS作為主時鐘基準
? ? ? ?ii. 音頻在回調函數中更新時鐘值
2. 視頻同步策略:
? ? ? ? i. 計算視頻幀PTS與當前音頻時鐘的差值
? ? ? ?ii. 差值為正(視頻超前):延遲顯示
? ? ? iii. 差值為負(視頻滯后):立即顯示
? ? ?iiii. 差值過大:考慮跳幀或重復幀

3. 時鐘管理:
? ? ? ? i. AVSync類提供時鐘讀寫接口
? ? ? ?ii. 音頻線程設置時鐘
? ? ? iii. 視頻線程讀取時鐘

? ? ? ? AVSync中記錄一個動態變差值,可以簡單理解為記錄音頻的pts。

為什么不能直接保存音頻的pts呢?

  1. ??pts只在音頻回調時更新??,而視頻可能在任意時刻查詢?GetClock()

    • 如果音頻回調間隔是 10ms,而視頻在兩次回調之間查詢?GetClock(),它拿到的?pts是 ??過時的??(沒有考慮這期間的時間流逝)。

    • ??結果??:視頻計算的時間偏差不準確,導致音畫不同步。

  2. ??無法處理音頻播放速度變化??(如加速、卡頓)。

    • 如果音頻因緩沖不足而卡頓,pts更新變慢,但系統時間仍在流逝。

    • 直接返回?_current_audio_pts無法反映這種延遲。

📁 音頻輸出設計

? ? ? ? 聲音輸出模塊負責從幀隊列取出音頻幀,進行必要的重采樣,并通過SDL輸出音頻。

1. 初始化流程:

? ? ? ? i. 初始化SDL音頻播放子系統

? ? ? ?ii. 設置音頻參數

? ? ? iii. 設置音頻回調函數

? ? ?iiii. 創建重采樣上下文(如果需要)

2. 回調機制:

? ? ? ? i. SDL音頻系統在需要數據時調用設置的回調函數

? ? ? ?ii. 回調函數從幀隊列獲取音頻幀

? ? ? iii. 根據需要進行重采樣 (使用SwrContext)

? ? ?iiii. 將處理后的音頻數據填充到SDL提供的緩沖區

3. 音頻時鐘:

? ? ? ? i. 以音頻PTS為主時鐘

? ? ? ?ii. 在每次回調中更新音頻時鐘

? ? ? iii. 作為視頻同步的基準

4. 資源管理:

? ? ? ? i. 管理重采樣上下文(SwrContext)

? ? ? ?ii. 管理音頻緩沖區

? ? ? iii. 在Delnit和析構函數中釋放資源

????????AVRational 是 FFmpeg 中用于表示 ??分數(有理數)?? 的結構體,主要用于時間基(time base)、幀率(frame rate)、采樣率(sample rate)等場景

📁 視頻輸出設計

????????畫面輸出模塊負責從幀隊列獲取視頻幀,與音頻同步,并通過SDL渲染到屏幕

1. 初始化流程:
????????初始化SDL視頻子系統
????????創建窗口和渲染器
????????創建紋理用于視頻渲染
2. 主循環機制:
????????處理SDL事件(如退出、按鍵等)
????????刷新視頻幀
????????控制幀率以實現音視頻同步
3. 同步策略:
????????比較視頻幀PTS與音頻時鐘
????????如果視頻超前,等待適當時間再顯示
????????如果視頻滯后,立即顯示并可能丟幀
4. 渲染過程:
????????將YUV數據更新到SDL紋理
????????將紋理渲染到窗口
????????釋放已顯示的幀

5. 資源管理:
????????管理SDL資源(窗口、渲染器、紋理)
????????在DeInit和析構函數中釋放資源

📁 總結

? ? ? ? 以上就是該項目的整體流程,相對來說還是比較簡單的。我認為將這個項目跑一邊,對于重點代碼寫一遍,那么對FFmpeg 7版本的接口就會有比較深刻的印象了,例如解封裝,解碼,轉碼等內容。

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

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

相關文章

Maven dependencyManagement標簽 properties標簽

dependencyManagement標簽properties標簽

前端埋坑之element Ui 組件el-progress display:flex后不顯示進度條解決方案

項目適用場景&#xff1a; <divs style"display&#xff1a;flex"> <span>這里是進度條前標題說明</span> <el-progress :percentage"50"></el-progress> </div> 問題呈現&#xff1a; el-progress進度條沒啦&#xf…

嵌入式學習-土堆PyTorch(7)-day23

損失函數的調用import torch from torch import nn from torch.nn import L1Lossinputs torch.tensor([1.0,2.0,3.0]) target torch.tensor([1.0,2.0,5.0])inputs torch.reshape(inputs, (1, 1, 1, 3)) target torch.reshape(target, (1, 1, 1, 3)) #損失函數 loss L1Loss…

【2025最新】使用neo4j實現GraphRAG所需的向量檢索

學習筆記&#xff0c;比較混亂&#xff0c;介意慎點。 背景 在將UMLS或者LightRAG構造的數據庫存入neo4j之后&#xff0c;我開始將知識圖譜運用到實際場景的使用中、例如查詢、推理。然而&#xff0c;由于字符串匹配導致大量術語在檢索時出現缺失。導致檢索效果不佳。我們需要…

【AI深究】隨機森林(Random Forest)全網最詳細全流程詳解與案例(附Python代碼演示)|集成學習|數學原理、案例流程、代碼演示及結果解讀|參數與調優、工程啟示、單棵決策樹的對比、優缺點

大家好&#xff0c;我是愛醬。本篇將會系統地講解隨機森林&#xff08;Random Forest&#xff09;的原理、核心思想、數學表達、算法流程、代碼實現與工程應用。內容適合初學者和進階讀者&#xff0c;配合公式和可視化示例。 注&#xff1a;本文章含大量數學算式、詳細例子說明…

6.String、StringBuffer、StringBuilder區別及使用場景

String固定長度&#xff0c;引用的字符串內容無法改變例如&#xff0c;String s abc;s def;那么 s 字符串對應的地址已經改變了StringBuider 聲明一個對象時&#xff0c;指向堆中的一塊空間&#xff0c;包括兩個屬性 value 和 count其中 value 屬性類似動態數組&#xff0c;可…

Qualcomm Linux 藍牙指南學習--驗證 Fluoride 協議棧的功能(2)

前言 Qualcomm Technologies推出的Linux藍牙指南詳細介紹了基于Qualcomm RB3 Gen 2和IQ-9100 Beta開發套件的藍牙解決方案。該文檔涵蓋BlueZ和Fluoride協議棧的功能驗證流程,支持藍牙5.2核心規范,包括WCN6750/WCN6856/QCA6698AQ芯片組的特性。主要內容分為三部分: ?1. 功…

Spring Boot中REST與gRPC并存架構設計與性能優化實踐指南

Spring Boot中REST與gRPC并存架構設計與性能優化實踐指南 在微服務架構日益復雜的當下&#xff0c;單一協議往往難以滿足高并發低延遲與生態兼容的雙重需求。本文基于真實生產環境的項目經驗&#xff0c;分享了如何在Spring Boot中同時提供RESTful API和gRPC接口的架構設計、性…

Simulink仿真-model Setting關鍵配置

1.概述 Simulink 的仿真設置&#xff08;Model Settings&#xff09;是確保仿真準確性的關鍵配置&#xff0c;主要包括仿真時間、步長、解法器選擇等核心參數的設定。 ?可以通過快捷鍵?CtrlE?打開仿真設置界面2.核心參數 2.1 求解器Solver配置 時間范圍&#xff1a;設置仿真…

內網與外網是通過什么進行傳輸的?內外網文件傳輸的安全方法

在當前企業信息化建設日益深入的背景下&#xff0c;出于安全防護與合規管理的需要&#xff0c;很多單位將網絡劃分為內網&#xff08;辦公網/生產網&#xff09;與外網&#xff08;互聯網/DMZ區&#xff09;。這種網絡隔離策略雖然提升了安全性&#xff0c;但也帶來了內外網文件…

RabbitMQ面試精講 Day 4:Queue屬性與消息特性

【RabbitMQ面試精講 Day 4】Queue屬性與消息特性 開篇 歡迎來到"RabbitMQ面試精講"系列的第4天&#xff01;今天我們將深入探討RabbitMQ中Queue的屬性配置與消息特性&#xff0c;這是理解和優化RabbitMQ使用的關鍵知識點。掌握這些內容不僅能幫助你在面試中展現深厚…

uniapp vue3 vite項目使用微信云開發(云函數)

1、在根目錄新建文件夾 cloudfunctions2、配置 manifest.json在項目根目錄的 manifest.json 文件中&#xff0c;找到微信小程序配置部分&#xff0c;添加 cloudfunctionRoot 字段&#xff0c;指向你的云函數目錄&#xff1a;{"mp-weixin": {"cloudfunctionRoot&…

AK視頻下載工具:免費高效,多平臺支持

近期小編又發現了一款更強大的新神器——AK視頻下載&#xff08;電腦版&#xff09;&#xff0c;一起來了解下吧~ 軟件亮點 完全免費&#xff0c;無需安裝&#xff0c;操作便捷&#xff0c;直接打開即可使用。 支持多平臺視頻下載&#xff0c;包括抖音、B站、小紅書、快手等主…

7月21日星期一今日早報簡報微語報早讀

7月21日星期一&#xff0c;農歷六月廿七&#xff0c;早報#微語早讀。1、廣東佛山累計報告基孔肯雅熱確診病例1873例&#xff0c;均為輕癥&#xff1b;2、祝賀&#xff01;石宇奇奪得日本羽毛球公開賽男單冠軍&#xff1b;3、中國和匈牙利順利完成引渡條約談判&#xff1b;4、科…

基于Milvus Lite的輕量級向量數據庫實戰指南

一、為什么選擇Milvus Lite&#xff1f; 在人工智能和語義搜索應用中&#xff0c;高效的向量檢索是核心需求。相比需要部署Docker的完整版Milvus&#xff0c;Milvus Lite提供&#xff1a; 零依賴&#xff1a;純Python實現&#xff0c;無需安裝Docker或外部組件 開箱即用&…

深度學習時代下的社交媒體情感分析:方法、工具與未來挑戰

摘要&#xff1a;基于Yue等學者2019年發表的權威綜述&#xff0c;本文系統總結情感分析的技術框架、實戰資源與前沿方向&#xff0c;附Python代碼示例。 一、情感分析為何重要&#xff1f; 情感分析&#xff08;Sentiment Analysis&#xff09;旨在從文本中提取主觀態度&…

Spring Boot 3.0新特性全面解析與實戰應用

Spring Boot 3.0新特性全面解析與實戰應用 引言 Spring Boot 3.0作為Spring生態系統的一個重要里程碑&#xff0c;帶來了眾多令人興奮的新特性和改進。本文將深入解析Spring Boot 3.0的核心變化&#xff0c;并通過實戰示例展示如何在項目中應用這些新特性。 核心變化概覽 Java版…

C# sqlsugar 主子表 聯合顯示 LeftJoin

在C#中使用SqlSugar ORM進行Left Join操作是一種常見需求&#xff0c;尤其是在處理復雜數據庫查詢時。SqlSugar是一個輕量級、高性能的ORM框架&#xff0c;支持多種數據庫。下面是如何使用SqlSugar進行Left Join操作的示例。1. 安裝SqlSugar首先&#xff0c;確保你的項目中已經…

【ROS1】08-ROS通信機制——服務通信

目錄 一、概念 二、何時使用服務 三、話題通信與服務通信的區別 四、案例 4.1 C實現 4.1.1 服務端 4.1.2 客戶端 4.1.3 測試執行 4.2 Python實現 4.2.1 服務端 4.2.2 客戶端 4.2.3 客戶端優化——動態傳參 4.2.4 客戶端優化——等待服務端啟動后再發起請求 一、概…

45.sentinel自定義異常

上文提到Blocked by Sentinel(flow limits) 限流異常,這樣返給用戶就不太友好,所以需要自定義異常。 默認情況下,發生限流、降級、授權攔截時,都會拋出異常到調用方。如果要自定義異常時的返回結果,需要實現BlockExceptionHandler接口: BlockException有很多子類: pac…