C#使用FFmpeg的總結

来源:https://www.cnblogs.com/ColorsWin/archive/2020/07/06/13252952.html
-Advertisement-
Play Games

上篇文章提到FFmpeg解決項目中視頻和語音問題,說道C#和FFmpeg不得不提的2個類庫。1、Xabe.FFmpeg簡單查看了下源碼和demo,發現基於ffmpeg.exe的命令行參數進行處理。2、FFmpeg.AutoGen 把C語言對外API和類型翻譯成C#的API和對象。看了一下這個源碼生成... ...


上篇文章提到FFmpeg解決項目中視頻和語音問題,說道C#和FFmpeg不得不提的2個類庫。

1、Xabe.FFmpeg

簡單查看了下源碼和demo,發現基於ffmpeg.exe的命令行參數進行處理。

2、FFmpeg.AutoGen

把C語言對外API和類型翻譯成C#的API和對象。

看了一下這個源碼生成,其中使用了CppSharp來生成g.cs的文件,然後在編譯g.cs文件。

這2類庫進行對比,第一個相對簡單,第二個需要瞭解的多和賦值,當然功能也強大。

最終選擇FFmpeg.AutoGen ,通過API方式控制靈活度更好,更能滿足自己的個性需求(推流要實現暫停和繼續推流功能)。

FFmpeg.AutoGen源碼不是每個版本都保留github上,只有一個master,所以最好克隆到自己項目中,不同版本的API差別還是有很大,穩定一個版本後即使有小問題,有源代碼可以自己修改一下。

項目中手機和電腦視頻採用的是rtmp方式推流,現在自己總結一下

開始說只需要視頻,當時就網上搜索一下 https://blog.csdn.net/vanjoge/article/details/79657874

在這個基礎稍微整理改進一下,交給客戶。然而沒有過多久提出新需,需要顯示聲音,為瞭解決這個問題花費不少時間

解決方式記錄如下:

一、使用ffplay.exe播放聲音,一直報錯沒有效果。


二、使用Vlc.DotNet能正常播放視頻和語音,但是聲音延遲7秒,隨著時間加長 有時候都延遲50多秒,

     另外在觀看視頻時候 隨時需要保存到本地,還需要單獨請求地址,明顯不符合要求。


三、在播放視頻基礎上,使用sdl2.Net播放聲音,死活沒有效果 。


四、參考網路C++代碼,寫C++動態庫讓C#來調用

    C#調用C++代碼,先簡單總結下後面準備寫個博客,有兩種常見方式調用 :

    1、調用純粹的C++庫裡面對外API ,即C#使用[DllImport("Test.dll")]方式。

    2、調用托管C++的庫,即C#直接引用。C++裡面添加一個類調用原始C++的方法,即創建一個類來簡單包裝一下。

  開始用第一種方式調用,就會出現多次調用視頻報錯問題,改為第二種方式new對象解決了第一種的問題,但又發現好多其他問題, 比如不同操作系統 需要生成不同的dll, 不應該選擇debug版本否則在不同電腦表現不一樣,最關鍵的是有些沒有及時釋放,視頻10分鐘後就崩了,總之對C++瞭解不多會遇到各種問題,被坑怕了。


五、網上找了一個C++封裝的播放器和者推流器然後提供給C#使用。

      該播放器是基於ffmpeg來實現的,播放器3萬,推流器也是3萬,核算一下覺得不是很划算,因為我現在遇到問題僅僅是聲音無法播放,而項目也不是很著急還有一段時間,也想挑戰一下自己。


六、主角上場,使用FFmpeg.AutoGen來操作API

   實在沒有更好的方法,決定用C#來進行,因為ffmpeg用C#的資料真的太少了,開始之前知道肯定比較費勁,想做的完美些就硬著頭皮來乾。經過一些時間努力實現了這些功能,很自豪的是這個視頻播放器延遲特別低,感覺是0延遲如果說有延遲基本也在1秒內左右,比市場上很多播放都快,比如這個著名播放器 PotPlayer。


    採用第六種方式後交給客戶,客戶很滿意,然後客戶給他們的客戶部署在生產環境中運行,客戶的客戶遇到一個問題 蘋果手機發送的語音,在電腦上播放是娃娃音。測試開發的時候是用安卓手機,因為手機端使用html5開發,發佈成app同樣的代碼就沒有仔細測試蘋果手機。在安卓手機沒有任何問題完美實現功能, 到了蘋果手機上就不行,心中一千個擦尼瑪,蘋果這樣坑開發者喜歡搞特殊 。後來發現採樣率不一樣特別是蘋果比較低的採樣率(32000)有這個問題,44100和48000常見的沒有問題,經過一段時間研究才給解決掉。


