Skip to content

Instantly share code, notes, and snippets.

@j0sh
Created June 26, 2025 17:47
Show Gist options
  • Save j0sh/dd5aceccbd89cb1f0b75363ec5ae09fc to your computer and use it in GitHub Desktop.
Save j0sh/dd5aceccbd89cb1f0b75363ec5ae09fc to your computer and use it in GitHub Desktop.
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