最近项目上需求,需要为上传的视频生成封面图片,类似于朋友圈中的小视频图片,点击后才进行视频播放。
经过调研,发现nginx上已经有人写了相应的插件,安装使用方式如下链接
http://www.ttlsa.com/nginx/nginx-modules-video-thumbextractor/
不过,上述方法经过测试,存在较大的性能问题,同一个缩略图多次请求,会存在反复生成的问题,效率不高,且经常存在请求不到的情况。
经过一番测试,决定采用ffmpeg+lua脚本的方式生成缩略图,这种方式可以对生成的缩略图进行缓存,在第一次请求后,生成的缩略图就被保存成图片格式,后续的请求则由nginx直接给客户端返回图片,这种方式,避免了多次生成缩略图造成的计算资源浪费,实际使用下来效果较好,具体的实现方式如下:
安装ffmpeg
#安装yasm依赖
yum -y install yasm
#下载ffmpeg安装包
wget http://mirrors.cmig.host/software/nginx/ffmpeg-3.3.3.tar.bz2
#解压并进入目录
tar -zf ffmpeg-3.3.3.tar.bz2
cd ffmpeg-3.3.3
#预编译
./configure --prefix=/usr/local/ffmpeg/ --enable-shared --disable-ffserver --disable-ffplay --enable-postproc --enable-gpl
#编译及安装
make && make install
nginx配置文件中添加如下配置
location ~* ^/G01/M00/(.+.(mp4|flv))@thumb.jpg
{
root /data/fastdfs/storage/data;
ngx_fastdfs_module;
set $video_root /data/fastdfs/storage/data/;
set $file "$video_root$1@thumb.jpg";
if ( !-f $file ) {
add_header X-Powered-By '90.vc';
add_header file-path $request_filename;
set $request_filepath /data/fastdfs/storage/data/$1;
lua_code_cache on;
content_by_lua_file /etc/nginx/lua/video_thumb.lua;
}
default_type image/png;
}
相应的lua脚本如下:
这里需要注意,目前取的都缩略图是视频第1秒的图片,并没有提供指定时间的功能,如果有需要的话,将下面脚本的 -ss
后面的值修改为接收nginx传入的值即可
local command = "/usr/local/ffmpeg/bin/ffmpeg -i " .. ngx.var.request_filepath .. " -ss 1 -vframes 1 " .. ngx.var.request_filepath .."@thumb.jpg"
os.execute(command);
ngx.exec(ngx.var.request_uri);