【思路】-分页条 分页下的导航条算法

实现:分页下的导航条算法

输入:总页数 ,每页显示条数,第几页,链接,中间页数

输出:一段固定的html代码,然后配合Css样式实现分页的效果

规则:

  • 当是第一页时:上一页处于禁用状态
  • 当是最后一页:下一页处于禁用状态
  • 当页数比较多时,中间显示省略号表示有很多页,防止分页条过长

分析过程

将整个分页条拆分出几个部分来组成

上一页

下一页

首页

最后一页

总条数

中间页面

这六个部分组成 其中首页和最后一页都是固定的

实现过程

第一步:

计算出总页数

总页数对每页显示条数求整运算,然后在做求余运算,余数大于0

就要在求整的结果上加上1

就得到总页数了

第二步:

每个步骤的链接

首页的链接是1,ReplaceStr(linkUrl, “id”, “1”)

最后一页的ID是总页数

上一页的链接是 当前页减去1

下一页的链接是 当前页加上1

第三步:

何时禁用按钮呢?

当当前页==1是 上一页禁用

当当期页==总页数是下一页禁用

难点在中间页码该如何计算处理

最后使用全局变量 逐个追加各个变量

扩展:

增加下拉框功能

增加快速跳转到多少页功能

分页条具有多种格式

比如

只显示上一页下一页,不展示中间页码【访客不知道我们网站到底有多少条数据】

【思路】-博客-自动发布功能设计思路-只说思路具体实现靠自己

VTSBlog自动发布

wordpress有自动发布的功能,我的实现过程是

在Post的表中设计一个PublishTime的字段 例如“2016-06-16 08:56:00”表示这个Post在这个时间开始发布

那么在前台调用数据的时候只需要让发布时间和当前时间做比对进行筛选,小于等于当前时间的就是已发布的,大于当前时间的就是未发布的

本质:就是一个比较时间大小的问题

自动发布:就是表中PublishTime字段按照一定的时间间隔来排列,这样每天查询出的数据都是最新的数据,从而实现自定发布的功能.

如何为系统中的所有Post实现自动的时间间隔呢?间隔时间的生成

问题:我想每天自动发布5条数据
比如有100条数据,我们想办法为这100条数据生成一段连续的时间间隔,就可以不用管网站了,每天都是自定发布

输入:起始发布时间,每天发布多少条,要发布的PostID列表
输出:每个PostID对应的发布时间

最后:采用批量更新的方式更新你的数据表,整个过程就完成了
这是一道数学题

100条数据每天发布5条,发布其实时间从今天00:00:00开始计算 就需要20天才能发布完
也就是100条数据生成20个发布时间间隔,每5个为一组,从二十个时间间隔中取出一个,直到完全取完

注意考虑:没有除尽的情况 101条的话就要21个发布时间间隔了
好了这个数学题思路我都说完了,还可以进行很多的扩展。

比如:设置间隔发布时间
有人说间隔时间怎么弄啊Datetime 有一个加天 加小时的函数。

【思路】-IP访问控制AccessControl-Httpmodule设计实现

IP访问控制AccessControl
用途:用来封杀访客的请求,基于访客IP的控制:可以访问?不可以访问?分时段访问?等等一些特殊的要求

实现思路如下
第一步:需要获得访客的IP,获取方式如下
通过.net内置的函数实现,可能没法知道访客是不是通过代理来访问的【当然也没必要做的那么死】
通过第三方的js代码,这种靠谱一些【需要访客在第一次访问我们网站的时候使用Ajax的方式将IP发送到我们的系统中去】
http://pv.sohu.com/cityjson?ie=utf-8
js代码这种方式也有可能不准备【不过要寻找到好的获取IP的第三方的扩展】
第二步:和我们系统中一个IP段,txt格式的做匹配
如果这个客户的IP在我们的IP访问段当中了,我们就做自己想做的事情

