C#調(diào)用FFmpeg操作音視頻的實現(xiàn)示例
項目背景
因為公司需要對音視頻做一些操作,比如說對系統(tǒng)用戶的發(fā)音和背景視頻進行合成,以及對多個音視頻之間進行合成,還有就是在指定的源背景音頻中按照對應(yīng)的規(guī)則在視頻的多少秒鐘內(nèi)插入一段客戶發(fā)音等一些復(fù)雜的音視頻操作。本篇文章主要講解的是使用C#進程(Process)調(diào)用FFmpeg.exe進行視頻合并,音頻合并,音頻與視頻合并成視頻這幾個簡單的音視頻操作,還有些復(fù)雜的音視頻操作后續(xù)有時間慢慢補上。
FFmpeg介紹
FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計算機程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多code都是從頭開發(fā)的。
FFmpeg在Linux平臺下開發(fā),但它同樣也可以在其它操作系統(tǒng)環(huán)境中編譯運行,包括Windows、Mac等多平臺。這個項目最早由Fabrice Bellard發(fā)起,2004年至2015年間由Michael Niedermayer主要負責(zé)維護。許多FFmpeg的開發(fā)人員都來自MPlayer項目,而且當前FFmpeg也是放在MPlayer項目組的服務(wù)器上。項目的名稱來自MPEG視頻編碼標準,前面的"FF"代表"Fast Forward"。 FFmpeg編碼庫可以使用GPU加速。
FFmpeg相關(guān)教程
開始之初你首先要了解FFmpeg是什么,有哪些常用的命令和實用的功能。
博客示例源碼
https://github.com/YSGStudyHards/FFmpegAudioAndVideoMerge
下載FFmpeg.exe安裝包
首先把下載下來的FFmpeg.exe放在你指定的目錄文件夾中,方便C#進程調(diào)用。
ffmpeg.exe 安裝包: https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip(74MB)
C#進程調(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進程調(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;//啟動該進程時傳遞的命令行參數(shù)
? ? ? ? ? ? ? ? ? ? process.StartInfo.UseShellExecute = false;
? ? ? ? ? ? ? ? ? ? process.StartInfo.RedirectStandardInput = false;//可能接受來自調(diào)用程序的輸入信息 ?
? ? ? ? ? ? ? ? ? ? process.StartInfo.RedirectStandardOutput = false;//由調(diào)用程序獲取輸出信息 ??
? ? ? ? ? ? ? ? ? ? process.StartInfo.RedirectStandardError = false;//重定向標準錯誤輸出
? ? ? ? ? ? ? ? ? ? process.StartInfo.CreateNoWindow = false;//不顯示程序窗口
? ? ? ? ? ? ? ? ? ? process.Start();//啟動程序
? ? ? ? ? ? ? ? ? ? process.WaitForExit();//等待程序執(zhí)行完退出進程(避免進程占用文件或者是合成文件還未生成)*
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? 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)文章
支持windows與linux的php計劃任務(wù)的實現(xiàn)方法
這篇文章主要介紹了支持windows與linux的php計劃任務(wù)的實現(xiàn)方法,較為詳細的講述了php計劃任務(wù)中涉及到的php程序?qū)崿F(xiàn)方法、Windows計劃任務(wù)實現(xiàn)方法等,需要的朋友可以參考下2014-11-11
BarCode條形碼基于C# GDI+ 的實現(xiàn)方法詳解
本篇文章介紹了,BarCode條形碼基于C# GDI+ 的實現(xiàn)方法詳解。需要的朋友參考下2013-05-05

