fix(audio): cap ffprobe/ffmpeg streams at 32 and narrow the probe output (#49)
A 900-stream file cost ~570 MB RSS in each tool; with the cap the same file fails in ~18 MB and is reported as unreadable. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,9 +30,22 @@ type FFprobe struct {
|
||||
// formats. "mov" covers .mp4/.m4a/.3gp; "matroska" covers .webm.
|
||||
const AllowedDemuxers = "wav,mov,mp4,m4a,3gp,mp3,ogg,matroska,webm,flac,aac,opus,aiff,amr,asf"
|
||||
|
||||
// MaxStreams bounds how many streams a file may declare. A 1.3 MB file declaring 900 of
|
||||
// them cost ~570 MB of RSS in each of ffprobe and ffmpeg (#49), against a 512 Mi pod;
|
||||
// real recordings have a handful.
|
||||
const MaxStreams = "32"
|
||||
|
||||
// inputRestrictions are ffmpeg/ffprobe INPUT options and must precede the input.
|
||||
// Local files and pipes only: no network, no other protocols.
|
||||
var inputRestrictions = []string{"-protocol_whitelist", "file,pipe", "-format_whitelist", AllowedDemuxers}
|
||||
// Local files and pipes only: no network, no other protocols, and a bounded stream count.
|
||||
var inputRestrictions = []string{
|
||||
"-protocol_whitelist", "file,pipe",
|
||||
"-format_whitelist", AllowedDemuxers,
|
||||
"-max_streams", MaxStreams,
|
||||
}
|
||||
|
||||
// probeEntries is exactly what ParseProbe reads. -show_format/-show_streams print every
|
||||
// tag too, and a 120 MB WAV made 491 MB of JSON that Output() buffers.
|
||||
const probeEntries = "format=duration:stream=codec_type:stream_disposition=attached_pic"
|
||||
|
||||
// killGrace bounds how long Probe waits for a cancelled ffprobe's pipes to close.
|
||||
const killGrace = 2 * time.Second
|
||||
@@ -48,7 +61,7 @@ func (f *FFprobe) Probe(ctx context.Context, path string) (uploads.Probe, error)
|
||||
bin = "ffprobe"
|
||||
}
|
||||
args := append([]string{"-v", "error"}, inputRestrictions...)
|
||||
args = append(args, "-print_format", "json", "-show_format", "-show_streams", path)
|
||||
args = append(args, "-print_format", "json", "-show_entries", probeEntries, path)
|
||||
cmd := exec.CommandContext(ctx, bin, args...)
|
||||
cmd.WaitDelay = killGrace
|
||||
out, err := cmd.Output()
|
||||
|
||||
Reference in New Issue
Block a user