难点1:算法 IP和IP段匹配的过程
有几种实现的方式:
我采用了最笨的一种方法:效率比较低 但是非常好理解
如果一个IP在一个IP段内,它的四个值 必定是大于等于起始段 并且小于等于结束段 【每个值都是如此,不信你来找我】
所以我逐个判断IP的四个值,最终确定这个IP是不是在这个IP段中
难点2:IP范围数据量大
比如:禁止美国访客的访问;或者禁止中国的访客访问等等
光美国的IP的条数 就有5000多条,就意味着需要这个访客IP要在这5000数据中循环匹配5000多次,效率的话就不太好
需要优化这个算法,更快的执行判断
暂时想到的
1.5000条数据缓存在Memcahed中去,避免在当前的进程中占用过多的内存
2.分离中这些IP段的头一个值,和访客的IP的第一个值 在接下来做文章【设想中。。。未实现】
目的:就是尽量减少IP的匹配次数
扩展:既然可以做IP的访问控制,那也就可以通过UA来控制基于浏览设备的控制,骚年继续思考吧

ffmpeg-140秒提取方案 精确时间提取视频 twitter专用2分20秒视频

关键字:twitter视频|ffmpeg|ffmpeg精准提取视频

脚本版本1

@echo off

ffmpeg -ss 00:01:55 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_1.mp4
ffmpeg -ss 00:03:35 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_2.mp4
ffmpeg -ss 00:05:15 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_3.mp4
ffmpeg -ss 00:06:55 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_4.mp4
ffmpeg -ss 00:08:35 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_5.mp4
ffmpeg -ss 00:10:15 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_6.mp4

echo "file 'C9268AF3D6A91C8F0788BAECE2DEE01C_1.mp4'\nfile 'C9268AF3D6A91C8F0788BAECE2DEE01C_2.mp4'\nfile 'C9268AF3D6A91C8F0788BAECE2DEE01C_3.mp4'\nfile 'C9268AF3D6A91C8F0788BAECE2DEE01C_4.mp4'\nfile 'C9268AF3D6A91C8F0788BAECE2DEE01C_5.mp4'\nfile 'C9268AF3D6A91C8F0788BAECE2DEE01C_6.mp4'" >>G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt

ffmpeg -f concat -i G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt -c copy -y G:\GoogleVideo\1020\Prev\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4

echo "14\n"

脚本版本2

@echo off

ffmpeg -ss 00:01:55 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_1.mp4
ffmpeg -ss 00:03:35 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_2.mp4
ffmpeg -ss 00:05:15 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_3.mp4
ffmpeg -ss 00:06:55 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_4.mp4
ffmpeg -ss 00:08:35 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_5.mp4
ffmpeg -ss 00:10:15 -t 23 -i G:\GoogleVideo\1020\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4 -y -c:v libx264 -c:a aac -strict experimental -b:a 98k -y G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_6.mp4

echo file 'G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_1.mp4' >>G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt
echo file 'G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_2.mp4' >> G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt
echo file 'G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_3.mp4' >> G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt
echo file 'G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_4.mp4' >> G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt
echo file 'G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_5.mp4' >> G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt
echo file 'G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_6.mp4' >> G:\\GoogleVideo\\1020\\temp\\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt

ffmpeg -f concat -i G:\GoogleVideo\1020\temp\C9268AF3D6A91C8F0788BAECE2DEE01C_files.txt -c copy -y G:\GoogleVideo\1020\Prev\C9268AF3D6A91C8F0788BAECE2DEE01C.mp4

echo 14

【思路】-【ImagesRename】-检查图片是否存在的设计思路

重命名

输入主图列和详细图列【竖线分割的文件名】,图片源目录,
输出重命名之后的图片和新命名的主图名字和详细图名字【保存在E盘】

