吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2748|回复: 27
收起左侧

[其他原创] [跨平台]视频 宫格缩略预览图 生成脚本工具

  [复制链接]
Vvvvvoid 发表于 2023-7-22 19:08
本帖最后由 Vvvvvoid 于 2023-7-24 20:38 编辑

加了个班, 现已支持 Windows

0x0

印象中, 在某榴社区/杏某社区, 查看技术文章的时候, 经常看到一些根据视频制作的宫格缩略图, 如下图. 感觉一张图就能把整个资料一览无遗. 很强大.   

9IE0sK.jpg

大概查了下, 包括很多软件都是基于 ffmpeg 做的二次开发,
所以, 今天把 ffmpeg 下载下来 研究了下这个东西是如何制作的.

0x1 依赖环境

  • ffmpeg

要使用这个工具,您需要在系统上安装ffmpeg

ffmpeg 是一个用于处理音频和视频文件的命令行工具。
ffmpeg 支持广泛的视频和音频格式、编解码器和容器,可以使用各种选项和过滤器进行定制,以达到特定的任务。

ffmpeg 可在 Windows、Mac 和 Linux 上使用,您可以按照官方网站上的说明进行安装。

还有许多第三方应用程序和库使用 ffmpeg 作为后端执行音频和视频处理任务。

0x2 How it works?

经过几天研究, 得出结论 , 要想实现这个宫格效果图,我们需要分三步:

  • 0x0. 根据宫格数量, 将视频拆成 n 个片, 每个片截取一张图最后 合并成一张大图. 顺便将 缩略图当前的时间写入到图片中. 最后输出 大图 pic_x_y
  • 0x1. 生成一张空白大图,获取视频信息(视频大小/长度/文件名) 写如到图片中, 输出 pic_info
  • 0x2. 将 pic_x_y pic_info 俩张图 合并到一块

如果各位大佬有更优解,请指出 ~ 谢谢 !!

0x2.0x0

首先利用 ffprobe 计算视频总时长

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "one-piece.E0162.mkv"
1423.700000

假设 我们要切成 3x4, 那么就是一共12个图 ,
1423.700000/(3x4+1) ~= 109.51
我们根据 chunk 数量 计算平均时间, 这里 + 1 是因为 切片不是从0开始的, 是从第一个片的结束时间开始的. 如果不加1, 很可能最后只能切够 11 个图

之后用 ffmpeg 按 109秒的时间循环截取图片,并且合并成 3x4 的 大图

ffmpeg -i "/Users/voidm/Downloads/one-piece.E0162.mkv" -frames:v 1 -update 1 -vf "select=(gte(t\,109.51))*(isnan(prev_selected_t)+gte(t-prev_selected_t\,109.51)),drawtext=text='%{pts\:hms}':fontsize=h/15:fontcolor=white:x=w/20:y=h/20, scale=636:-1,tile=3x4:padding=20:margin=50:color=gray, " -fps_mode auto "/Users/voidm/Downloads/one-piece.E0162.mkv_time_2.png"

参数介绍:

