项目背景

  因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中按照对应的规则在视频的多少秒钟内插入一段客户发音等一些复杂的音视频操作。本篇文章主要讲解的是使用C#进程(Process)调用FFmpeg.exe进行视频合并,音频合并,音频与视频合并成视频这几个简单的音视频操作,还有些复杂的音视频操作后续有时间慢慢补上。

FFmpeg介绍

来源百度百科

  FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

  FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac等多平台。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。 FFmpeg编码库可以使用GPU加速。

FFmpeg相关教程

开始之初你首先要了解FFmpeg是什么,有哪些常用的命令和实用的功能。

博客示例源码

https://github.com/YSGStudyHards/FFmpegAudioAndVideoMerge

下载FFmpeg.exe安装包

首先把下载下来的FFmpeg.exe放在你指定的目录文件夹中,方便C#进程调用。

ffmpeg.exe 安装包: https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip (74MB)

C#进程调用FFmpeg操作音视频

  1. namespace FFmpegAudioAndVideoMerge
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. var physicalPath = "E:\\FFmpegAudioAndVideoMerge\\FFmpegAudioAndVideoMerge\\files\\";
  8.  
  9. //视频合并
  10. VideoCombine(physicalPath + "video1.mp4", physicalPath + "video2.mp4", physicalPath + "merageVideoyy.mp4");
  11.  
  12. //音频合并
  13. var audioMergeList = new List<string>();
  14. audioMergeList.Add(physicalPath + "music1.mp3");
  15. audioMergeList.Add(physicalPath + "music2.mp3");
  16. audioMergeList.Add(physicalPath + "music3.mp3");
  17. AudioMerge(physicalPath, audioMergeList);
  18.  
  19. //音频与视频合并成视频
  20. AudioAndVideoMerge(physicalPath);
  21. }
  22.  
  23. #region 视频合并
  24. /// <summary>
  25. /// 视频合并
  26. /// </summary>
  27. /// <param name="video1">合并视频1</param>
  28. /// <param name="video2">合并视频2</param>
  29. /// <param name="saveFilePath">保存文件名</param>
  30. /// <returns></returns>
  31. public static void VideoCombine(string video1, string video2, string saveFilePath)
  32. {
  33. string strTmp1 = video1 + ".ts";
  34. string strTmp2 = video2 + ".ts";
  35. string strCmd1 = " -i " + video1 + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + strTmp1 + " -y ";
  36. string strCmd2 = " -i " + video2 + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + strTmp2 + " -y ";
  37.  
  38. string videoMerge = " -i \"concat:" + strTmp1 + "|" +
  39. strTmp2 + "\" -c copy -bsf:a aac_adtstoasc -movflags +faststart " + saveFilePath + " -y ";
  40.  
  41. //1、转换文件类型,由于不是所有类型的视频文件都支持直接合并,需要先转换格式
  42. CommandManager(strCmd1);
  43. CommandManager(strCmd2);
  44.  
  45. //2、视频合并
  46. CommandManager(videoMerge);
  47. }
  48. #endregion
  49.  
  50. #region 音频合并
  51. /// <summary>
  52. /// 音频合并
  53. /// </summary>
  54. public static void AudioMerge(string physicalPath, List<string> mergeFile)
  55. {
  56. //将多个音频混合成一个音频文件输出 http://www.ffmpeg.org/ffmpeg-all.html#amix
  57.  
  58. //ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
  59.  
  60. //合并两个音频
  61. //ffmpeg -i input1.mp3 -i input2.mp3 -filter_complex amerge -ac 2 - c:a libmp3lame -q:a 4 output.mp3
  62.  
  63. //获取视频中的音频
  64. //ffmpeg -i input.mp4 -vn -y -acodec copy output.m4a
  65.  
  66. //去掉视频中的音频
  67. //ffmpeg -i input.mp4 -an output.mp4
  68.  
  69. // https://www.cnblogs.com/simadi/p/10649345.html
  70. // ffmpeg -i "concat:123.mp3|124.mp3" -acodec copy output.mp3
  71. // 解释:-i代表输入参数
  72. // contact: 123.mp3 | 124.mp3代表着需要连接到一起的音频文件 -acodec copy output.mp3 重新编码并复制到新文件中
  73.  
  74. string mergeCommandStr = $"-i \"concat:{string.Join("|", mergeFile.ToArray())}\" -acodec copy {physicalPath}AudioMerge.mp3 -y";
  75. CommandManager(mergeCommandStr);
  76. }
  77. #endregion
  78.  
  79. #region 音频与视频合并成视频
  80. /// <summary>
  81. /// 音频与视频合并成视频
  82. /// </summary>
  83. /// <param name="physicalPath">物理路径</param>
  84. public static void AudioAndVideoMerge(string physicalPath)
  85. {
  86. //1、视频文件中没有音频。
  87. //ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4
  88. //string mergeCommandStr = $"-i {physicalPath}video2.mp4 -i {physicalPath}music1.mp3 -c:v copy -c:a aac -strict experimental {physicalPath}output.mp4 -y";
  89.  
  90. //video.mp4,audio.wav分别是要合并的视频和音频,output.mp4是合并后输出的音视频文件。
  91. //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
  92. 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";
  93.  
  94. //3、c++音频视频合并(视频文件中没有音频的情况下)
  95. //"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"
  96. //string mergeCommandStr3 = $"-i {physicalPath}video5.mp4 -i {physicalPath}AudioMerge.mp3 -c copy -bsf:a aac_adtstoasc {physicalPath}AudioAndVideoMerge1.mp4 -y";
  97.  
  98. CommandManager(mergeCommandStr);
  99. }
  100. #endregion
  101.  
  102. /// <summary>
  103. /// 执行
  104. /// C# Process进程调用 https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.process?view=net-5.0
  105. /// </summary>
  106. /// <param name="commandStr">执行命令</param>
  107. public static void CommandManager(string commandStr)
  108. {
  109. try
  110. {
  111. using (Process process = new Process())
  112. {
  113. process.StartInfo.FileName = "D:\\FFmpeg\\bin\\ffmpeg.exe";//要执行的程序名称(属性,获取或设置要启动的应用程序或文档。FileName 属性不需要表示可执行文件。 它可以是其扩展名已经与系统上安装的应用程序关联的任何文件类型。)
  114. process.StartInfo.Arguments = " " + commandStr;//启动该进程时传递的命令行参数
  115. process.StartInfo.UseShellExecute = false;
  116. process.StartInfo.RedirectStandardInput = false;//可能接受来自调用程序的输入信息
  117. process.StartInfo.RedirectStandardOutput = false;//由调用程序获取输出信息
  118. process.StartInfo.RedirectStandardError = false;//重定向标准错误输出
  119. process.StartInfo.CreateNoWindow = false;//不显示程序窗口
  120. process.Start();//启动程序
  121. process.WaitForExit();//等待程序执行完退出进程(避免进程占用文件或者是合成文件还未生成)*
  122. }
  123. }
  124. catch (Exception e)
  125. {
  126. Console.WriteLine(e.Message);
  127. }
  128. }
  129.  
  130. }
  131. }

