修复跳屏问题
This commit is contained in:
@@ -146,7 +146,7 @@ func MovieList(c *gin.Context) {
|
||||
sortBy := c.Query("sort")
|
||||
order := c.Query("order")
|
||||
if sortBy == "" {
|
||||
sortBy = "created_time" // 默认按创建时间排序
|
||||
sortBy = "duration" // 默认按创建时间排序
|
||||
}
|
||||
|
||||
// 应用排序
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Movie 电影信息结构
|
||||
@@ -74,7 +75,7 @@ var Movies []*Movie // 存储所有电影信息的全局切
|
||||
var MovieDict = make(map[string]*Movie) // 存储需要处理缩略图的视频字典
|
||||
var MovieDictLock sync.Mutex // 保护MovieDict的并发访问
|
||||
|
||||
var IsRemakePNG = false // 是否重新生成所有PNG缩略图
|
||||
var IsRemakePNG = true // 是否重新生成所有PNG缩略图
|
||||
var Categories = []string{ // 分类
|
||||
"15min", "30min", "60min", "大于60min", "最新添加"}
|
||||
|
||||
@@ -223,38 +224,55 @@ func generateThumbnail(movie *Movie) {
|
||||
baseName := strings.TrimSuffix(movie.FileName, filepath.Ext(movie.FileName))
|
||||
outputPath := filepath.Join("movie", baseName+".png")
|
||||
|
||||
// 根据时长选择不同的采样策略
|
||||
var filter string
|
||||
switch {
|
||||
case movie.Duration <= 2:
|
||||
filter = "select='isnan(prev_selected_t)+gte(t-prev_selected_t\\,5)',scale=320:180,tile=3x3"
|
||||
case movie.Duration <= 5:
|
||||
filter = "select='isnan(prev_selected_t)+gte(t-prev_selected_t\\,10)',scale=320:180,tile=3x3"
|
||||
case movie.Duration <= 30:
|
||||
filter = "select='isnan(prev_selected_t)+gte(t-prev_selected_t\\,20)',scale=320:180,tile=3x3"
|
||||
case movie.Duration <= 60:
|
||||
filter = "select='isnan(prev_selected_t)+gte(t-prev_selected_t\\,35)',scale=320:180,tile=3x3"
|
||||
default:
|
||||
filter = "select='isnan(prev_selected_t)+gte(t-prev_selected_t\\,60)',scale=320:180,tile=3x3"
|
||||
}
|
||||
// --- Start of improved logic ---
|
||||
|
||||
// 执行ffmpeg命令生成缩略图
|
||||
// Fixed skip for the beginning of the video, as per original code's ffmpeg args
|
||||
const skipStartSeconds = 10.0
|
||||
// Number of frames we want in the tile (for a 3x3 grid)
|
||||
const numFramesInTile = 9.0 // Use float for calculations
|
||||
|
||||
durationAfterSkip := float64(movie.Duration) - skipStartSeconds
|
||||
|
||||
var intervalSeconds float64
|
||||
|
||||
if durationAfterSkip <= 0.1 { // Use a small threshold like 0.1s
|
||||
intervalSeconds = 0.05 // A very small interval to grab whatever is there.
|
||||
} else {
|
||||
if numFramesInTile > 1 {
|
||||
intervalSeconds = durationAfterSkip / (numFramesInTile - 1.0)
|
||||
} else {
|
||||
intervalSeconds = durationAfterSkip
|
||||
}
|
||||
if intervalSeconds <= 0 {
|
||||
intervalSeconds = 0.05 // Fallback to a tiny interval
|
||||
}
|
||||
}
|
||||
filter := fmt.Sprintf("select='isnan(prev_selected_t)+gte(t-prev_selected_t\\,%.3f)',scale=320:180,tile=3x3", intervalSeconds)
|
||||
|
||||
log.Printf("Movie: %s, OriginalDuration: %ds, SkipStart: %.1fs, DurationForSampling: %.2fs, CalculatedInterval: %.3fs",
|
||||
movie.FileName, movie.Duration, skipStartSeconds, durationAfterSkip, intervalSeconds)
|
||||
|
||||
// Execute ffmpeg command
|
||||
cmd := exec.Command("ffmpeg",
|
||||
"-ss", fmt.Sprintf("%.0f", skipStartSeconds), // Using the defined skipStartSeconds
|
||||
"-i", movie.VideoPath,
|
||||
"-vf", filter,
|
||||
"-frames:v", "1",
|
||||
"-q:v", "3",
|
||||
"-y", // 覆盖已存在文件
|
||||
"-frames:v", "1", // Crucial for outputting a single tiled image
|
||||
"-q:v", "3", // Quality for the frames before tiling/PNG compression
|
||||
"-y", // Overwrite output file if it exists
|
||||
outputPath,
|
||||
)
|
||||
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
startTime := time.Now()
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("生成缩略图失败: %s (%d min): %v\n错误输出: %s",
|
||||
// Assuming movie.Duration is in seconds, adjusted log from (%d min) to (%d s)
|
||||
log.Printf("生成缩略图失败: %s (%d s): %v\n错误输出: %s",
|
||||
movie.VideoPath, movie.Duration, err, stderr.String())
|
||||
} else {
|
||||
log.Printf("成功生成缩略图: %s", outputPath)
|
||||
log.Printf("成功生成缩略图: %s (耗时: %v)", outputPath, time.Since(startTime))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user