如果文件不存在,那么新名字一行将为空
读取Excel获得Reader,然后循环处理每一行
获得主图原名称,获得文件的扩展后缀,生成新的名字。命名方式:随机编号 ;基于主图名字;基于产品名字;
随机编号:采用时间命名,为了防止程序过快重复,追加一个后缀变量i,来保证新名字每个都是唯一的
主图名字:西欧字符有可能不能正确命名,采用一个函数,逐个过滤每个字符串,只保留a-z 0-9 空格,下划线,减号等字符,保证新名称 每一个都是唯一的
详细图:兼容zencart的命名格式,在主图的基础上追加”_“+i的方式生成

处理完成一列之后,如果图片重命名成功之后,在Stringbulider 变量中保存这个新名字,处理完成一行直接换行
先复制主图,主图复制完成之后在复制详细图
Path.GetExtension 可能因为字符的问题引发异常,所默认需要给一个默认的后缀名

如何保存生成之后的新的详细图列呢?
使用一个变量:复制成功之后就在整个变量上累加”|”,如果不成功就累加空
每次处理完一行之后,重新将整个变量置为空
可以扩展到任意后缀的文件重命名
增加复制成功的图片个数统计
用来校队图片文件数

检查


用来检查Excel图片列中的主图列在文件目录中都是存在的,防止图片不存在
循环读取Excel的每一行,获得名字,获得文件的路径地址,判断文件是否存在,如果不存在变量递增1
函数从第二行开始计算
最后检查变量如果不存在的图片为0,表示图片和名字一一对应上,大于0表示 名字和图片文件没有对象需要重命名

过滤


用来将图片文件从众多的图片中分离出来,保存在另一个目录
【前提】Excel列中保存的图片名字都不重复,必须在对图片重命名之后,才使用此功能
输入源目录 保存目录 数据Excel文件
循环读取Excel中的每一行,获得文件名,获得文件地址。判断存在,开始复制
分文件夹过滤
Excel中包含文件夹列:用来将图片分别复制到不同的文件夹中去
读取一行,读取文件名 读取文件名名
如果文件不存在,创建文件夹,开始复制文件

检查重复


输入一个Excel文件,将需要检查的一列命名成“重复”
用来检查Excel中的名字列是否有重复的,可以检查图片的下载链接
创建一个List集合,使用Contains函数,如果包含这个字符串就输出这个字符串
否则就添加到集合中去

创建文件
用来根据Excel中的表格数据,创建生成IndexFile和Resource表的SQL语句

ffmpeg-错误-提取视频预览时 报错-h.264 – FFMPEG (libx264) height not divisible by 2

I sometimes get the following error:

[libx264 @ 0xa3b85a0] height not divisible by 2 (520×369)

归结原因就是 height 不是偶数

After playing around with this a bit, I think I’ve answered my own question. Here is the solution in case anyone else runs into a similar issue… I had to add the below argument to the command:

-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

Command

ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

Basically, .h264 needs even dimensions so this filter will:

Divide the original height and width by 2
Round it down to the nearest pixel
Multiply it by 2 again, thus making it an even number

https://stackoverflow.com/questions/20847674/ffmpeg-libx264-height-not-divisible-by-2

http://www.itkeyword.com/doc/3596353026169028160/ffmpeg-libx264-height-not-divisible-by-2

ffmpeg-命令使用汇总-不断更新中

转mp4格式

ffmpeg -i input.mp4 output.avi
FFMPEG  -i  uploadfile/video/test.wmv -c:v libx264 -strict -2 uploadfile/mp4/test.mp4
FFMPEG  -i  uploadfile/video/test.wmv -c:v libx264 -strict -2 -s 1280x720 -b 1000k uploadfile/mp4/test.mp4

截取一张图片

使用说明
测试视频
66666.MP4
2155秒

请问视频1秒播放几帧图像,使用ffmpeg反复在同一秒截取图片是否截取的是同一帧图像?
答案是:是同一张图片

【通过】截取一张图片
ffmpeg -ss 00:00:30 -i input.mp4 -f image2 -y 66666-1.jpg

参数说明

