一個很全面的forum
http://bbs.chinavideo.org/forumdisplay.php?fid=10
中文網站
http://www.ffmpeg.com.cn/index.php/%E9%A6%96%E9%A1%B5
前一段时间做视频转换,在做的过程中我遇到了很多问题,把自己的经验写一下,共大家参考:
用户上传的视频我主要爱
格式:
ffmpeg [[输入文件选项]- i 输入文件名] {[输入文件选项] 输出文件名}
主要选项:
-L 显示ffmpeg的版权说明
-h 显示帮助
-version 显示版本
-formats 显示支持的文件格式,编码和协议
-f 格式名 强制使用格式
-img 文件格式名 强制使用片格式
-i 文件名 待转换文件名字
-y 覆盖同名输出文件
-t 时间 设置影片时间长度
-fs 最大尺寸 设置文件的最大尺寸
-ss 时间点 设置开始转换的时间点
-title 文字 设置标题
-author 文字 设置作者
-copyright 文字 设置版权声明
-comment 文字 设置备注
视频选项:
-b 比特率 设置文件比特率 (单位是kbit/s)
-r 速度 桢速度 (Hz value)
-s 大小 设置大小,宽乘高
-newvideo 在现在的视频流后面加入信的视频流
音频选项:
-aframes 数字 设置转换多少桢(frame)的音频
-ab bitrate 设置音乐的比特率(单位:kbit/s)
-aq 质量 这只音频质量 (指定编码)
-ar 采样率 设置音频采样率 (单位:Hz)
-ac 声道数字 设置声道数
-an 取消音频
-acodec 编码 强制音频 编码 ('copy' to copy stream)
-vol volume 改变音量 (256为普通)
-newaudio 追加音乐
是这样的,现在得接到任务得进行一个视频共享网站的视频上传转换技术,我在google里面一下就找了ffmpeg,经过一天的研究终于用java+ffmpeg代码写了个小小的转换程序,但是现在有了点变动要求我利用ffmpeg的源代码进行编译,也就说要使用动态连接库了,可以前从来没接触过,我一直做的是java的啊,对VC和C#什么的一点都不了解,所以请给位高手,大侠们提供一个在java开发环境下使用ffmepg开发视频共享网站上传视频转换技术的思路啊,我的开发环境下是widowsxp的啊。谢谢啊,现在真的是救命啊!:'(
转换的话...JAVA一样可以调用FFMPEG的EXE程序吧...
恩,前天刚用java做过了一个小程序用的就是ffmpeg.exe文件的,转换的几种文件都成功了,现在的关键是在VC下对COM的开发了,用JAVA能开发吗?因为我想网站的流量可能会很大所以用exe文件应该不怎么行的,只有封装了dll文件才会更好的支持,还有想请教下,想对ffmpeg的源代码和思想进行下研究,你能提供的方法吗?我看过贴子您也做过视频网站开发的能提供点经验吗?谢谢
为什么这么说呢?
不瞒大家啊,这是我毕业的第一份工作,我想做好啊,并切会努力的学习的,希望大家多多的帮助啊。谢谢啦。:)
问下admin啊,编写的com是不是要编写实现视频转换功能的代码啊?能不能给点代码参考下啊?
我不知道我这样想的对不对,但我还是说下哈,在第一个ConvertVideo.java的时候,ffmpeg.exe文件只有放在ConvertVideo.java相同的目录下才能成功的,我不知道这是什么原因,但是我觉得在一个项目中不能每次都要去用 ... [/quote]
其实把FFMPEG封装成COM调用...跟直接调用FFMPEG.EXE一样...
我不知道JAVA能不能调用绝对路径的外部程序,但觉得应该可以...不需要一定放在跟JAVA文件同目录下...
封装成COM组件来用,也得建立一条独立线程来执行...不可能阻塞主线程的...而且也不可能把信息实时反馈给用户...因为你做的是网站...不是本地程序...
我用C#也是一样的用FFMPEG.EXE...感觉跟用COM没多大分别...
问下admin啊,编写的com是不是要编写实现视频转换功能的代码啊?能不能给点代码参考下啊? [/quote]
代码是没有的...当初我也碰到过同样的问题...不过原因跟你有点不一样而已...
你可以直接用JAVA调用DLL(可以的话),这样做就要把处理逻辑用JAVA来写...
你也可以把整个FFMPEG封装成一个COM...这个COM提供2个接口...1个输入,1个输出...然后JAVA调用...
建议:你编写一个独立的转换系统,支持多线程、批处理……,可独立运行的,然后你的java程序通过一定的方式(如通过数据库交换)向前面说的独立转换系统提交转换任务,转换系统接收到新的转换后,开始转换,同时写入转换进度到数据库中,这时,你的java程序也可以从数据库中获取实时的转换进度了,转换系统转换完成之后,把结果也写入数据库,这样,你的java程序也就知道转换完成了。这样做的好处是,可以实现分布式处理、多服务器并行处理、系统的负载均衡处理等,优势还是很明显的。
可以很明确说,大型一点的视频网站,都不是用户上传一个文件就马上在WEB进程中转换的,而是有一套如我上面所说的转换系统,而且转换不一定是在WEB发布的服务器上进行的,有专门的转换服务器,:)
admin 大侠啊,你给我思路我基本是懂了,可似乎更难了啊?!:( ~~
所以我现在想不这样考虑了,我想再写一个dll文件,直接加载ffmpeg中的main方法,去执行我的需求,你看怎么样啊?还有我想读下代码该怎么去理解啊?你有相关的看代码的帮助文档吗?我现在会很努力的去学习C了了,给点资料哈,再次表示谢谢啦~~~~~~~~~好人啦~~~~~~`:) :victory:
我现在做的那个项目就有你这样的问题...
我也是直接写了一个类...用asp.net调用外部程序(ffmpeg.exe),转换,然后获取返回的信息...来写到数据库...
而这个类是用一条新的进程来执行的...网站主线程不需要等待...
而且这个类还会自动扫描数据库...只要后用户上传后,调用了这个类...他就会扫描一遍数据库,发现没转换的,循环转换...
这样转换和网站就可以脱离开了...
而我也明白你的意思...你是想做成一个DLL或者COM...让网站主线程直接调用...把信息实时反馈给用户...
但这是不太可能的...因为网站不是本地程序...不可能跟外壳(网站就是指客户端页面,本地程序就是指窗体)实时交互...就算用ajax也不行...因为后台处理有一个并发的问题...
我公司一台服务器,用最新架构的至强3.0CPU...也最多能并行运行10个左右的FFMPEG...超过了就会卡机...
所以WEB的后台转换必须是用队列来实现...一次转一个...这是最理想的...当然...这又要用到线程阻塞之类的东西...这就没办法帮你了...呵呵...
“我也是直接写了一个类...用asp.net调用外部程序(ffmpeg.exe),转换,然后获取返回的信息...来写到数据库...
而这个类是用一条新的进程来执行的...网站主线程不需要等待...
而且这个类还会自动扫描数据库...只要后用户上传后,调用了这个类...他就会扫描一遍数据库,发现没转换的,循环转换...
这样转换和网站就可以脱离开了...”
能具体说下思想吗?或则可能的话给我点源代码,顺便让我学学习c方面的饿知识啊。:handshake
“我也是直接写了一个类...用asp.net调用外部程序(ffmpeg.exe),转换,然后获取返回的信息...来写到数据库...
而这个类是用一条新的进程来执行的...网站主线程不需要等待...
而且这个类还会自动扫描数据库...只要 ... [/quote]
我是用C#写的...代码有啊...这论坛就有...
[url=http://bbs.chinavideo.org/viewthread.php?tid=2326&extra=page%3D1]http://bbs.chinavideo.org/viewthread.php?tid=2326&extra=page%3D1[/url]
那是C#写的...不知道你看得明白不...
然后调用转换类(或者方法)...扫描数据库...做个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转换的并发问题的?
我看了你写的思路,恩,收获很大的。这可是说真的啊。我现在呢,有了两种想法,一种是在在客户端,一种是在服务器端去处理转换的。呵呵,现在只是在构想中。
我绝对支持你说的那句话,程序员....只有想不到,没有 ... [/quote]
客户端转可以...
但是用户会产生不好的心理...
谁叫客户都是上帝...
而且客户端转会产生很多意想不到的问题...超出你的控制范围...
在服务器端转呢...出错了,还有挽救的余地.