C#中使用ffmpeg的心得

        前段时间由于项目需求,要对即时视频通话进行本地录制,而且要求将对方视频及双方音频合并成所需视频,并生成mp4格式。视频通话是WebRTC技术,录下的视频格式是webm,一个远端,一个近端,由于需求比较奇怪,简单的视频合成难以完成任务,这就需要使用ffmpeg这款强大的工具来实现了。
ffmpeg详细功能可通过:https://ffmpeg.zeranoe.com/forum/ 来学习。我这只说遇到的一些问题。

先看需求,要求将远端的音视频及近端的音频合成一个mp4格式的视频,目前只保存了一个远端一个近端两个视频。

所以需要先将远端音频分离出来,

string cmd = string.Format("-y -i {0} -f mp3 -vn {1}", inAudio, outFileName);
       ExcuteCMD(cmd);

得到remote.mp3,再将近端音频分离出来,得到local.mp3,

再将远端视频分离出来,

string cmd = string.Format("-y -threads 2 -i {0} -c:v libx264 -strict -2 {1}", inVideo, outFileName);
       ExcuteCMD(cmd);

得到remote.mp4,此时将远端音频与近端音频合并成一个音频,

string cmd = string.Format("-y -i {0} -i {1} -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f mp3 {2}", inAudio1, inAudio2, outFileName);
        ExcuteCMD(cmd);

得到mix.mp3,最后将remote.mp4与mix.mp3,合成新的视频

string cmd = string.Format("-y -threads 2 -i {0} -i {1} -vcodec copy -acodec copy {2}", inVideo, inAudio, outFileName);
        ExcuteCMD(cmd);

经过这些步骤得到的就是需要的视频了。

虽然代码很简单,但在这过程中遇到不少坑。

第一个坑,ffmpeg要求指令中的路径不能有空格或者别的非法字符,否则会报

也很容易理解,就是ffmpeg找不到目录,经过一番查找,发现只需要将指令中的路径加上双引号即可,原来如此简单,比如上面的合成视频指令改成如下即可:

 string cmd = string.Format("-y -threads 2 -i \"{0}\" -i \"{1}\" -vcodec copy -acodec copy \"{2}\"", inVideo, inAudio, outFileName);

第二个坑,在c#中调用ffmpeg程序执行指令首先想到的是Process.Start() 这个功能,也很简单:

private static void ExcuteCMD(string cmd)
        {
            Process p = new Process();

            p.StartInfo.FileName = @"D:\Program Files (x86)\远程程控客户端\ffmpeg.exe";

            p.StartInfo.Arguments = cmd;   //执行参数

            p.StartInfo.UseShellExecute = false;  不使用系统外壳程序启动进程
            p.StartInfo.CreateNoWindow = true;  //不显示dos程序窗口

            p.StartInfo.RedirectStandardInput = true;

            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中

            p.Start();

            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            p.BeginErrorReadLine();//开始异步读取

            p.WaitForExit();//阻塞等待进程结束

            p.Close();//关闭进程

            p.Dispose();//释放资源
        }

p.WaitForExit();这个设置必不可少,因为转换的视频如果较大,这个指令执行的时间会比较长,所以需要等待进程结束才可进行下一步操作,否则会出错。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值