-i 设定输入流
-f 设定输出格式 【网上说一般不用,会更加后缀名自动识别,但是我还是每次都加上】
image2 表示输出jpg格式
-ss 开始时间【时间格式:允许毫秒】 从视频哪里开始处理
比如下面的格式都是有效的
‘55’
55 seconds

‘12:03:45’
12 hours, 03 minutes and 45 seconds

‘23.189’
23.189 seconds


-y 覆盖输出文件 同名 不需要询问直接覆盖
【备注】 建议把ss参数放在 -i参数之前使用

截取多张图片

ffmpeg -i input.mp4 -r 1 -q:v 2 -f image2 pic-%03d.jpeg

-r 表示每一秒几帧
-q:v 表示存储jpeg的图像质量,一般2是高质量
如此,ffmpeg会把input.mp4,每隔一秒,存一张图片下来.假设有60s,那会有60张 [如果视频特别长就会截取很多图片来,所以要设置一个时间段儿]

设置开始的时间,和你想要截取的时间,每秒1帧

ffmpeg -ss 00:00:30 -t 10 -i input.mp4  -r 1 -q:v 2 -f image2 -y pic-%03d.jpeg

-t 表示共要多少时间

ffmpeg会从input.mp4的第20s时间开始,往下10s,即20~30s这10秒钟之间,每隔1s就抓一帧,总共会抓10帧

其他
每秒2帧
ffmpeg -ss 00:00:30 -t 10 -i 66666.mp4 -r 2 -q:v 2 -f image2 -y pic-%03d.jpeg

每秒23帧 持续40秒 920张
ffmpeg -ss 00:00:30 -t 40 -i 66666.mp4 -r 23 -q:v 2 -f image2 -y pic-%03d.jpeg

每秒25帧 持续2秒 【默认25帧】
ffmpeg -ss 00:00:07 -t 2 -i 66666.mp4 -r 25 -q:v 2 -f image2 -y pic-%03d.jpeg

可以设置1.5吗
每秒24帧 持续1.5秒 36张图
ffmpeg -ss 00:00:07 -t 1.500 -i 66666.mp4 -r 24 -q:v 2 -f image2 -y pic-%03d.jpeg

最终:视频9秒 6个场景 每个场景1.5秒 持续截取1.5秒 开始在7.5秒左右 每秒24帧图像 一共36张图片

ffmpeg -ss 00:00:07.500 -t 1.500 -i input.mp4  -r 24 -q:v 2 -f image2 -y pic-%03d.jpeg

下面这个不清楚-r 0.2

假如影片第10分钟到第20分钟之间,每隔5秒截一张 共计120张
ffmpeg -ss 10:00 -t 10:00 -i 66666.mp4 -r 0.2 -q:v 2 -f image2 -y pic2-%03d.jpeg
ffmpeg -ss 10:00 -i input -f image2 -r 0.2 -t 10:00 %3d.jpg

设置输出帧大小 -s 480X270 300X168

ffmpeg -ss 00:00:07.500 -t 1.500 -i input.mp4  -r 24 -q:v 2 -f image2 -y -s 480X270 pic-%03d.jpeg

提取视频

ffmpeg -i "A_File.mp4" -ss 00:00:0.0 -t 10 -an "B_File.mp4"
-an 不处理音频

【通过】提取视频–默认方式
ffmpeg -ss 00:00:07.500 -t 1.500 -i 66666.mp4 -y -an B_File.mp4

【通过】提取视频–指定尺寸
ffmpeg -ss 00:00:07.500 -t 1.500 -i 66666.mp4 -y -an -s 480X270 B_File.mp4

【通过】提取视频–缩放方式
ffmpeg -ss 00:00:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File.mp4

ps: 如果540不写,写成-1,即scale=960:-1, 那也是可以的,ffmpeg会通知缩放滤镜在输出时保持原始的宽高比。【但是必须保证一定的比率】,否则就会向下面这样报错

【不通过】 height not divisible by 2 (300×169)
ffmpeg -ss 00:00:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=300:-1 B_File.mp4