後續準備寫一些列文章來總結一下基於FFmpeg.AutoGen實現推流和拉流的功能,已經實現的功能主要包括下麵

拉流方面:

一、C# FFmpeg播放rtmp視頻(Bitmap或者BitmapSource來展示圖像)

二、C# FFmpeg使用SDL2方式播放rtmp視頻

三、C#FFmpeg使用NAudio方式播放rtmp音頻。

四、C#FFmpeg使用SDL2方式播放rtmp音頻。

五、C#FFmpeg實現rtmp播放器 NAudio播放聲音和(Bitmap或者BitmapSource來展示圖像)。

六、C# FFmpeg使用SDL2實現rtmp播放器

七、C#FFmpeg本地mp3,mp4文件播放(兩種方式SDL2和NAudio)

八、C#FFmpeg邊播放rtmp視頻,邊保存到本地文件。

拉流播放主要有兩個難點 

1、播放器播放網路rtmp地址 聲音和視頻不同步

2、C#FFmpeg播放本地文件,使用NAudio播放聲音緩存問題,

    由於本地解析很快緩存清理過導致快播放不完整,不清理緩存容易搞爆,比如播放60分鐘的mp3文件。


推流方面:

一、C#FFmpeg使用API推攝像頭和麥克風到rtmp遠程地址

二、C#FFmpeg使用API推桌面和麥克風到rtmp遠程地址

三、C#FFmpeg使用API推本地文件MP4,mkv到rtmp遠程地址.

四、C#FFmpeg使用API邊推流預覽邊保存本地文件

五、C#FFmpeg推流實現暫停功能









 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要介紹在使用阿裡雲Redis的開發規範,從下麵幾個方面進行說明。 鍵值設計 命令使用 客戶端使用 相關工具 通過本文的介紹可以減少使用Redis過程帶來的問題。 一、鍵值設計 1、key名設計 可讀性和可管理性 以業務名(或資料庫名)為首碼(防止key衝突),用冒號分隔,比如業務名:表名:id ...
  • 總結: 基本數據類型(瞭解) 整數 byte、short、int、long 浮點數 float、double 字元 char 布爾 boolean 類型轉換(瞭解) 數據範圍小的賦值給數據範圍大的會自動轉換 數據範圍大的賦值給數據範圍小用括弧括起來 大轉小會出現精度損失 一、數據類型 1. 電腦存 ...
  • 總結: 常量(掌握) 在程式運行過程中,其值不可以發生改變的量。 Java中的常量:字元串、整數、小數、字元、布爾、null 變數(掌握) 在程式運行過程中,其值可以發生改變的量。 變數的定義格式:數據類型 變數名 = 初始化值; 同一對{}中,定義變數名不能重覆 變數未賦值不能使用 定義long類 ...
  • 總結: 註釋(掌握) 單行註釋:// 多行註釋:/* */ 關鍵字(瞭解) 賦予了特殊含義的單詞 關鍵字的字母全部小寫 編輯器對關鍵字都有高亮顯示 標識符(掌握) 由字母、數字、下劃線“_”、美元符號“$”組成,第一個字元不能是數字 不能使用java中的關鍵字作為標識符 小駝峰式命名:變數名、方法名 ...
  • 1. Collection a) List (有序,可重覆) i. ArrayList底層用數組實現。線程不安全,效率高 ii. LinkedList:底層用雙向鏈表實現。線程不安全,效率高 ii. Vector:底層用數組實現。線程安全,效率低 b) Set (無序,不可重覆) HashSet(內 ...
  • 棧 1. 存放局部變數 2. 不可以被多個線程共用 3. 空間連續,速度快 堆 1. 存放對象 2. 可以被多個線程共用 3. 空間不連續,速度慢。但是靈活 方法區 1. 存放類的信息:代碼、靜態變數、字元串常量等 2. 可以被多個線程共用 3. 空間不連續,速度慢。但是靈活 ...
  • 1 前言 Docker是容器開發的事實標準,而Springboot是Java微服務常用框架,二者必然是會走到一起的。本文將講解如何開發Springboot項目,把它做成Docker鏡像,並運行起來。 2 把Springboot打包成Docker鏡像 Springboot的Web開發非常簡單,本次使用 ...
  • 方法重載(Overload): 兩同(同一個類、同一個方法名)三不同(參數列表不同:;類型、個數、順序) 返回值不同,構成重載嗎? No 形參名稱不同,構成重載嗎? No 方法重寫(0verride): 子類定義一個和父類方法名,參數完全相同的方法。 =: 方法名保持一致 >=: 子類許可權修飾符可以 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...