解决群晖DSM7+视频没有缩略图问题
2025-07-05 18:34:00
  1. 安装FFmpeg
    点击套件中心-设置-套件来源-新增 https://spk7.imnks.com/

    然后返回查找FFmpeg、python 并安装。
  2. 将VideoThumbGen.py上传到目标文件下,该文件夹下所有视频都会生成缩略图。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env python3
# Synology Video Thumbnail Generator
# 创建日期: 2025-07-05

import os
import sys
import subprocess
import argparse
from pathlib import Path

# Configuration
FFPROBE_PATH = '/var/packages/ffmpeg/target/bin/ffprobe'
SUPPORTED_FORMATS = {
'.mp4', '.avi', '.wmv', '.mkv', '.flv',
'.mov', '.rmvb', '.amv', '.m1v', '.m2ts',
'.m2v', '.m4v', '.swf', '.ts'
}

def setup_arguments():
"""初始化命令行参数解析器"""
parser = argparse.ArgumentParser(
description='为Synology Photos生成视频缩略图'
)
parser.add_argument(
"-o", "--overwrite",
action="store_true",
help="覆盖已存在的缩略图文件"
)
return parser.parse_args()

def get_video_duration(video_path):
"""使用ffprobe获取视频时长(秒)"""
cmd = [
FFPROBE_PATH,
'-loglevel', 'error',
'-show_entries', 'format=duration',
'-of', 'csv=p=0',
str(video_path)
]
try:
result = subprocess.run(
cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
return float(result.stdout.strip())
except subprocess.CalledProcessError as e:
print(f"[错误] 无法获取视频时长 {video_path}: {e.stderr}")
return None

def generate_thumbnail(video_path, output_path, duration):
"""在视频中点生成缩略图"""
midpoint = duration / 2
cmd = [
'ffmpeg',
'-loglevel', 'warning',
'-ss', str(midpoint),
'-i', str(video_path),
'-y',
'-vframes', '1',
'-vf', 'scale=-1:480',
str(output_path)
]
try:
subprocess.run(cmd, check=True)
return True
except subprocess.CalledProcessError as e:
print(f"[错误] 生成缩略图失败: {e.stderr}")
return False

def process_video_file(video_path, args):
"""处理单个视频文件生成缩略图"""
video_dir = video_path.parent
thumb_dir = video_dir / '@eaDir' / video_path.name

try:
# 清理之前失败的生成记录
for fail_file in thumb_dir.glob('*.fail'):
fail_file.unlink()

# 创建缩略图目录(如果不存在)
thumb_dir.mkdir(parents=True, exist_ok=True)

# 定义输出文件路径
thumb_m = thumb_dir / 'SYNOPHOTO_THUMB_M.jpg'
thumb_xl = thumb_dir / 'SYNOVIDEO_VIDEO_SCREENSHOT.jpg'

# 获取视频时长
duration = get_video_duration(video_path)
if duration is None:
return False

# 生成中等缩略图(如果需要)
if args.overwrite or not thumb_m.exists():
print(f'正在生成中等缩略图: {thumb_m}')
if not generate_thumbnail(video_path, thumb_m, duration):
return False

# 生成大尺寸缩略图(如果需要)
if args.overwrite or not thumb_xl.exists():
print(f'正在生成大尺寸缩略图: {thumb_xl}')
if not generate_thumbnail(video_path, thumb_xl, duration):
return False

return True

except Exception as e:
print(f"[错误] 处理 {video_path} 时出错: {str(e)}")
return False
finally:
# 如果生成失败且目录为空,则清理目录
if thumb_dir.exists() and not any(thumb_dir.iterdir()):
thumb_dir.rmdir()

def generate_all_thumbnails(args):
"""主函数:遍历目录生成所有缩略图"""
base_path = Path(__file__).parent.resolve()
processed_count = 0
success_count = 0

for item in base_path.rglob('*'):
if item.is_file() and item.suffix.lower() in SUPPORTED_FORMATS:
processed_count += 1
print(f"\n正在处理 [{processed_count}] {item}")
success = process_video_file(item, args)
if success:
success_count += 1
print(f"[成功] 已处理: {item}")
else:
print(f"[失败] 处理失败: {item}")

print(f"\n处理完成。总计: {processed_count} 个文件, 成功: {success_count} 个, 失败: {processed_count-success_count} 个")

if __name__ == '__main__':
print("=== Synology 视频缩略图生成工具 ===")
args = setup_arguments()
generate_all_thumbnails(args)
  1. 设置定时任务
    控制面板-任务计划-新增-计划的任务
    添加脚本位置
上一页
2025-07-05 10:58:56