生成影片的预览图像另Mencoder和ffmpeg使用实例小全
授权方式:署名,非商业用途,保持一致,转载时请务必以超链接(http://www.fwolf.com/blog/post/251)的形式标明文章原始出处和作者信息及本声明。下载电影的时候,我们总希望在全部下载完成之前能够预览一下影片内容,于是发布者时常会放一些影片截图在种子文件中,或者直接贴到网上,也有一些截图是一张图片,但包含很多幅影片在一起,就像下面这张:

有很多软件能够截取影片图像、合并图像,但如果影片太多,比如视频网站为用户上传的图像生成预览图之类的,人工在gui方式下操作就不可取了,我们需要在命令行方式下来截取、合并。
首先,截取影片图像使用最多的就是mplayer或者ffmpeg,我用mplayer比较熟,本文就以此为例了,ffmpeg功能也是非常强大的,但据说支持的文件格式却不丰富。mplayer截取影片图像的基本命令为:
mplayer -ss START_TIME -noframedrop -nosound -vo jpeg -frames N NAME_OF_VIDEO_FILE
上例中,-ss指定开始的时间,结合-frames参数,限定从某个时间开始、截取几帧图像。为了体现整个影片的内容,我需要在影片中间隔时间相同的几个点、每个点截取1帧图像,所以按道理应该用-frames 1,但是mplayer这样截图的情况下,第一帧似乎永远都会截取到一个黑屏,所以我常用-frames 2。截取下来的图像保存在了当前目录,名称从00000001.jpg开始依次递增,按照-frames 2,就是取00000002.jpg为结果,删除00000001.jpg即可。经过简单实验,在截取wmv、rmvb影片时,前面的好几帧都会是黑屏,也只能参考上面的做法多取几帧了。
为了取影片中间隔大致相同的几个点,可以用-ss指定时间,也可以用-sb指定开始字节,在我的实际使用中,使用-sb只会得到黑屏,所以通过文件大小来设置间隔点的办法不行,只能用-ss时间间隔了,这就需要首先得到影片的总时间。好在mplayer为我们提供了类似的功能:
mplayer -identify movie-filename -nosound -vc dummy -vo null
这样会输出一大堆影片信息,从中截取所需内容即可,在bash shell中,取得影片总时间长度(以秒为单位)的命令如下:
FILESIZE=`mplayer -identify -nosound -vc dummy -vo null $1 | grep ID_LENGTH | sed -r 's/ID_LENGTH=([[:digit:]]*)(\.[[:digit:]]*)?/\1/g’`
有了影片的总时长,我们就可以根据所要截取的帧数,计算出每个间隔点的时间位移了。不过要注意一般影片的开始-ss 0和结束-ss TOTAL_TIME_OF_VIDEO截取下来都会是黑屏,在处理的时候要分别加上和减去若干秒。
截取工作完成后,我们拥有了一堆000000xx.jpg文件,如果能把这些文件都放到一个文件中,每行2张,成为一张大图片,在发布的时候会很方便。所以,我们使用imagemagick中的montage命令来实现:
montage -geometry +0+0 -tile 2 *.jpg montage.jpg
-geometry +0+0是设定使用原始图片大小,-tile 2参数设定每行放2张图片,最后一个参数是要生成的目标文件名,现在,我们就能够得到像刚才那张一样的图片了。
原理已经讲清楚了,可以自己写一个bash脚本来方便调用,我在网上找到了一个很不错的例子,可以在这个基础上进行修改,过程不再详述了。
下面再列一些在网上找到的其他mplayer、mencoder、ffmpeg的使用实例:
mplayer获取影片信息
mplayer -identify movie-filename -nosound -vc dummy -vo null
从所有输出中可以grep到如下信息:
- filetype: ASF file format detected.
- dimensions and format: VIDEO: [MP43] 320×240 24bpp 1000.000 fps 0.0 kbps ( 0.0 kbyte/s)
- video format: ID_VIDEO_FORMAT=MP43
- width (dimensions): ID_VIDEO_WIDTH=320
- height (dimensions): ID_VIDEO_HEIGHT=240
- length in seconds: ID_LENGTH=98.00
mencoder图片做成电影
-
用当前目录中的所有JPEG文件创建DivX4文件:
mencoder \*.jpg -mf on:w=800:h=600:fps=25 -ovc divx4 -o output.avi -
用当前目录中的一些JPEG文件创建DivX4文件:
mencoder -mf on:w=800:h=600:fps=25 -ovc divx4 -o output.avi \*.jpg -
用当前目录中的所有JPEG文件创建Motion JPEG(MJPEG)文件:
mencoder -mf on:w=800:h=600:fps=25 -ovc copy -o output.avi \*.jpg -
用当前目录中的所有PNG文件创建一个非压缩的文件:
mencoder -mf on:w=800:h=600:fps=25:type=png -ovc rawrgb -o output.avi \*.png
简单用法:
mencoder *.jpg -mf on:fps=15 -o output.avi -ovc xvid
ffmpeg屏幕录像
ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s 1024x768 ~/test.avi
其中,-vd x11:0,0 指录制所使用的偏移为 x=0 和 y=0,-s 1024×768 指录制视频的大小为 1024×768。录制的视频文件为 test.avi,将保存到用户主目录中。其他选项可查阅其说明文档。
如果你只想录制一个应用程序窗口或者桌面上的一个固定区域,那么可以指定偏移位置和区域大小。使用xwininfo -frame命令可以完成查找上述参数。
你也可以重新调整视频尺寸大小,如:./ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -i ~/test.avi -s 800×600 ~/test-800-600.avi。
参考5
mplayer对video进行截屏 截图(wmv mpeg mov flv all works)
mplayer 78.mov -ss 1 -nosound -vo jpeg:outdir=./ -frames 2
我截的第一张图不知为何全部都是黑屏
参考4
转换为flv文件
mencoder NOW.wmv -ffourcc FLV1 -of lavf -ovc lavc -lavcopts vcodec=flv:acodec=mp3:abitrate=56 -srate 22050 -oac mp3lame -o NOW.flv
ffmpeg -i a.asf -ab 56 -ar 22050 -b 500 -r 15 -s 320×240 asf.flv
使用ffmpeg抓图
ffmpeg -i test2.asf -y -f image2 -ss 08.010 -t 0.001 -s 352x240 b.jpg
jpg: ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352x240 -ss a.jpg //注意-ss就是要提取视频文件中指定时间的图像
jpg: ffmpeg -i asf.flv -y -f image2 -t 1 asf.jpg
gif: ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
如何合并几个视频片段
mencoder -oac copy -ovc copy -idx -o output.avi video1.avi video2.avi video3.avi
- 其中,-oac copy 选项告诉 mencoder 要正确拷贝音频流。而 -ovc copy 选项则是拷贝视频流。
- 如果在视频文件中没有找到索引的话,那么 -idx 选项会要求 mencoder 建立它。
- -o 选项指定输出文件的名称。
- 最后几个参数为需要合并的几个视频片段。

Save to Browser Favorites
Ask
backflip
blinklist
BlogBookmark
Bloglines
BlogMarks
Blogsvine
BUMPzee!
CiteULike
co.mments
Connotea
del.icio.us
DotNetKicks
Digg
diigo
dropjack.com
dzone
Facebook
Fark
Faves
Feed Me Links
Friendsite
folkd.com
Furl
Google
Hugg
Jeqq
Kaboodle
linkaGoGo
LinksMarker
Ma.gnolia
Mister Wong
Mixx
MySpace
MyWeb
Netvouz
Newsvine
PlugIM
popcurrent
Propeller
Reddit
Rojo
Segnalo
Shoutwire
Simpy
sk*rt
Slashdot
Sphere
Sphinn
Spurl.net
Squidoo
StumbleUpon
Technorati
ThisNext
Webride
Windows Live
Yahoo!
Email This to a Friend
If you like this then please subscribe to the
November 10th, 2006 at 11:48:07
cool and funny
[Reply]
December 11th, 2006 at 18:05:22
这是博主的令一个博?还是你的文章给人盗了?
连个转贴字样都没有啊!替你不值。
http://shadow.wohuan.com/archives/353
[Reply]
December 12th, 2006 at 9:18:07
To: lerosua
谢谢提醒,我这个才是“正宗”的,shadow那个不是我的blog,
并且在转载时去掉了源地址与cc信息
我去留言提醒他一下
shadow抄也不抄全一点,图片引用的还是我放在flickr的图片
[Reply]
December 12th, 2006 at 17:17:05
抱歉啦, 我抄过去是为了看着方便一点, 你们真吝啬 :( 回头我加上
[Reply]
December 12th, 2006 at 17:19:19
[...] 原文???Fwolf’s Blog [...]
December 18th, 2006 at 10:45:15
shadow, 这并不是吝啬问题。而是对别人劳动的基本尊重。其实加上一个url也是费一点点时间。
并且博主是明确地说了:
授权方式:署名,非商业用途,保持一致,转载时请务必以超链接(http://www.fwolf.com/blog/post/251)的形式标明文章原始出处和作者信息及本声明。
和谐社会,尊重版权嘛!呵呵!
[Reply]
December 19th, 2006 at 10:34:33
谢谢楼上
一起努力,共建和谐社会!
[Reply]
December 20th, 2006 at 16:59:30
感謝,你的整理是我看過最容易使用也夠全面的了!
我們公司內部是使用 transcode 來把 image sequence 轉為 video,不過正在考慮改以 mplayer 來做
[Reply]
March 13th, 2007 at 17:08:26
为了能够得到文件的播放的总时间??
在执行下面BASH的时候,出错阿??
FILESIZE=
mplayer -identify -nosound -vc dummy -vo null $1 | grep ID_LENGTH | sed -r ’s/ID_LENGTH=([[:digit:]]*)(\.[[:digit:]]*)?/\1/g’错误提示:
bash:syntax error near unexpected token ‘(’
你们 都没 提示错误吗?
[Reply]
March 13th, 2007 at 17:20:33
在bash shell中,取得影片总时间长度(以秒为单位)的命令如下:
FILESIZE=
mplayer -identify -nosound -vc dummy -vo null $1 | grep ID_LENGTH | sed -r ’s/ID_LENGTH=([[:digit:]]*)(\.[[:digit:]]*)?/\1/g’怎么看取得的总时间??
在 终端以上命令
然后我通过$FILESIZE怎么什么都 没有?能给我说详细点么?
实在是着急,希望能快点得到您的回复,谢谢!!
[Reply]
March 14th, 2007 at 10:05:33
楼上的,wordpress发布文章的时候,会自动把英文单引号改成中文的单引号
你粘贴命令过去执行的时候要手工更正过来才行
[Reply]
April 20th, 2007 at 18:47:02
[...] 本方法还参考了《 生成影片的预览图像另Mencoder和ffmpeg使用实例小全 》, 在我没有想到用rma之前, 本来想只能靠mplayer来获取片子的总长, [...]
May 9th, 2007 at 22:48:56
我有mplayer对flv文件进行截屏时得到的总的图片总是黑屏,请问一下楼主知道是什么原因吗?谢谢
[Reply]
May 10th, 2007 at 0:11:42
第一帧好像总是会黑屏,直接取第二帧就行了。
[Reply]
May 10th, 2007 at 17:44:49
取WMV文件时,取第二帧是好的。
可是取FLV文件时,不管取第几帧都是黑屏。。很郁闷。
[Reply]
May 11th, 2007 at 0:17:10
可以变通一下,先使用截取影片功能把头1秒截取出来存为xvid什么的格式(24帧)
然后再进行截图
另外用ffmpeg截flv的图是否效果更好一些?
[Reply]
December 4th, 2007 at 17:43:42
請問要如何使用ffmpeg 抓取串流的資料
例如 rtsp://p1401.demo.pixord.com
除了抓之外又可以當成proxy 轉出去
因為我看vlc 他有這樣的功能
所以想ffmpeg 也該會有才對
只是不知道如何用, 因為他的官方介紹並沒有這塊
但是您在這方面相當有經驗, 所以來請教您如何來處理
謝謝您
[Reply]
December 4th, 2007 at 22:46:56
实在抱歉,我对处理在线视频这快不熟悉,甚至不知道ffmpeg或者mencoder能否处理他们
我在mencoder的man里面也没有看到转换在线视频的资料。
不过,如果能用某种方法把在线视频下载下来(这方面工具应该还是有的)
就能够用ffmpeg转换成其它格式。
另外,如果你只是想作转发的话,根本用不到这些转码工具,
只需要用支持相关协议的防火墙或者iptables,
进行相关协议、端口的转发就可以了。
[Reply]
December 17th, 2007 at 15:45:59
我在Windows下使用mplayer命令行:
mplayer.exe -ss 30 -noframedrop -nosound -vo jpeg -frames 2
F:\movies\test.rmvb -zoom -x 150 -y 150
结果(最后部分)如下:
Opening video decoder: [realvid] RealVideo decoder
Opening video decoder: [realvid] RealVideo decoder
Opening video decoder: [realvid] RealVideo decoder
Cannot find codec matching selected -vo and video format 0×30345652.
Opening video decoder: [realvid] RealVideo decoder
Error loading dll
ERROR: Could not open required DirectShow codec drvc.so.
Read the RealVideo section of the DOCS!
VDecoder init failed
Error loading dll
ERROR: Could not open required DirectShow codec drv4.so.6.0.
Read the RealVideo section of the DOCS!
VDecoder init failed
Error loading dll
ERROR: Could not open required DirectShow codec drv43260.dll.
Read the RealVideo section of the DOCS!
VDecoder init failed
Error loading dll
ERROR: Could not open required DirectShow codec drvc.bundle/Contents/MacOS/drvc.
Read the RealVideo section of the DOCS!
VDecoder init failed
Read DOCS/HTML/en/codecs.html!
得不到视频图片。
请问如何解决?
谢谢!
[Reply]
December 19th, 2007 at 18:07:29
@muzi
看你的错误信息,似乎是你缺少对应的视频解码器。
windows下的东西我不熟,建议你先保证能用mplayer正常播放了,再继续。
[Reply]