66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
package validator
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"coda/internal/config"
|
|
)
|
|
|
|
type Validator struct {
|
|
cfg *config.Service
|
|
}
|
|
|
|
func New(cfg *config.Service) *Validator {
|
|
return &Validator{cfg: cfg}
|
|
}
|
|
|
|
func (v *Validator) Validate(ctx context.Context, mp3Paths []string) error {
|
|
cfg := v.cfg.Get()
|
|
if cfg.DryRun {
|
|
return nil
|
|
}
|
|
|
|
for _, path := range mp3Paths {
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
return fmt.Errorf("validate %s: %w", path, err)
|
|
}
|
|
if info.Size() == 0 {
|
|
return fmt.Errorf("validate %s: file is empty", path)
|
|
}
|
|
|
|
if err := v.probe(ctx, cfg.FFprobeBin, path); err != nil {
|
|
return fmt.Errorf("validate %s: %w", path, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *Validator) probe(ctx context.Context, ffprobeBin, path string) error {
|
|
cmd := exec.CommandContext(ctx, ffprobeBin,
|
|
"-v", "error",
|
|
"-select_streams", "a:0",
|
|
"-show_entries", "stream=codec_name",
|
|
"-of", "csv=p=0",
|
|
path,
|
|
)
|
|
|
|
var stdout bytes.Buffer
|
|
cmd.Stdout = &stdout
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("ffprobe: %w", err)
|
|
}
|
|
|
|
if strings.TrimSpace(stdout.String()) == "" {
|
|
return fmt.Errorf("no audio stream detected")
|
|
}
|
|
|
|
return nil
|
|
}
|