史林楓:C#.NET利用ffmpeg操作視頻實戰(格式轉換,加水印 一步到位)

来源:http://www.cnblogs.com/jayshsoft/archive/2016/01/02/csharp_ffmpeg.html
-Advertisement-
Play Games

C#實操FFmpeg的過程記錄


ffmpeg.exe是大名鼎鼎的視頻處理軟體,以命令行參數形式運行。網上也有很多關於ffmpeg的資料介紹。但是在用C#做實際開發時,卻遇到了幾個問題及註意事項,比如如何無損處理視頻?如何在轉換格式的同時添加水印,以提升處理效率?,ffmpeg的版本應該選擇什麼版本?。今天史林峰將用實戰的方式來探索C#操作ffmpeg的奧秘。

關於ffmpeg的使用及其參數命令,這裡就不做過多介紹了。主要以項目實戰中為主。

因工作需要,筆者手頭有近300部短視頻需要處理,在網上找了不少工具,雖然能用,但是用起來卻有一種Hold不住的感覺。要麼是處理後有軟體水印或片花,要麼是不能直接批量一次性處理完,視頻要一個一個地去設置。

這裡主要需求是給現有的視頻做格式轉換,如果視頻格式已經滿足要求,就直接在指定位置加水印(png圖片),在處理完之後,為瞭解決磁碟空間,在視頻處理完成之後要刪除原視頻。筆者對C#語言是最熟知的,因此選用C# Winform做一個簡易的視頻批處理軟體。

先上一張完工的項目截圖:

 

 

在指定目錄中讀取視頻,然後一件處理即可(中間的截取秒數的參數,屬於視頻剪切,暫時沒有這塊功能)

 

現有的視頻均為flv格式的,通過C#調用ffmpeg,轉換為mp4格式,並添加水印

C#調用ffmpeg的方法封裝如下:

 1 /// <summary>
 2 /// 視頻處理器ffmpeg.exe的位置
 3 /// </summary>
 4 public string FFmpegPath { get; set; }
 5  
 6 /// <summary>
 7 /// 調用ffmpeg.exe 執行命令
 8 /// </summary>
 9 /// <param name="Parameters">命令參數</param>
10 /// <returns>返回執行結果</returns>
11 private string RunProcess(string Parameters)
12 {
13 //創建一個ProcessStartInfo對象 並設置相關屬性
14 var oInfo = new ProcessStartInfo(FFmpegPath, Parameters);
15 oInfo.UseShellExecute = false;
16 oInfo.CreateNoWindow = true;
17 oInfo.RedirectStandardOutput = true;
18 oInfo.RedirectStandardError = true;
19 oInfo.RedirectStandardInput = true;
20  
21 //創建一個字元串和StreamReader 用來獲取處理結果
22 string output = null;
23 StreamReader srOutput = null;
24  
25 try
26 {
27     //調用ffmpeg開始處理命令
28     var proc = Process.Start(oInfo);
29  
30     proc.WaitForExit();
31  
32  
33     //獲取輸出流
34     srOutput = proc.StandardError;
35  
36     //轉換成string
37     output = srOutput.ReadToEnd();
38  
39     //關閉處理程式
40     proc.Close();
41 }
42 catch (Exception)
43 {
44     output = string.Empty;
45 }
46 finally
47 {
48     //釋放資源
49     if (srOutput != null)
50     {
51         srOutput.Close();
52         srOutput.Dispose();
53     }
54 }
55 return output;
56 }
View Code

 

轉換格式的命令參數:-i orignal.flv -y -b 1024k -acodec copy -f mp4 newFile.mp4

添加水印的命令參數:-i orignal.flv -i water.png -filter_complex \"overlay=10:10\" newFile.flv

參數簡要說明和細節提示:

orignal.flv : 要處理的原始視頻文件(最好是絕對路徑)
-y : 覆蓋已有文件(註意,加水印不可覆蓋原始文件,否則只能生成1秒的視頻)
-b:視頻的碼率 這裡設置1024k 基本可滿足無損處理 如不設置-b參數則預設為200k 視頻會非常模糊
-acodec copy : 保持音頻質量不變
-f mp4 : 表示轉換的視頻格式
 
-i water.png : 水印圖片路徑
overlay=10:10 : 水印距離視頻的左上角坐標
其他位置參數:
右上角:main_w-overlay_w-10:10
左下角:10:main_h-overlay_h-10
右下角:main_w-overlay_w-10:main_h-overlay_h-10
 
newFile.mp4  要保存的文件路徑

 

上面這個方法就是核心處理。筆者在實際執行的過程中,發現了以下問題:

 

  在使用cmd視窗執行以上命令時(cmd中參數前面要加 ffmpeg 註意文件位置),可以成功處理,但在運行Winform測試的時候,發現只有一個大小為0kb的新文件生成,但遲遲不見處理。給人一種假死的現象。而當筆者關掉調試的Winform程式時,過幾秒鐘,貌似ffmpeg.exe 又起作用了,文件處理成功了。這個不得其解。(在調用處理程式時,新開了一個線程執行的)

