first working version
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func ConvertVideo(path string) {
|
||||
out := path[:len(path)-len(filepath.Ext(path))] + ".mp4"
|
||||
|
||||
cmd := exec.Command("ffmpeg",
|
||||
"-i", "input.mp4",
|
||||
"-c:v", "libx264",
|
||||
"-crf", "23",
|
||||
"-preset", "medium",
|
||||
"-c:a", "aac",
|
||||
"-b:a", "128k",
|
||||
out,
|
||||
)
|
||||
|
||||
cmd.Stderr = cmd.Stdout
|
||||
|
||||
_, err := cmd.CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error converting %s: %v\n", path, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.Remove(path); err != nil {
|
||||
fmt.Printf("Converted %s -> %s, but failed to delete original: %v\n", path, out, err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Converted %s -> %s (original deleted)\n", path, out)
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const touchedFile = ".touched"
|
||||
|
||||
var touched = loadTouched()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
var imageExts = map[string]bool{
|
||||
".jpeg": true,
|
||||
".jpg": true,
|
||||
".png": true,
|
||||
".gif": true,
|
||||
".bmp": true,
|
||||
".tiff": true,
|
||||
".tif": true,
|
||||
".webp": true,
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(path))
|
||||
switch {
|
||||
case ext == ".mov":
|
||||
wg.Go(func() {
|
||||
ConvertVideo(path)
|
||||
})
|
||||
case imageExts[ext]:
|
||||
if touched[path] {
|
||||
fmt.Printf("Skipping %s (already touched)\n", path)
|
||||
return nil
|
||||
}
|
||||
wg.Go(func() { OptimizeImage(path) })
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func loadTouched() map[string]bool {
|
||||
set := map[string]bool{}
|
||||
data, err := os.ReadFile(touchedFile)
|
||||
if err != nil {
|
||||
return set
|
||||
}
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" && !set[line] {
|
||||
set[line] = true
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
func markTouched(path string) {
|
||||
f, err := os.OpenFile(touchedFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Error updating %s: %v\n", touchedFile, err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err := fmt.Fprintln(f, path); err == nil {
|
||||
touched[path] = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func OptimizeImage(path string) {
|
||||
|
||||
fmt.Println("optiimg")
|
||||
cmd := exec.Command("mogrify",
|
||||
"-strip",
|
||||
"-interlace", "Plane",
|
||||
"-sampling-factor", "4:2:0",
|
||||
"-resize", "5000x3000",
|
||||
"-quality", "80%",
|
||||
path,
|
||||
)
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Printf("Error optimizing %s: %v\n%s", path, err, out)
|
||||
} else {
|
||||
markTouched(path)
|
||||
fmt.Printf("Optimized %s\n", path)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user