细说使用AForge.Video.FFMPEG的几个坑

小柊 发表于 2016年09月15日 19时09分18秒

一直觉得.net在多媒体处理方面渣得不行。最近需要做一个摄像头的程序,为了方便,用了AForge这个开源项目。AForge项目中有AForge.Video和AForge.Video. DirectShow这两个子项目,可以方便的调用摄像头。但是这两个项目最终只能取得视频帧,并不能保存为视频文件。经高人指点,AForge还有一个子项目AForge.Video.FFMPEG,它可以将图片压制成Avi视频格式。不过这个AForge.Video.FFMPEG在实际使用的时候会遇到不少坑,下面我将我在这次使用中遇到的坑分享给大家。

 

第一坑:引用

你要用AForge.Video.FFMPEG,当然第一步是引用啦。但这个AForge.Video.FFMPEG并不能像AForge其他项目一样可以用Visual Studio自带的NuGet去获得,你会发现NuGet上根本找不到这个项目。

 

找不到么,那我就去官网找好了,咱们可以去AForge项目官网下载AForge项目的源码和已编译文件。不过这里有俩问题:

  1. AForge项目官网打开速度非常非常非常慢,你可以点链接打开官网,然后打开游戏玩一会儿。(这里我就给各位放个AForge下载页直链:http://www.aforgenet.com/framework/downloads.html
  2. AForge项目的源码和生成文件最终都是放在GoogleCode上的,国内你懂得。不过这边我们就可以用的小花招就是用迅雷之类的下载器下载,他们的离线下载是可以翻墙的。

 

我是选择了“Download Full ZIP Archive”,右键选择“复制链接地址”,然后放进迅雷下载。

 

下载下来之后是一个压缩包,AForge.Video.FFMPEG.dll就放在压缩包的Release文件夹中。

 

第二坑:调用

刚刚我们从官网下载下来了AForge.Video.FFMPEG.dll,接下来调用就好了对吧。

然而并不是,你只是一脚踏进了一个深坑罢了,为什么说是深坑呢?因为这个dll调用非常非常的恶心。

我们来看一下有多恶心,首先我们假设我们已经在项目中已经添加了AForge、AForge.Video和AForge.Video.FFMPEG这三个类库。

然后修改Main函数:

 

按F5调试,瞬间爆炸:

 

发生这个问题的原因比较简单,因为这个AForge.Video.FFMPEG使用VC++写的,编译的时候已经被编译成本地代码,而我们现在C#一般目标平台都是“Any CPU”,所以会发生这个问题。

解决方案就是不再选择使用“Any CPU”作为目标平台,改成“x86”或者“x64”。因为x86可以跑在x64上,而x64不能在x86上跑,所以我选择了x86。

点击Visual Studio上方的配置管理器中“AnyCPU”旁的下按钮,在下拉菜单里选择“配置管理器”。

 

在新打开的“配置管理器”窗口里,单击“活动解决方案平台(P):”下的下来菜单,选择“<新建...>”(如果已经有x86平台,则直接选择即可)。

 

在新窗口里“键入或选择新平台(p):”下的组合框里选择“x86”,单击确定,然后关闭配置管理器。

 

现在再按F5启动调试,再一次瞬间爆炸【冷漠脸】。

 

怎么说呢,起码出错提示换了对吧【冷漠脸】。

 

那么这次又是出什么问题了呢。

咱们现在用的是AForge.Video.FFMPEG对吧。我们都知道FFMPEG是一个著名的开源多媒体处理项目对吧,这个AForge.Video.FFMPEG其实是在内部调用FFMPEG来工作的。所以这个FileNotFoundException其实是AForge.Video.FFMPEG找不到FFMPEG的文件所以抛出来的。AForge.Video.FFMPEG依赖的FFMPEG组件其实已经放在了刚刚下载下来的压缩包的\Externals\ffmpeg\bin目录下:

 

我们把这个8个文件复制到程序目录下,注意我们刚刚改过目标平台了,现在程序编译输出的目录已经是\bin\x86\Debug,不要复制错了。

 

复制好之后我们继续按F5调试程序。

嗯,爆炸了,我已经习惯了【冷漠脸】。

 

这次问题的原因是什么呢……

其实是因为我的项目目标框架是.net Framework 4.0,而AForge官方在编译AForge.Video.FFMPEG.dll的时候,目标框架选的是.net Framework 2.0……

在.net Framework 4.0以前,由于程序运行环境本质还是.net Framework 2.0,并且.net Framework 2.0兼容.net Framework 1.0和1.1,但在升级到.net Framework 4.0时,.NET的内核作了重大调整,以前在.net Framework 2.0或.net3.5中生成的程序集,如果要在.net Framework 4.0下运行,需要在配置文件中指定此应用程序支持的公共语言运行时版本和启用.net Framework 2.0运行时激活策略。

 

解决方案有三种:

  1. 降低自己项目的目标.net Framework版本;
  2. 修改Config文件;
  3. 重新编译Video.FFMPEG。

 

这里我就讲一下方法二,方法三放到下一章。

在Visual Studio中按Ctrl+Shift+A,打开“添加新项”窗口,选择“应用程序配置文件”,再点击“添加”。

 

打开新建的App.Config文件,在<configuration>和</configuration>标签中加入以下内容:

 

即:

 

添加完成后,按F5启动调试。

 

终于一切正常。

 

第三坑:编译

刚刚在上面说了介绍了一种通过修改App.Config文件来启用传统 .net Framework 2.0 运行时策略的方法来解决最后一个异常。不过这种方法并不推荐,因为它只是让.net Framework不使用4.0的策略,其问题本质还是没有解决,如果后期丢失了这个App.Config文件,程序在运行时依旧会抛出异常。所以我个人还是推荐自己重新编译一次AForge.Video.FFMPEG这个托管库的。

AForge.Video.FFMPEG也是一个开源的项目,不过这个项目不像AForge放在GoogleCode上,而是放在微软自家的CodePlex上。

AForge.Video.FFMPEG项目主页地址:http://aforgeffmpeg.codeplex.com/

我们可以在这里下载到AForge.Video.FFMPEG的源码。

 

下载下来之后是一个压缩包,进入压缩包的\Sources\Video.FFMPEG目录,用Visual Studio打开文件夹里的“Video.FFMPEG.sln”文件。

 

打开之后Visual Studio可能会提示升级VC++编译器和库,点击确定升级就是。

 

首先我们在解决方案资源管理器里对着Video.FFMPEG这个项目右键点击属性,进入通用属性页,会发现有个带红色感叹号的AForge.Video项(如果你这里没有,可以直接跳过这步),选中后点击下方“移除引用”移除掉,以免之后生成的时候产生警告。

 

之后检查一下通用属性页上方的目标框架是否与你的项目目标框架版本一致,我这里上面显示的目标框架版本是.net Framework 4.5,和我的项目不符(我的项目是.net Framework 4.0),需要进行修改。

VC++修改目标框架的方法比较奇怪,需要关掉Visual Studio之后用记事本打开“Video.FFMPEG.vcxproj”文件(注意是vcxproj文件,不是别的),然后修改<TargetFrameworkVersion>标签内的值(我这里是要改成v4.0)。

 

修改后保存文件,然后重新用Visual Studio打开“Video.FFMPEG.sln”文件。打开之后就可以直接按F6生成项目了。生成结束之后去项目文件的..\..\Release\文件夹下找编译出的AForge.Video.FFMPEG.dll文件。

 

将这个dll复制进你的项目文件里并引用即可。

 

按F5启动调试,一切正常。

 

第四坑:部署

最后一个坑其实是真正最坑的地方。我在项目结束之后部署到了我的WIndows Server服务器上,结果一运行就爆炸。

 

因为抛出来的异常是FileNotFoundException,所以以为是丢文件了,重新打包部署,发现没有文件丢失。怀疑是Windows Server没有Windows Desktop版的什么文件,Dump进程内存看dmp文件,前前后后折腾了两小时无果。

 

最后的最后突然想起一件事情:

我们不是用VisualC++编译过AForge.Video.FFMPEG过么?

VisualC++是要单独安装运行时的!

 

我是单独用Visual Studio 2013编译过,所以需要下载并安装Visual C++ 2013 Redistributable环境。官方编译是用Visual Studio 2010,安装Visual C++ 2010 Redistributable就够了。x86和x64两个版本选择根据自身需要安装。如果你编译的是x86版,就算系统是x64的还是需要安装x86版Visual C++ Redistributable。

 

安装完成后,再次启动程序,一切正常。

 

后记:

在我这篇博客写了一半的时候,我才发现其实AForge还有一个子项目:AForge.Video.VFW也是可以将图片转换为Avi视频的,而且这个项目是用Visual C#写的,调用起来应该会比AForge.Video.FFMPEG方便。

不过这也是后话了,希望有兴趣的看官去尝试看看,告诉我这个项目坑不坑。

 

 

 

小柊

2016年9月15日 18:56:39

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注