排查情況:

  可能是ffmpeg的版本問題,於是下載了2.8.2版本(應該是最新的),測試,沒有任何變化

  檢查程式的調用流程,將調用過程cmd視窗顯示出來。結果一片空白,什麼也沒有,依然是沒有效果。

最後在經過各種資料的查找之後,在不經意間看到有人說 proc.WaitForExit(); 這句執行會造成程式一直處於等待狀態。是的,沒錯,以前做類似程式調用也是這樣做的,也沒出現過這種問題。於是,抱著試試看的態度,註釋了這一句。當然,程式不再等待執行完畢,proc.Close(); 這一句也要註釋一下。測試結果成功!!(懂得底層原理的大牛,望告知一二)

 

問題解決了,但是還有一個處理效率的問題:如何更快的處理?

筆者嘗試了各種命令的組合,發現對於不同版本的ffmpeg,有的參數是不能使用的,就筆者使用的2.8.2版本最終 找了一個比較好的解決方案:

可以選擇使用以下命令參數:

-i orignal.flv -i water.png -filter_complex \"overlay=10:10\" -y -b 1024k -acodec copy -f mp4

 

-i orignal.flv -i water.png -filter_complex \"overlay=10:10\" -b 1024k -acodec copy

 

上面一個適合同時轉換格式和加水印

下麵一個適合只加水印,不做格式轉換

這些核心問題解決了,剩下的就是文件的讀取,保存,判斷等等細節了。

 

總結:                                                          

  1. C#調用ffmpeg時 不要使用proc.WaitForExit();方法,否則會假死

  2. ffmpeg的版本最好使用最新版本,並參考命令參數說明

  3. 無損轉換,無損加水印 要註意保證視頻的碼率 和音頻的參數(直接copy,視頻不能這樣寫-avcodec copy  會報錯,只能用-b設置視頻碼率) 

  4. 一步到位的處理方法(轉換的同時加水印,參考上面的命令參數)

 

程式開發好之後,筆者不用再苦逼地一個一個去設置,處理了,電腦開著,顯示器關閉,只聽見主機嗷嗷叫的處理,等吃完飯,所有事情均已搞定。。。

 

 

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 一:故事背景 以前在寫WebApi2的時候,一直是用作前後端分離(WebApi2 +angularjs),可是最近自己在給WebApp寫介面的時候遇到了很多坑,總結一下就是跨域問題。而跨域問題在WebApi2中配置也是有點麻煩,不知道在2中是否有對jsonp跨域問題更好解決方案,如果有,跪求各位博....
  • 《重構》這本書的代碼都是java,我準備用C#來一遍。而今天我的主要任務是寫一大段垃圾代碼出來,然後重構(僅限於函數的,不涉及到其它方面的重構)。程式界面:功能介紹:俠客名字自己取,然後點擊按鈕隨機角色的屬性,根骨,經脈,柔韌,悟性等四項屬性值都是隨機而來。其他的都是由這四個屬性計算而來:根骨:影響...
  • Technorati 標記: http 代理驗證及測試Technorati 標記: C#參考了網上很多資料,綜合整理出來最終的代碼:using System; using System.Collections; using System.Collections.Generic; using Syst...
  • 使用NuGet安裝Nancy和直接引用源碼項目存在一些差異,如序列化,授權驗證問題。如果引用源碼的話,自定義JsonSerializer,如下:註意,需要使用NuGet安裝Newtonsoft.Json public class CustomJsonNetSerializer : JsonSeria...
  • 1、新建UserDatabase類,實現IUserMapper介面 using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using S...
  • 轉眼2015年已經過去,我們有跌跌撞撞的闖入了2016年!看湖南衛視的跨年演唱會時何老師說“大家好好想一想2015年你收穫了什麼?” 回想2015年還是有些收穫的。從8月份的什麼都不懂到現在經過五個多月的學習已經可以獨立完成一個簡單的KTV點歌系統了(雖然不能聯網)!我覺得這就是我2015年最大的收...
  • 多線程編程相對於單線程會出現一個特有的問題,就是線程安全的問題。為了保證多線程情況下,訪問靜態變數的安全,除了可以用鎖機制的方式外,還可以採用另外一種新的方式來處理
  • var關鍵字是.net3.5推出的關鍵字,主要是讓編譯器自動推斷並判斷變數類型,類似javascript中的var。在使用一些性能優化軟體時,在代碼優化時,我發現不管定義什麼類型的變數,變數的類型都統統換成var。難道var的性能比具體的類型和object都要高?實踐出真知:新建一個控制台應用程式 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...