C#进程调用FFmpeg操作音视频的更多相关文章

  1. FFmpeg Android 学习(一):Android 如何调用 FFMPEG 编辑音视频

    一.概述 在Android开发中,我们对一些音视频的处理比较无力,特别是编辑音视频这部分.而且在Android上对视频编辑方面,几乎没有任何API做支持,MediaCodec(硬编码)也没有做支持.那 ...

  2. javaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操作?

    通过"javaCV入门指南:序章 "大家知道了处理音视频流媒体的前置基本知识,基本知识包含了像素格式.编解码格式.封装格式.网络协议以及一些音视频专业名词,专业名词不会赘述,自行搜 ...

  3. FFmpeg处理音视频流程学习笔记

    原文作者:一叶知秋0830 链接:https://www.jianshu.com/p/1b715966af50 FFmpeg处理音视频完整流程包括5个阶段(输入文件—>编码数据包—>解码后 ...

  4. FFmpeg开发实战(五):FFmpeg 抽取音视频的视频数据

    如何使用FFmpeg抽取音视频的视频数据,代码如下: // FFmpegTest.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include ...

  5. FFmpeg开发实战(四):FFmpeg 抽取音视频的音频数据

    如何使用FFmpeg抽取音视频的音频数据,代码如下: void adts_header(char *szAdtsHeader, int dataLen); // 使用FFmpeg从视频中抽取音频 vo ...

  6. C++调用ffmpeg.exe提取视频帧

    有时候,我们获得一段视频,需要将其中的每一帧都提取出来,来进行一些相关的处理,这时候我们就可以需要用到ffmpeg.exe来进行视频帧的提取. ffmpeg简介:FFmpeg是一套可以用来记录.转换数 ...

  7. ffmpeg解码音视频过程(附代码)

    0. 引言 最近一直在使用和学习ffmpeg. 工作中需要拉流解码, 获取音频和视频数据. 这些都是使用ffmpeg处理. 因为对ffmpeg接触不多, 用的不深, 在使用的过程中经常遇到不太懂的地方 ...

  8. 如何使用ffmpeg进行音视频裁剪命令和音视频合成命令

    音视频剪裁命令 ffmpeg -i input.mp4 -ss 00:00:00 -t 10 out.ts -i : 指定视频 -ss : 开始时间 -t : 指定裁剪的秒数 音视频合并的命令 ffm ...

  9. ffmpeg实战-音视频基础概念

    转发自白狼栈:查看原文 关于音视频,相信大家都看过电影(视频),听过音乐(音频),至少应该都知道mp4是视频文件,mp3是音频文件. 对于一个音视频文件,都有哪些属性呢?以视频为例,我们可以通过 ff ...

