提供java+winwows下使用ffmpeg解决视频转换思路和代码
From Ffmpeg工程组
提供一个在java开发环境下使用ffmepg开发视频共享网站上传视频转换技术的思路
如果你想在java中使用的话,你必须先采用VC++等开发工具写一个COM或是OCX组件,通过这个组件调用ffmpeg提供的动态库, 这个组件是可以满足你的需求的,然后在java中你再把这个组件封装一下。
如果你想把ffmpeg.exe这个程序封装为一个DLL,或是COM的话,难度很大,特别是你现在对VC++不熟悉! 建议:你编写一个独立的转换系统,支持多线程、批处理……,可独立运行的,然后你的java程序通过一定的方式(如通过数 据库交换)向前面说的独立转换系统提交转换任务,转换系统接收到新的转换后,开始转换,同时写入转换进度到数据库中,这时 ,你的java程序也可以从数据库中获取实时的转换进度了,转换系统转换完成之后,把结果也写入数据库,这样,你的java程序 也就知道转换完成了。这样做的好处是,可以实现分布式处理、多服务器并行处理、系统的负载均衡处理等,优势还是很明显的。
可以很明确说,大型一点的视频网站,都不是用户上传一个文件就马上在WEB进程中转换的,而是有一套如我上面所说的转换 系统,而且转换不一定是在WEB发布的服务器上进行的,有专门的转换服务器。
基本思路如下:
看了admin说的...的确很对... 我现在做的那个项目就有你这样的问题...
我也是直接写了一个类...用asp.net调用外部程序(ffmpeg.exe),转换,然后获取返回的信息...来写到数据库... 而这个类是用一条新的进程来执行的...网站主线程不需要等待... 而且这个类还会自动扫描数据库...只要后用户上传后,调用了这个类...他就会扫描一遍数据库,发现没转换的,循环转换... 这样转换和网站就可以脱离开了...
而我也明白你的意思...你是想做成一个DLL或者COM...让网站主线程直接调用...把信息实时反馈给用户... 但这是不太可能的...因为网站不是本地程序...不可能跟外壳(网站就是指客户端页面,本地程序就是指窗体)实时交互...就算 用ajax也不行...因为后台处理有一个并发的问题... 我公司一台服务器,用最新架构的至强3.0CPU...也最多能并行运行10个左右的FFMPEG...超过了就会卡机... 所以WEB的后台转换必须是用队列来实现...一次转一个...这是最理想的...当然...这又要用到线程阻塞之类的东西...这就没 办法帮你了...呵呵...
代码详解:
我是用C#写的...代码有啊...这论坛就有... http://bbs.chinavideo.org/viewthread.php?tid=2326&extra=page%3D1
详细思路如下:
思路也不难...用户上传完毕...把上传后的文件名和路径等信息插到数据库...并标上未转换的标记(怎么实现见人见志)... 然后调用转换类(或者方法)...扫描数据库...做个SELECT就行了...得出数据集...
这要看你的思路了... 1.可以把全部未转换的select出来,然后用for(XXX)来循环这个数据集 2.用select top 1 加while来扫描...
第一种方法就安全一点,但在这个类(或者方法)执行(数据集取出来后)过程,再有用户上传,也不会被加入转换队列,需要等当前转 换队列完成后,再有用户上传,才会被加到转换队列...
第二种方法就比较危险一点,毕竟是用while,只要中间逻辑出现任何错误,就有可能出现死循环...但是用while和select top 1 的话,转换队列是非常灵活的...是取一条,转一个...也就是说,只要这个while没完成(就是说数据库中还有没被转换的,包括转换 开始后才增加的数据),他都会调出来加到队列转换...相对实时一点...
上面说的是数据库扫描的思路... 下面说说转换的安全性...
视频转换占用CPU严重人尽皆知,这个就没啥好说的...所以我推荐不并发...每次只转换1个视频...
那么你用开发语言(JAVA也好,C#也好)调用外部程序(ffmpeg.exe)的时候...记得...一定要等待进程结束...不然的话...等着 死机吧...我试过做一个while+select top1的转换队列系统...忘记了加上等待进程结束的语句...结果FFMPEG那个线程被运 行了上百条...但其实我数据库只有1条未转换记录...但是只要没转换完成,他就不会把数据库的记录改写(改成已转换),所以 WHILE不断的建立新线程来执行...
调用外部程序,系统会分配一条独立的线程序,这里只要加上等待线程结束的语句就好了... 另外,调用整个类(或者方法),也必须开一条单独的线程序,而且只能运行1个这样的线程序...
举个例...你的网站肯定不会只有1个别用户访问...那么的话...这个类(或者方法)有可能被调用多次...那么如果不限制执行这 个类(或者方法)的数量,那么就会产生多个类(或者方法)的镜像...同时执行...同时扫描数据库,同时开1条FFMPEG进程来转换同 1份文件...最后的结果也是消耗无谓的资源...导致服务器挂掉...这也很好的说明web站和本地程序开发的很大不同...一个并发 量问题...
所以呢...这整个类(或者方法)你也要做保护装置...你可以用1个全局变量来保存一个状态...例如这个全局变量为status...那 么每当这个类(或者方法)开始执行,就把status改成1...然后在这个类(或者方法)外部再加一个判断: if(status == 1) return; 这样就是一个简单的保护了...
复杂一点的方法呢...就是用一条线程来执行这个类(或者方法)...用阻塞来防止被多次运行这个类(或者方法)...至于实现的 办法...每种语言都不同...你自己找找方法吧...
这是我将要使用在我项目上的思路...呵呵... 最后,告诫一句...程序员...只有想不到,没有做不到...多多发散自己的思维...对你以后工作会有很大帮助...
有关该问题的讨论帖可参考ffmpeg工程组论坛中的相关讨论:
有关java+winwows下使用ffmpeg解决视频转换技术的讨论