【通过】
ffmpeg -ss 00:00:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=300:168 B_File.mp4

通过设置高度168 可以解决

提取视频【实际使用】

在实际使用中我使用下面的命令提取视频

ffmpeg -i 88888.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 cutout1.mp4 -y
ffmpeg -i 88888.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 -ss 00:01:30 -to 00:01:50 cutout1.mp4 -y
ffmpeg -ss 00:46:28 -i "Morning_News.asf" -acodec copy -vcodec copy -t 00:03:25 output.asf

这行命令解释为:从文件 Morning_News.asf 第 46:28 分秒开始,截取 03: 25 的时间,其中视频和音频解码不变,输出文件名为 output.asf

这样提取出来的视频和原始视频一样的编码

视频合并

首先提前截取各个场景

480
ffmpeg -ss 00:00:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File1.mp4
ffmpeg -ss 00:06:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File2.mp4
ffmpeg -ss 00:12:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File3.mp4
ffmpeg -ss 00:18:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File4.mp4
ffmpeg -ss 00:24:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File5.mp4
ffmpeg -ss 00:30:07.500 -t 1.500 -i 66666.mp4 -y -an -vf scale=480:-1 B_File6.mp4

合并视频

ffmpeg -f concat -i files.txt -c copy -y output.mp4

files.txt格式如下

file 'B_File1.mp4'
file 'B_File2.mp4'
file 'B_File3.mp4'
file 'B_File4.mp4'
file 'B_File5.mp4'
file 'B_File6.mp4'

再看一个例子

264秒
ffmpeg -ss 00:00:07.500 -t 1.500 -i 88888.mp4 -y -an -vf scale=480:-1 B_File1.mp4
ffmpeg -ss 00:00:51.500 -t 1.500 -i 88888.mp4 -y -an -vf scale=480:-1 B_File2.mp4
ffmpeg -ss 00:01:35.500 -t 1.500 -i 88888.mp4 -y -an -vf scale=480:-1 B_File3.mp4
ffmpeg -ss 00:02:19.500 -t 1.500 -i 88888.mp4 -y -an -vf scale=480:-1 B_File4.mp4
ffmpeg -ss 00:03:03.500 -t 1.500 -i 88888.mp4 -y -an -vf scale=480:-1 B_File5.mp4
ffmpeg -ss 00:03:47.500 -t 1.500 -i 88888.mp4 -y -an -vf scale=480:-1 B_File6.mp4
ffmpeg -f concat -i files.txt -c copy -y output2.mp4

视频转码

一个视频的编码是MPEG4,想用H264编码,咋办?

ffmpeg -i c.mp4 -vcodec h264 c_output.mp4

相反也一样

ffmpeg -i input.mp4 -vcodec mpeg4 output.mp4

当然了,如果ffmpeg当时编译时,添加了外部的x265或者X264,那也可以用外部的编码器来编码。

(不知道什么是X265,可以 Google一下,简单的说,就是她不包含在ffmpeg的源码里,是独立的一个开源代码,用于编码HEVC,ffmpeg编码时可以调用它。当然 了,ffmpeg自己也有编码器)
ffmpeg -i input.mp4 -c:v libx265 output.mp4
ffmpeg -i input.mp4 -c:v libx264 output.mp4

ffmpeg-gif-图片合成Gif命令-秋名山

命令如下

C:\Users\Administrator\AppData\Local\Temp\ScreenToGif\Recording\
ffmpeg.exe -f image2 -i C:\Users\Administrator\AppData\Local\Temp\ScreenToGif\Recording\G1006\%d.png -vcodec libx264 -r 10 G1006.mp4

ffmpeg.exe -f image2 -i C:\Users\Administrator\AppData\Local\Temp\ScreenToGif\Recording\G1015\%d.png -vcodec libx264 -r 10 G1015.mp4

ffmpeg支持很多中视频格式,想知道ffmpeg支持哪些编码格式,可以用 ffmpeg -codecs 命令来查看