随机推荐

  1. Vlookup大叔早已油腻(Excel函数集团)

    1.Vlookup基础用法:https://mp.weixin.qq.com/s/0JRytWlBD-KYM2jkecG2rA 2.合并字符串:https://mp.weixin.qq.com/s/9 ...

  2. OpenWrt之关闭IPv6

    目录 OpenWrt之关闭IPv6 1.前言 2.WAN口设置 3.LAN口设置 4.保存并应用 5.防火墙设置 6.DHCP/DNS设置 1)SSH连接路由器 2)输入第一条命令,按回车执行 3)输 ...

  3. js实现数组扁平化

    数组扁平化的方式 什么是数组扁平化? 数组扁平化:指将一个多维数组转化为一个一维数组. 例:将下面数组扁平化处理. const arr = [1, [2, 3, [4, 5]]] // ---> ...

  4. CF919B Perfect Number 题解

    Content 给定一个数字 \(k\),求出第 \(k\) 小的各数位和为 \(10\) 的数. 数据范围:\(1\leqslant k\leqslant 10000\). Solution 这题为 ...

  5. WebApi的前端调用

    WebApi前端调用 HTML代码: <!DOCTYPE html><html> <head> <meta charset="utf-8" ...

  6. urllib结合 concurrent.futures 多线程下载文件。

    示例: #!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Time: 2020/12/16 10:42 # @Author:zhangmingda # ...

  7. 基于nginx的rtmp直播服务器(nginx-rtmp-module实现)

    首先,在搭建服务之前先了解下目前主流的几个直播协议: 1.RTMP: 实时消息传输协议,Real Time Messaging Protocol,是 Adobe Systems 公司为 Flash 播 ...

  8. Vim使用简介

    Vim操作 Vim真的很酷:D 编辑模式 正常模式:在文件中四处移动光标进行修改 插入模式:插入文本 替换模式:替换文本 可视化(一般,行,块)模式:选中文本块 命令模式:用于执行命令 在不同的操作模 ...

  9. Mybatis-Plus中使用max、sum聚合函数、只查询指定字段、查询语句多个OR处理

    聚合函数查询 可以使用以下方法 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select(" I ...

  10. JAVA接收postman的中raw的参数

    /** * java获取raw */ public static String readRaw(InputStream inputStream) { String result = "&qu ...