select=(gte(t\,109.51))*(isnan(prev_selected_t)+gte(t-prev_selected_t\,109.51

  • 109.51: 切片时间

tile=3x4:padding=20:margin=50:color=gray

  • tile=3x4: 指定网格的行列数,这里是 3 行 4 列。
  • padding=20: 指定每个帧之间的间距,这里是 20 像素。
  • margin=50: 指定大图像的边距,这里是 50 像素。
  • color=gray: 指定间距的颜色,这里是灰色。

drawtext=text='%{pts\:hms}':fontsize=h/15:fontcolor=white:x=w/20:y=h/20

  • text='%{pts\:hms}': 指定要添加的文本内容,这里是显示视频时间戳的小时、分钟和秒数。
  • fontsize=h/15: 指定文本字体的大小,这里是视频高度的 1/15。
  • fontcolor=white: 指定文本的颜色,这里是白色。
  • x=w/20: 指定文本的水平位置,这里是视频宽度的 1/20。
  • y=h/20: 指定文本的垂直位置,这里是视频高度的 1/20。

scale=$tile_img_width:-1

scale 是输出分辨率, 用法有俩种. 放到tile前面是代表 tile 每一个切片的大小, 放到后面则是汇总图的大小.

如果在tile之后放置scale,则参数控制最终合成图像的分辨率。并且tile中的padding/margin属性可能无法正确计算。
所以我们这离要放到 tile 前面。
此时我们需要根据最终输出的大图的width , 以及 padding,margin 计算出小图的 width
公式如下:

tile_img_width=$(echo "($composite_img_width - ($padding * ($x-1)) - ($margin * 2)) / $x" | bc)  

假设: composite_img_width =2048,margin=50,padding=20 , 则 tile_img_width = 636

scale= 636:-1

执行完后就有了下图:

one-piece.E0162.mkv_time_2.jpg

0x2.0x1

然后我们将视频信息写入到一张单独的小图中

info=$(ffprobe -v quiet -print_format json -show_format -show_streams "$abs_video_file")
filename=$(echo "$info" | jq -r '.format.filename')
size=$(echo "$info" | jq -r '.format.size')
duration=$(echo "$info" | jq -r '.format.duration')
width=$(echo "$info" | jq -r '.streams[0].width')
height=$(echo "$info" | jq -r '.streams[0].height')

cat >$text_tile <<EOF
Filename: $video_name
Size: $size
Resolution: ${width}x${height}
duration: ${duration}
EOF

先用 ffprobe 获取视频信息, 得到一个 json串,之后 用固定的 jsonpath 获取到视频的时长/大小/分辨率..
然后将这些视频先写入到一个 txt 文件中去, 之后在调用 ffmpeg 生成一张大图, 然后把 txt 写入到大图中

ffmpeg -f lavfi -i color=gray:s=2048x130:d=1 -update 1 -filter:v "drawtext=textfile='/Users/voidm/Downloads/one-piece.E0162.mkv_info.txt':fontsize=24:fontcolor=white:x=50/2:y=h/4" "/Users/voidm/Downloads/one-piece.E0162.mkv_info.png"

参数介绍 :

- lavfi -i color=gray:s=2048x130:d=1:  指定一个灰色的背景,大小为 2048x130 像素  
- drawtext=textfile='/Users/voidm/Downloads/one-piece.E0162.mkv_info.txt':指定要在视频中绘制的文本内容
- fontsize=24 :指定字体大小为 24。
- fontcolor=white: 指定字体颜色为白色。

得到了下图:

one-piece.E0162.mkv_info.jpg

0x2.0x2

最后 将 0x2.0x0 得到的图片 向上拉伸 130px 的位置,把 0x2.0x1 得到的图片 填充进来

ffmpeg -i "/Users/voidm/Downloads/one-piece.E0162.mkv_time_2.png" -i "/Users/voidm/Downloads/one-piece.E0162.mkv_info.png" -update 1 -frames:v 1 -filter_complex "[0:v]pad=iw:ih+130:0:130:color=white[top]; [top][1:v]overlay=0:0" "/Users/voidm/Downloads/one-piece.E0162.mkv_merge.png"

参数介绍:

  • filter_complex: 指定要应用的复杂滤镜,可以在输入流之间进行多个滤镜操作。
    • pad=iw:ih+130:0:130:color=white[top]: 使用 pad 滤镜将第一个输入流的视频流进行填充,使其高度增加 130 像素,并将填充后的视频流保存为 top。
      • iw: 表示填充后的视频宽度与输入视频宽度相同。
      • ih+130: 表示填充后的视频高度比输入视频高度增加了 130 像素。
      • 0:130: 表示在垂直方向上向上填充 130 像素。
      • color=white: 表示填充的颜色为白色。
    • [top][1:v]overlay=0:0: 使用 overlay 滤镜将填充后的视频流 top 和第二个输入流中的视频流进行叠加,将第二个输入流的视频流放置在填充后的视频流的左上角。
      • 0:0: 表示在水平方向和垂直方向上都不向右或向下偏移。

注意这些数字都是计算出来的,比如这里的填充 130 其实就是 信息小图的高度 , 而且 要合并的俩张图的宽度也得是一致的

最终得到成品图 :

one-piece.E0162.mkv_merge.jpg

0x3 一部到胃

为了方便, 我封装制作了一键shell 脚本..

shell.png

Usage:

# Mac/Linux
sh thumbnail_maker.sh sample/video.mp4 4 5

# Windows
.\thumbnail_maker.bat sample\video.mp4 3 4

Github:  

https://github.com/marlkiller/thumbnail_maker↗.

0x3 支持的平台

  • Mac OS
  • Linux
  • Windows

注:若转载请注明来源(本贴地址)与作者信息。

免费评分

参与人数 3威望 +1 吾爱币 +14 热心值 +3 收起 理由
苏紫方璇 + 1 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xiaolong23330 + 1 + 1 细说下啥社区/坏笑
onlyclxy + 3 + 1 正巧这一阵老想着这个东西正好就看见了, 念念不忘必有回响嘛这是

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

死月 发表于 2023-7-22 20:04
这个更省事
视频缩略图制作器汉化绿色版Video Thumbnails Maker Platinum 17.3.0.0_64bit_绿色汉化版

多系统的话确实 如果win上 这个是个人感觉最好用的
onlyclxy 发表于 2023-7-22 21:12
两年前我也写过这样一个需求的代码. 当时是电脑视频太多了. 想都搞成这种缩略图的
但是写的方法也特别笨.先生成图片后在拼接.最后图片还特别大不知道怎么弄,一直成历史遗留问题了.
potplayer你别看确实有一手,但是批量处理视频的时候,碰到那种有那种有问题的视频,就会直接闪退. 而且自己的代码可以捕获那种错误而跳过.从而可以一次性成功把全电脑的视频都转成图片
但是当时还是遇到个问题.,生成大量缩略图后,如何通过缩略图找到视频又成了新问题. 因为你即使看到想要的视频图片, 也不是特别方便定位到这个视频位置.
比如那种qq接收到的缓存视频那种, 文件名啥的都不可控, 而且你搜索也没准有重名的文件
后来就琢磨把视频的路径信息,和名称都写入到图片的那个详细信息里,
然后又写了一个软件,可以读取这些信息,而直接打开图片里对应的视频.
最后效果就是, 随便看到哪个图片, 直接右键就可以打开对应视频.
本来挺欣欣向荣的, 当时真的是超级爽.特别省时间
然后电脑中病毒了. 所有的视频全部被锁. 然后格盘, 最后啥也没有了..
本来之前还想解决我之前那个分辨率的遗留问题,然后也没兴致了...
总之,真是起起伏伏...

免费评分

参与人数 2吾爱币 +2 热心值 +1 收起 理由
Vvvvvoid + 1 程序员不要放弃!
_达圣 + 1 + 1 杠杠的。

查看全部评分

yueyebushou 发表于 2023-7-22 19:23
 楼主| Vvvvvoid 发表于 2023-7-22 19:32
yueyebushou 发表于 2023-7-22 19:23
小知识点,potplayer自带这个功能。。。


我知道 ,包括 QQ视频.. 很多工具都有...

最开始的需求是我要在服务器(linux)上批量跑视频...

头像被屏蔽
xz1234 发表于 2023-7-22 19:33
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽
dongse 发表于 2023-7-22 19:41
提示: 作者被禁止或删除 内容自动屏蔽
Caraciold_Jr 发表于 2023-7-22 19:48
yueyebushou 发表于 2023-7-22 19:23
小知识点,potplayer自带这个功能。。。

大佬potplayer怎么操作
bloodss 发表于 2023-7-22 19:48
这个不错,用起来方便多了
lizhipei78 发表于 2023-7-22 19:50
yueyebushou 发表于 2023-7-22 19:23
小知识点,potplayer自带这个功能。。。

怎么弄的,麻烦发个图看看
maiziv 发表于 2023-7-22 20:01
没想到还有独立的脚本,真不错
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 07:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表