From 81507319dd53edcfeabcf3d43d2d538bdaa77d34 Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:25:05 -0700 Subject: [PATCH] disable by default --- src/asses/one.go | 84 ++++++++++++++++++++++-------------------- src/asses/one_test.go | 2 + src/asses/transcode.go | 64 ++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 39 deletions(-) create mode 100644 src/asses/transcode.go diff --git a/src/asses/one.go b/src/asses/one.go index e94090c..2887ff1 100644 --- a/src/asses/one.go +++ b/src/asses/one.go @@ -11,21 +11,22 @@ import ( "os" "path" "show-rss/src/slow" - "strconv" - "golang.org/x/time/rate" + "strconv" "time" + + "golang.org/x/time/rate" ) var EnvCksumBPS = func() int { - s := os.Getenv("CKSUM_BPS") - if s == "" { - return 50_000_000 - } - n, err := strconv.Atoi(s) - if err != nil || n < 1 { - panic(err) - } - return n + s := os.Getenv("CKSUM_BPS") + if s == "" { + return 50_000_000 + } + n, err := strconv.Atoi(s) + if err != nil || n < 1 { + panic(err) + } + return n }() func One(ctx context.Context, p string) error { @@ -36,17 +37,17 @@ func One(ctx context.Context, p string) error { return err } - threshold := 20 + rand.New(rand.NewSource(func() int64{ - b := md5.New().Sum([]byte(p)) - var sum int64 - for _, c := range b { - sum += int64(c) - sum *= int64(c) - } - return sum - }())).Int()%10 - if daysSince := int(time.Since(last.T).Hours()/24); daysSince > threshold { - log.Printf("asses.One(%s) // no modified check as %vd since last check", shortp, daysSince) + threshold := 20 + rand.New(rand.NewSource(func() int64 { + b := md5.New().Sum([]byte(p)) + var sum int64 + for _, c := range b { + sum += int64(c) + sum *= int64(c) + } + return sum + }())).Int()%10 + if daysSince := int(time.Since(last.T).Hours() / 24); daysSince > threshold { + log.Printf("asses.One(%s) // no modified check as %vd since last check", shortp, daysSince) } else if stat, err := os.Stat(p); err != nil { return fmt.Errorf("cannot stat %s: %w", p, err) } else if stat.ModTime() == last.Modified { @@ -54,16 +55,16 @@ func One(ctx context.Context, p string) error { return nil } else { log.Printf("asses.One(%s) // modified (%v) is now %v", shortp, last.Modified, stat.ModTime()) - } + } - doCksum := true + doCksum := true if err := func() error { if len(last.Cksum) > 0 { - if last.Modified.IsZero() { - doCksum = false + if last.Modified.IsZero() { + doCksum = false log.Printf("asses.One(%s) // assume cksum unchanged given null modified ", shortp) return nil - } + } cksum, err := Cksum(ctx, p) if err != nil { @@ -81,29 +82,34 @@ func One(ctx context.Context, p string) error { return err } + log.Printf("asses.transcode(%s)...", shortp) + if err := transcode(ctx, p); err != nil { + return err + } + return nil }(); err != nil { return err } - var cksum string - if doCksum { - var err error - cksum, err = Cksum(ctx, p) - if err != nil { - return err - } - } + var cksum string + if doCksum { + var err error + cksum, err = Cksum(ctx, p) + if err != nil { + return err + } + } stat, err := os.Stat(p) if err != nil { return err } if err := checked(ctx, p, cksum, stat.ModTime()); err != nil { - log.Printf("failed to mark %s checked: %v", shortp, err) - return err - } + log.Printf("failed to mark %s checked: %v", shortp, err) + return err + } - return nil + return nil } func Cksum(ctx context.Context, p string) (string, error) { diff --git a/src/asses/one_test.go b/src/asses/one_test.go index dc07070..680365f 100644 --- a/src/asses/one_test.go +++ b/src/asses/one_test.go @@ -12,6 +12,8 @@ import ( func TestOne(t *testing.T) { ctx := db.Test(t, context.Background()) + os.Setenv("DO_TRANSCODE", "true") + d := t.TempDir() b, _ := os.ReadFile(path.Join("testdata", "survivor_au_S11E12.smoller.mkv")) p := path.Join(d, "f.mkv") diff --git a/src/asses/transcode.go b/src/asses/transcode.go new file mode 100644 index 0000000..704752b --- /dev/null +++ b/src/asses/transcode.go @@ -0,0 +1,64 @@ +package asses + +import ( + "context" + "fmt" + "log" + "os" + "path" + "slices" + "strings" +) + +func EntrypointTranscode(ctx context.Context, p string) error { + return transcode(ctx, p) +} + +func transcode(ctx context.Context, p string) error { + if os.Getenv("NO_TRANSCODE") != "" || os.Getenv("DO_TRANSCODE") == "" { + log.Printf("would transcode %s but $NO_TRANSCODE=x or $DO_TRANSCODE=", p) + return nil + } + + output, err := ffprobe(ctx, "-i", p) + if err != nil { + return err + } + + h264 := slices.ContainsFunc(strings.Split(output, "\n"), func(line string) bool { + return strings.Contains(line, "tream #") && strings.Contains(line, "Video: ") && strings.Contains(line, "h264") + }) + aac := slices.ContainsFunc(strings.Split(output, "\n"), func(line string) bool { + return strings.Contains(line, "tream #") && strings.Contains(line, "Audio: ") && strings.Contains(line, "aac") + }) + + if h264 && aac { + return nil + } + + p2 := p + ".en" + path.Ext(p) + if err := ffmpeg(ctx, "-y", + "-i", p, + "-vcodec", "libx264", + "-acodec", "aac", + p2, + ); err != nil { + return err + } + + output2, err := ffprobe(ctx, "-i", p) + if err != nil { + return err + } + + df := func(line string) bool { + return !strings.Contains(line, "tream #") + } + originalStreams := slices.DeleteFunc(strings.Split(output, "\n"), df) + newStreams := slices.DeleteFunc(strings.Split(output2, "\n"), df) + if len(originalStreams) != len(newStreams) { + return fmt.Errorf("stream count changed from transcode") + } + + return os.Rename(p2, p) +}