Created
June 26, 2025 17:47
-
-
Save j0sh/dd5aceccbd89cb1f0b75363ec5ae09fc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"log/slog" | |
"os" | |
"path/filepath" | |
"strings" | |
"time" | |
"github.com/livepeer/lpms/ffmpeg" | |
) | |
func main() { | |
inputs := getInputs() | |
for _, input := range inputs { | |
runTranscode(input) | |
} | |
} | |
func runTranscode(input string) { | |
accel := ffmpeg.Nvidia | |
res, err := ffmpeg.Transcode3(&ffmpeg.TranscodeOptionsIn{ | |
Fname: input, | |
Accel: accel, | |
}, []ffmpeg.TranscodeOptions{{ | |
Oname: "-", | |
Accel: accel, | |
Profile: ffmpeg.P240p30fps16x9, | |
AudioEncoder: ffmpeg.ComponentOptions{Name: "copy"}, | |
Muxer: ffmpeg.ComponentOptions{Name: "null"}, | |
}}) | |
if err != nil { | |
slog.Error("Error transcoding", "input", input, "err", err) | |
} | |
if res.Encoded[0].Frames > res.Decoded.Frames*3 { | |
slog.Warn("Too many frames!", "input", input, "decoded", res.Decoded.Frames, "encoded", res.Encoded[0].Frames) | |
} else { | |
slog.Info("Transcoding OK", "input", input, "decoded", res.Decoded.Frames, "encoded", res.Encoded[0].Frames) | |
} | |
} | |
func getInputs() []string { | |
// Command‐line flags | |
location := flag.String("loc", "", "File or directory to scan for '*tempfile'") | |
startStr := flag.String("start", "", "Start time in RFC3339 format (e.g. 2025-05-21T15:04:05Z)") | |
endStr := flag.String("end", "", "End time in RFC3339 format") | |
flag.Parse() | |
if *location == "" { | |
slog.Error("A -location must be provided") | |
flag.Usage() | |
os.Exit(1) | |
} | |
// Parse start/end times if given | |
var ( | |
startTime time.Time | |
endTime time.Time | |
err error | |
hasStart = false | |
hasEnd = false | |
) | |
if *startStr != "" { | |
startTime, err = time.Parse(time.RFC3339, *startStr) | |
if err != nil { | |
slog.Error("Invalid -start time", "err", err) | |
os.Exit(1) | |
} | |
hasStart = true | |
} | |
if *endStr != "" { | |
endTime, err = time.Parse(time.RFC3339, *endStr) | |
if err != nil { | |
slog.Error("Invalid -end time", "err", err) | |
os.Exit(1) | |
} | |
hasEnd = true | |
} | |
// Collect matching inputs | |
inputs := []string{} | |
info, err := os.Stat(*location) | |
if err != nil || info == nil { | |
slog.Error("Unable to stat location", "location", *location, "err", err) | |
os.Exit(1) | |
} | |
// Helper to decide if a file passes filters | |
matches := func(path string, fi os.FileInfo) bool { | |
if !strings.HasSuffix(fi.Name(), "tempfile") { | |
return false | |
} | |
mtime := fi.ModTime() | |
if hasStart && mtime.Before(startTime) { | |
return false | |
} | |
if hasEnd && mtime.After(endTime) { | |
return false | |
} | |
return true | |
} | |
if info.IsDir() { | |
// Scan directory (non‐recursive) | |
entries, err := os.ReadDir(*location) | |
if err != nil { | |
slog.Error("Failed to read directory", "dir", *location, "err", err) | |
os.Exit(1) | |
} | |
for _, e := range entries { | |
if e.IsDir() { | |
continue | |
} | |
name := e.Name() | |
// must end with "tempfile" | |
if !strings.HasSuffix(name, "tempfile") { | |
continue | |
} | |
// must not begin with "out_" | |
if strings.HasPrefix(name, "out_") { | |
continue | |
} | |
full := filepath.Join(*location, name) | |
fi, err := e.Info() | |
if err != nil { | |
slog.Warn("Skipping file (cannot stat)", "file", full, "err", err) | |
continue | |
} | |
if matches(full, fi) { | |
inputs = append(inputs, full) | |
} | |
} | |
} else { | |
// Single file | |
inputs = append(inputs, *location) | |
} | |
if len(inputs) == 0 { | |
slog.Info("No matching tempfile inputs found") | |
os.Exit(1) | |
} | |
return inputs | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment