Deduce bit depth, sample rate, and bitrate from file sizes; add comprehensive parser tests

This commit is contained in:
Alexander
2026-05-09 22:09:17 +02:00
parent 7fa859e815
commit 1e8506f146
2 changed files with 542 additions and 68 deletions
+73
View File
@@ -196,6 +196,7 @@ func (p *GenericParser) fillFromTorrent(r *release.Release, torrentData []byte)
}
p.fillFromTitle(r, info.Name)
p.deduceFromFileSize(r)
log.Trace().
Str("hash", r.InfoHash).
@@ -205,6 +206,9 @@ func (p *GenericParser) fillFromTorrent(r *release.Release, torrentData []byte)
Bool("cover", r.HasCoverArt).
Bool("cue", r.HasCueSheet).
Bool("log", r.HasRipLog).
Int("bit_depth", r.BitDepth).
Int("sample_rate", r.SampleRate).
Str("bitrate", r.Bitrate).
Msg("filled from torrent")
}
@@ -267,6 +271,75 @@ func (p *GenericParser) fillFromTitle(r *release.Release, title string) {
Msg("filled from title")
}
func (p *GenericParser) deduceFromFileSize(r *release.Release) {
if r.AudioFileCount == 0 || r.TotalAudioSize == 0 {
return
}
avgFileSize := r.TotalAudioSize / int64(r.AudioFileCount)
avgFileSizeMB := float64(avgFileSize) / (1024 * 1024)
switch {
case r.Format.IsLossless():
if r.BitDepth > 0 && r.SampleRate > 0 {
return
}
// Average FLAC file size per ~4 min track:
// 16/44.1 ≈ 25-35 MB 24/48 ≈ 40-60 MB
// 24/96 ≈ 80-120 MB 24/192 ≈ 160-240 MB
switch {
case avgFileSizeMB >= 130:
p.setIfMissing(r, 24, 192000)
case avgFileSizeMB >= 65:
p.setIfMissing(r, 24, 96000)
case avgFileSizeMB >= 38:
p.setIfMissing(r, 24, 48000)
default:
p.setIfMissing(r, 16, 44100)
}
log.Trace().
Float64("avg_file_mb", avgFileSizeMB).
Int("deduced_bit_depth", r.BitDepth).
Int("deduced_sample_rate", r.SampleRate).
Msg("deduced lossless quality from file size")
case r.Format == release.FormatMP3:
if r.Bitrate != "" {
return
}
// Average MP3 file size per ~4 min track:
// 128 kbps ≈ 3.5-4 MB 192 kbps ≈ 5-6 MB
// 256 kbps ≈ 7-8 MB 320 kbps ≈ 9-10 MB
switch {
case avgFileSizeMB >= 8.5:
r.Bitrate = "320 kbps"
case avgFileSizeMB >= 6.5:
r.Bitrate = "256 kbps"
case avgFileSizeMB >= 4.5:
r.Bitrate = "192 kbps"
default:
r.Bitrate = "128 kbps"
}
log.Trace().
Float64("avg_file_mb", avgFileSizeMB).
Str("deduced_bitrate", r.Bitrate).
Msg("deduced mp3 bitrate from file size")
}
}
func (p *GenericParser) setIfMissing(r *release.Release, bitDepth int, sampleRate int) {
if r.BitDepth == 0 {
r.BitDepth = bitDepth
}
if r.SampleRate == 0 {
r.SampleRate = sampleRate
}
}
var trackNumberPrefix = regexp.MustCompile(`^\d{1,3}[\s.\-]+`)
func cleanTrackName(name string) string {