用 Golang 写一个查找最小视频的命令行小工具
需求描述
我电脑的一个文件夹里有成百上千的文件,我想找一个最小的视频文件(用 ffmpeg 来玩, 先每隔几秒抽帧再把抽的帧合成一个视频)。
需求分析
此文旨在解决前一个需求,即:在一个文件夹中查找一个最小的视频文件。用 Golang 写一个命令行小工具来查找(旨在练手和记录📝)。
后一个需求(ffmpeg 抽帧再合成帧)见稍后的文档。
前提条件
- 可能需要科学上网。
- Golang 环境。
工程实现
1. 创建项目文件夹
打开命令行执行:
mkdir -p minvideo && cd minvideo
2. 初始化项目
go mod init minvideo
3. 创建代码文件
touch main.go
4. 编辑代码文件
需事先安装好
visual studio code
命令行工具。
code .
代码:
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
)
func main() {
// 定义参数
recursive := flag.Bool("r", false, "是否递归扫描子目录")
flag.Parse()
if flag.NArg() < 1 {
fmt.Println("用法: minvideo [-r] <目录路径>")
return
}
root := flag.Arg(0)
videoExts := []string{".mp4", ".mov", ".mkv", ".avi", ".flv", ".wmv"}
var minFile string
var minSize int64 = -1
err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
// 跳过根目录本身
if path == root {
return nil
}
// 如果不是递归模式,遇到目录就跳过
if d.IsDir() && !*recursive {
return filepath.SkipDir
}
// 检查扩展名是否为视频
ext := strings.ToLower(filepath.Ext(d.Name()))
if !contains(videoExts, ext) {
return nil
}
info, err := d.Info()
if err != nil {
return nil
}
size := info.Size()
if minSize == -1 || size < minSize {
minSize = size
minFile = path
}
return nil
})
if err != nil {
fmt.Println("遍历目录时出错:", err)
return
}
if minFile == "" {
fmt.Println("目录中没有找到视频文件")
} else {
fmt.Printf("最小的视频文件: %s (%.2f MB)\n", minFile, float64(minSize)/1024/1024)
}
}
func contains(list []string, target string) bool {
for _, v := range list {
if v == target {
return true
}
}
return false
}
5. 编译
go build -o minvideo main.go
6. 放到 PATH 里
如果你想在任何目录下都能运行,可以把它放到 /usr/local/bin
sudo mv minvideo /usr/local/bin/
7. 清理
cd .. && rm -rf minvideo
使用示例
- 只扫描一层目录
minvideo ~/Downloads/videos
- 递归扫描所有子目录
minvideo -r ~/Downloads/videos