package main import ( "fmt" "log" "os" "os/exec" "path" "strings" "time" ) var ( timeLocation *time.Location ) func init() { // 初始化时区 var err error timeLocation, err = time.LoadLocation("Local") if err != nil { log.Fatalf("LoadLocation fail: %v", err) } } func main() { fmt.Println("start processing") pwd, err := os.Open(".") if err != nil { log.Fatalf("os.Open . error: %v", err) } defer pwd.Close() pwdInfo, err := pwd.Stat() if err != nil { log.Fatalf("pwd.Stat error: %v", err) } processDir(pwdInfo, pwd, []string{}) } func processDir(pwdInfo os.FileInfo, pwd *os.File, paths []string) { fmt.Println("processing dir ", pwdInfo.Name()) if !pwdInfo.IsDir() { log.Fatalf("input file %s is not a Dir", pwdInfo.Name()) } if pwd == nil { var err error path := strings.Join(paths, "/") pwd, err = os.Open(path + "/" + pwdInfo.Name()) if err != nil { log.Fatalf("os.Open %v %s error: %v", paths, pwdInfo.Name(), err) } defer pwd.Close() } fileInfos, err := pwd.Readdir(0) if err != nil { log.Fatalf("pwd %s Readdir error: %v", pwd.Name(), err) } ffmpegInstalled, ffmpegPath := checkFfmpegExist() if ffmpegInstalled { log.Println("ffmpeg installed: ", ffmpegPath) } else { log.Println("ffmpeg not installed, skip video files") } for _, fileInfo := range fileInfos { if fileInfo.IsDir() { processDir(fileInfo, nil, append(paths, pwdInfo.Name())) } else { ext := path.Ext(fileInfo.Name()) switch ext { case ".jpg": processJPG(fileInfo, append(paths, pwdInfo.Name())) case ".mp4": if ffmpegInstalled { processMP4(fileInfo, append(paths, pwdInfo.Name())) } } } } } func processJPG(fileInfo os.FileInfo, paths []string) { filename := fileInfo.Name() path := strings.Join(paths, "/") if path != "." { filename = path + "/" + filename } t := fileInfo.ModTime() fmt.Println("processing file ", filename) err := os.Chtimes(filename, t, t) if err != nil { log.Printf("Chtimes file %s fail: %v\n", filename, err) } if filename != fileInfo.Name() { newName := strings.Join(paths[1:], "") + "-" + fileInfo.Name() log.Println("will rename ", filename, " to ", newName) err = os.Rename(filename, newName) if err != nil { log.Printf("Move file %s fail: %v\n", filename, err) } } } func processMP4(fileInfo os.FileInfo, paths []string) { filename := fileInfo.Name() path := strings.Join(paths, "/") if path != "." { filename = path + "/" + filename } t := fileInfo.ModTime() fmt.Println("processing file ", filename, t.Format(time.RFC3339)) if filename != fileInfo.Name() { newName := strings.Join(paths[1:], "") + "-" + fileInfo.Name() log.Println("will move file ", filename, " to ", newName) cmd := exec.Command("ffmpeg", "-i", filename, "-c", "copy", "-metadata", "creation_time=\""+t.Format(time.RFC3339)+"\"", newName) err := cmd.Start() if err != nil { log.Println("set creation_time for file ", filename, " error: ", err) return } } else { log.Println("will replace old file ", filename) tmpFilename := filename + ".tmp.mp4" cmd := exec.Command("ffmpeg", "-i", filename, "-c", "copy", "-metadata", "creation_time="+t.Format(time.RFC3339), tmpFilename) err := cmd.Run() if err != nil { log.Println("set creation_time for file ", filename, " error: ", err) return } err = os.Remove(filename) if err != nil { log.Println("remove old file ", filename, " error") return } err = os.Rename(tmpFilename, filename) if err != nil { log.Println("move file ", tmpFilename, "to ", filename, " error") return } } } func checkFfmpegExist() (exist bool, path string) { path, err := exec.LookPath("ffmpeg") if err != nil { return } return true, path }