C#調(diào)用FFmpeg操作音視頻的實現(xiàn)示例
項目背景
因為公司需要對音視頻做一些操作,比如說對系統(tǒng)用戶的發(fā)音和背景視頻進(jìn)行合成,以及對多個音視頻之間進(jìn)行合成,還有就是在指定的源背景音頻中按照對應(yīng)的規(guī)則在視頻的多少秒鐘內(nèi)插入一段客戶發(fā)音等一些復(fù)雜的音視頻操作。本篇文章主要講解的是使用C#進(jìn)程(Process)調(diào)用FFmpeg.exe進(jìn)行視頻合并,音頻合并,音頻與視頻合并成視頻這幾個簡單的音視頻操作,還有些復(fù)雜的音視頻操作后續(xù)有時間慢慢補上。
FFmpeg介紹
FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計算機程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多code都是從頭開發(fā)的。
FFmpeg在Linux平臺下開發(fā),但它同樣也可以在其它操作系統(tǒng)環(huán)境中編譯運行,包括Windows、Mac等多平臺。這個項目最早由Fabrice Bellard發(fā)起,2004年至2015年間由Michael Niedermayer主要負(fù)責(zé)維護(hù)。許多FFmpeg的開發(fā)人員都來自MPlayer項目,而且當(dāng)前FFmpeg也是放在MPlayer項目組的服務(wù)器上。項目的名稱來自MPEG視頻編碼標(biāo)準(zhǔn),前面的"FF"代表"Fast Forward"。 FFmpeg編碼庫可以使用GPU加速。
FFmpeg相關(guān)教程
開始之初你首先要了解FFmpeg是什么,有哪些常用的命令和實用的功能。
博客示例源碼
https://github.com/YSGStudyHards/FFmpegAudioAndVideoMerge
下載FFmpeg.exe安裝包
首先把下載下來的FFmpeg.exe放在你指定的目錄文件夾中,方便C#進(jìn)程調(diào)用。
ffmpeg.exe 安裝包: https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip(74MB)
C#進(jìn)程調(diào)用FFmpeg操作音視頻
namespace FFmpegAudioAndVideoMerge { ? ? class Program ? ? { ? ? ? ? static void Main(string[] args) ? ? ? ? { ? ? ? ? ? ? var physicalPath = "E:\\FFmpegAudioAndVideoMerge\\FFmpegAudioAndVideoMerge\\files\\"; ? ? ? ? ? ? //視頻合并 ? ? ? ? ? ? VideoCombine(physicalPath + "video1.mp4", physicalPath + "video2.mp4", physicalPath + "merageVideoyy.mp4"); ? ? ? ? ? ? //音頻合并 ? ? ? ? ? ? var audioMergeList = new List<string>(); ? ? ? ? ? ? audioMergeList.Add(physicalPath + "music1.mp3"); ? ? ? ? ? ? audioMergeList.Add(physicalPath + "music2.mp3"); ? ? ? ? ? ? audioMergeList.Add(physicalPath + "music3.mp3"); ? ? ? ? ? ? AudioMerge(physicalPath, audioMergeList); ? ? ? ? ? ? //音頻與視頻合并成視頻 ? ? ? ? ? ? AudioAndVideoMerge(physicalPath); ? ? ? ? } ? ? ? ? #region 視頻合并 ? ? ? ? /// <summary> ? ? ? ? /// 視頻合并 ? ? ? ? /// </summary> ? ? ? ? /// <param name="video1">合并視頻1</param> ? ? ? ? /// <param name="video2">合并視頻2</param> ? ? ? ? /// <param name="saveFilePath">保存文件名</param> ? ? ? ? /// <returns></returns> ? ? ? ? public static void VideoCombine(string video1, string video2, string saveFilePath) ? ? ? ? { ? ? ? ? ? ? string strTmp1 = video1 + ".ts"; ? ? ? ? ? ? string strTmp2 = video2 + ".ts"; ? ? ? ? ? ? string strCmd1 = " -i " + video1 + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + strTmp1 + " -y "; ? ? ? ? ? ? string strCmd2 = " -i " + video2 + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + strTmp2 + " -y "; ? ? ? ? ? ? string videoMerge = " -i \"concat:" + strTmp1 + "|" + ? ? ? ? ? ? ? ? strTmp2 + "\" -c copy -bsf:a aac_adtstoasc -movflags +faststart " + saveFilePath + " -y "; ? ? ? ? ? ? //1、轉(zhuǎn)換文件類型,由于不是所有類型的視頻文件都支持直接合并,需要先轉(zhuǎn)換格式 ? ? ? ? ? ? CommandManager(strCmd1); ? ? ? ? ? ? CommandManager(strCmd2); ? ? ? ? ? ? //2、視頻合并 ? ? ? ? ? ? CommandManager(videoMerge); ? ? ? ? } ? ? ? ? #endregion ? ? ? ? #region 音頻合并 ? ? ? ? /// <summary> ? ? ? ? /// 音頻合并 ? ? ? ? /// </summary> ? ? ? ? public static void AudioMerge(string physicalPath, List<string> mergeFile) ? ? ? ? { ? ? ? ? ? ? //將多個音頻混合成一個音頻文件輸出 http://www.ffmpeg.org/ffmpeg-all.html#amix ? ? ? ? ? ? //ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT ? ? ? ? ? ? //合并兩個音頻 ? ? ? ? ? ? //ffmpeg -i input1.mp3 -i input2.mp3 -filter_complex amerge -ac 2 - c:a libmp3lame -q:a 4 output.mp3 ? ? ? ? ? ? //獲取視頻中的音頻 ? ? ? ? ? ? //ffmpeg -i input.mp4 -vn -y -acodec copy output.m4a ? ? ? ? ? ? //去掉視頻中的音頻 ? ? ? ? ? ? //ffmpeg -i input.mp4 -an output.mp4 ? ? ? ? ? ? // https://www.cnblogs.com/simadi/p/10649345.html ? ? ? ? ? ? // ffmpeg -i "concat:123.mp3|124.mp3" -acodec copy output.mp3 ? ? ? ? ? ? // 解釋:-i代表輸入?yún)?shù) ? ? ? ? ? ? // contact: 123.mp3 | 124.mp3代表著需要連接到一起的音頻文件 -acodec copy output.mp3 重新編碼并復(fù)制到新文件中 ? ? ? ? ? ? string mergeCommandStr = $"-i \"concat:{string.Join("|", mergeFile.ToArray())}\" -acodec copy {physicalPath}AudioMerge.mp3 ?-y"; ? ? ? ? ? ? CommandManager(mergeCommandStr); ? ? ? ? } ? ? ? ? #endregion ? ? ? ? #region 音頻與視頻合并成視頻 ? ? ? ? /// <summary> ? ? ? ? /// 音頻與視頻合并成視頻 ? ? ? ? /// </summary> ? ? ? ? /// <param name="physicalPath">物理路徑</param> ? ? ? ? public static void AudioAndVideoMerge(string physicalPath) ? ? ? ? { ? ? ? ? ? ? //1、視頻文件中沒有音頻。 ? ? ? ? ? ? //ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4 ? ? ? ? ? ? //string mergeCommandStr = $"-i {physicalPath}video2.mp4 -i {physicalPath}music1.mp3 -c:v copy -c:a aac -strict experimental {physicalPath}output.mp4 ?-y"; ? ? ? ? ? ? //video.mp4,audio.wav分別是要合并的視頻和音頻,output.mp4是合并后輸出的音視頻文件。 ? ? ? ? ? ? //2、下面的命令是用audio音頻替換video中的音頻 ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a: 0 output.mp4 ? ? ? ? ? ? string mergeCommandStr = $"-i {physicalPath}video3.mp4 -i {physicalPath}AudioMerge.mp3 -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 {physicalPath}AudioAndVideoMerge.mp4 ?-y"; ? ? ? ? ? ? //3、c++音頻視頻合并(視頻文件中沒有音頻的情況下) ? ? ? ? ? ? //"ffmpeg -i /tmp/mergeMp3/392118469203595327/392118469203595327.aac ?-i /tmp/mergeMp3/392118469203595327/bg.mp4 -c copy -bsf:a aac_adtstoasc /tmp/mergeMp3/392118469203595327/392118469203595327.mp4 -y" ? ? ? ? ? ? //string mergeCommandStr3 = $"-i {physicalPath}video5.mp4 ?-i {physicalPath}AudioMerge.mp3 -c copy -bsf:a aac_adtstoasc {physicalPath}AudioAndVideoMerge1.mp4 -y"; ? ? ? ? ? ? CommandManager(mergeCommandStr); ? ? ? ? } ? ? ? ? #endregion ? ? ? ? /// <summary> ? ? ? ? /// 執(zhí)行 ? ? ? ? /// C# Process進(jìn)程調(diào)用 https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.process?view=net-5.0 ? ? ? ? /// </summary> ? ? ? ? /// <param name="commandStr">執(zhí)行命令</param> ? ? ? ? public static void CommandManager(string commandStr) ? ? ? ? { ? ? ? ? ? ? try ? ? ? ? ? ? { ? ? ? ? ? ? ? ? using (Process process = new Process()) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? process.StartInfo.FileName = "D:\\FFmpeg\\bin\\ffmpeg.exe";//要執(zhí)行的程序名稱(屬性,獲取或設(shè)置要啟動的應(yīng)用程序或文檔。FileName 屬性不需要表示可執(zhí)行文件。 它可以是其擴展名已經(jīng)與系統(tǒng)上安裝的應(yīng)用程序關(guān)聯(lián)的任何文件類型。) ? ? ? ? ? ? ? ? ? ? process.StartInfo.Arguments = " " + commandStr;//啟動該進(jìn)程時傳遞的命令行參數(shù) ? ? ? ? ? ? ? ? ? ? process.StartInfo.UseShellExecute = false; ? ? ? ? ? ? ? ? ? ? process.StartInfo.RedirectStandardInput = false;//可能接受來自調(diào)用程序的輸入信息 ? ? ? ? ? ? ? ? ? ? ? process.StartInfo.RedirectStandardOutput = false;//由調(diào)用程序獲取輸出信息 ?? ? ? ? ? ? ? ? ? ? ? process.StartInfo.RedirectStandardError = false;//重定向標(biāo)準(zhǔn)錯誤輸出 ? ? ? ? ? ? ? ? ? ? process.StartInfo.CreateNoWindow = false;//不顯示程序窗口 ? ? ? ? ? ? ? ? ? ? process.Start();//啟動程序 ? ? ? ? ? ? ? ? ? ? process.WaitForExit();//等待程序執(zhí)行完退出進(jìn)程(避免進(jìn)程占用文件或者是合成文件還未生成)* ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? catch (Exception e) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? Console.WriteLine(e.Message); ? ? ? ? ? ? } ? ? ? ? } ? ?? } }
到此這篇關(guān)于C#調(diào)用FFmpeg操作音視頻的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)C# FFmpeg音視頻內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#對接阿里云IOT平臺進(jìn)行設(shè)備開發(fā)
這篇文章介紹了C#對接阿里云IOT平臺進(jìn)行設(shè)備開發(fā),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01支持windows與linux的php計劃任務(wù)的實現(xiàn)方法
這篇文章主要介紹了支持windows與linux的php計劃任務(wù)的實現(xiàn)方法,較為詳細(xì)的講述了php計劃任務(wù)中涉及到的php程序?qū)崿F(xiàn)方法、Windows計劃任務(wù)實現(xiàn)方法等,需要的朋友可以參考下2014-11-11C#程序最小化到托盤圖標(biāo)操作步驟與實現(xiàn)代碼
設(shè)置窗體屬性showinTask=false;加notifyicon控件notifyIcon1,為控件notifyIcon1的屬性Icon添加一個icon圖標(biāo);添加窗體最小化事件(首先需要添加事件引用)接下來介紹實現(xiàn)代碼,感興趣的朋友可以研究下2012-12-12BarCode條形碼基于C# GDI+ 的實現(xiàn)方法詳解
本篇文章介紹了,BarCode條形碼基于C# GDI+ 的實現(xiàn)方法詳解。需要的朋友參考下2013-05-05