你的图片可以是jpg, 可以bmp,可以是tiff。其他的格式可以自己测试

假如你的图片在c:\temp\下面。那么通过下面的命令就可以将这个目录下面的图片转换成视频。这里面有个要求就是你的图片全部是自然数为文件名, 001, 002, 003这样的。前面要几个0取决于你的图片的个数,如109张,那么就是3-1=2个0,从001 到109,如果是1009张就是0001到1009

ffmpeg -f image2 -i c:\temp\d.jpg test.mp4

你可以指定编码格式:

ffmpeg -f image2 -i c:\temp\d.jpg -vcodec libx264 test.mp4

也许你还想指定输出帧率:

ffmpeg -f image2 -i c:\temp\d.jpg -vcodec libx264 -r 10  test.mp4

这样输出的test.mp4就是每秒播放10帧了

如果你要指定码率:

ffmpeg -f image2 -i c:\temp\d.jpg -vcodec libx264 -r 10 -b 200k  test.mp4

注意这里的200k的单位bit/s.

最后生成的文件的参数都是什么样子,比如我们刚才设置的参数,还有我们没有设置的参数:

那么这个命令就可以帮你搞定:

ffmpeg -i test.mp4

前面是你用的ffmpeg的基本信息:

包括版本,编译时间,用的编译器,配置选项。

重点看绿色部分,这也是你会关心的东西:

duration告诉视频时长,这里是10秒, bitrate是码率。

video: 视频编码格式。 帧率是10fps。

【思路】-GIF加水印

GIF加水印
目的:实现GIF加水印的效果,实现水印文字在GIF移动的效果


脑补知识:帧,GIF是一组帧的集合,帧是一张张图片按照顺序进行展示,每张帧有自己的延迟时间,所以整体来看GIF播放效果就是每张帧延迟一定的时间,最终看到GIF播放的效果
关于帧延迟:该帧的延迟时间就是下一帧的间隔时间

实现思路


通过2345看图王发现一个保存帧的功能,保存之后在一个文件夹下发现了一组静态的图片
也就说明可以从GIF中提取帧
第一步:从GIF提取帧
第二步:对提取之后的帧,也就是每张图单独的使用GDI编程加水印
第三步:关键点:合成,合成不是我来做的用到一个开源的组件Gif.Components,这个组件提供了这个功能
通过给这个组件输入一组按一定顺序的Image对象,并设置一个延迟,最终输出一个GIF图片 实现我们加水印的功能

提取帧


GIF通过绝对路径的方式初始化系统中的一个Image对象,该对象可以获取到GIF所有的帧GetFrameCount
循环遍历,并激活当前帧,在使用gif.Save(fileName, ImageFormat.Jpeg);把帧提取出来最终完成帧的提取工作

下一步就是逐个加水印


WaterMark 来自于别人写的类,可以实现文字水印和图片水印
既然加水印,就可以设置水印的位置,对于提取之后的每张帧,我们在处理完第一张帧是之后,让第二张帧偏移指定的像素,这样合成之后就可以实现文字的移动效果
通过控制x-y 两个方向上的偏移,文字可以实现各种移动的效果

批量加水印


多线程的使用:对此有几点说明
1.在线程上调用方法,所谓多线程,其实就是在线程上调用方法,并且传递你自定义的数据对象【我觉得学习多线程入门这一点一定要记住:方法是在线程上调用的,线程一开启方法就会执行】
2.包:就是传递给线程指定方法的自定义的参数对象

所以我将整个处理GIF加水应的写在一个总的函数里面,GifRun(object gd) 该函数接收一个自定义参数,包括了该函数所需要的全部数据
通过外面的循环实例化线程对象,开始执行每一个加水印的任务【一个GIF的处理就是一个任务,就需要一个线程对象来处理】
注意点:所有的都使用实例对象来完成,暂时不适用静态的方法和字段
美中不足
GIF合成的组件处理完成之后GIf的效果和原始的GIF多少还有些差别,这个地方暂时无法解决