You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

视频缩略图缓存的合规短文件名编码方案咨询

视频缩略图缓存的合规短文件名编码方案咨询

我正在给lf写一个预览脚本,用chafa以sixel格式展示图片预览。目前处理视频预览时,我打算直接提取视频的第一帧作为预览图,核心逻辑是把生成的缩略图缓存到指定文件夹,避免每次都调用ffmpeg(毕竟ffmpeg处理视频还是挺慢的)。

我原本的做法是用base64编码视频文件名作为缓存PNG的文件名,代码大概是这样的:

# check if cache folder exists
if [ ! -d "$cache_folder" ]; then
    mkdir "$cache_folder"
fi

# going to store thumbnail here:
# not using mktemp as chafa expects a file extension
thumbnail_file="$cache_folder/$(echo "$1" | base64).png"

# if the thumbnail isn't cached then make it:
if [ ! -f "$thumbnail_file" ]; then
    # get first frame of video:
    # the below makes the pixels square in case we have non-square pixels
    # which means the image won't look stretched/squished after displaying
    # add -y to overwrite thumbnail file if exists
    ffmpeg -i "$1" -vf "scale=iw*sar:ih,setsar=1" -vframes 1 -y "$thumbnail_file" &>/dev/null
fi

chafa -f sixel -s "$2x$3" --animate off --polite on "$thumbnail_file"

但遇到一些长文件名的视频时,会触发chafa: Failed to open [thumbnail file]: File name too long的错误,这显然是base64编码后的字符串太长导致的。现在我需要一种更合适的缓存文件名生成方式,满足这几个要求:

  • 唯一性:不同视频文件不会生成相同的缓存文件名,避免预览图串用
  • 足够短:不会触发文件名过长的错误(暂时没查到chafa的具体限制,但至少要符合系统的文件名长度规范)
  • 合法合规:文件名里不能包含/这类非法字符

推荐解决方案:用哈希算法替代Base64

Base64的问题在于,原文件名越长,编码后的字符串就越长,很容易超出长度限制。而哈希算法(比如MD5、SHA-256)可以把任意长度的输入转换成固定长度的字符串,完美解决这个问题,同时还能保证极低的碰撞概率(对于个人使用场景,几乎不可能出现不同文件生成相同哈希的情况)。

具体修改只需要替换生成缓存文件名的那一行:

方案1:用SHA-256哈希(64位字符,安全性更高)

thumbnail_file="$cache_folder/$(sha256sum "$1" | cut -d' ' -f1).png"

方案2:用MD5哈希(32位字符,更短)

thumbnail_file="$cache_folder/$(md5sum "$1" | cut -d' ' -f1).png"

方案3:短哈希(进一步缩短长度,个人使用足够安全)

如果觉得32位还是有点长,可以取哈希值的前16位,碰撞概率依然极低:

thumbnail_file="$cache_folder/$(sha256sum "$1" | cut -d' ' -f1 | head -c 16).png"

为什么哈希更合适?

  1. 长度固定:不管原文件名多长,哈希后的字符串长度都是固定的(MD5是32位,SHA-256是64位),完全不会触发文件名过长的问题
  2. 唯一性保障:哈希算法的碰撞概率极低,对于个人日常使用的视频文件来说,几乎不可能出现两个不同文件生成相同哈希的情况
  3. 合法文件名:哈希结果只包含0-9和a-f的字符,没有任何非法字符,符合所有系统的文件名规范

另外,因为你已经假设视频内容不会变化,用文件内容的哈希来生成缓存名是完全合理的——如果后续需要更新缩略图,直接删除缓存文件夹里的对应文件即可。

备注:内容来源于stack exchange,提问作者revsuine

火山引擎 最新活动