diff --git a/NEWS b/NEWS index 6052555ee..74069fbd9 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,9 @@ more fairly by the autotagger. For example, if you're missing the acute accent on the "e" in "cafe", that change won't be penalized. This introduces a new dependency on the "unidecode" Python module. +* The bitrate of lossless files is now calculated from their file size + (rather than being fixed at 0 or reflecting the uncompressed audio + bitrate). * Fixed a problem where duplicate albums or items imported at the same time would fail to be detected. * BPD now uses a persistent "virtual filesystem" in order to fake a diff --git a/beets/mediafile.py b/beets/mediafile.py index 636108a4b..c11ad4abd 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -28,7 +28,6 @@ A field will always return a reasonable value of the correct type, even if no tag is present. If no value is available, the value will be false (e.g., zero or the empty string). """ - import mutagen import mutagen.mp3 import mutagen.oggvorbis @@ -39,6 +38,7 @@ import datetime import re import base64 import imghdr +import os from beets.util.enumeration import enum __all__ = ['UnreadableFileError', 'FileTypeError', 'MediaFile'] @@ -607,6 +607,8 @@ class MediaFile(object): """Constructs a new MediaFile reflecting the file at path. May throw UnreadableFileError. """ + self.path = path + unreadable_exc = ( mutagen.mp3.HeaderNotFoundError, mutagen.flac.FLACNoHeaderError, @@ -843,20 +845,14 @@ class MediaFile(object): @property def bitrate(self): - if self.type in ('flac', 'ape'): - if hasattr(self.mgfile.info, 'bits_per_sample'): - # Simulate bitrate for lossless formats. - #fixme: The utility of this guess is questionable. - return self.mgfile.info.sample_rate * \ - self.mgfile.info.bits_per_sample - else: - # Old APE file format. - return 0 - elif self.type == 'wv': - # Mutagen doesn't provide enough information. - return 0 - else: + if hasattr(self.mgfile.info, 'bitrate'): + # Many formats provide it explicitly. return self.mgfile.info.bitrate + else: + # Otherwise, we calculate bitrate from the file size. (This + # is the case for all of the lossless formats.) + size = os.path.getsize(self.path) + return int(size * 8 / self.length) @property def format(self): diff --git a/test/test_mediafile_basic.py b/test/test_mediafile_basic.py index 1f0a6623f..8dfe08667 100644 --- a/test/test_mediafile_basic.py +++ b/test/test_mediafile_basic.py @@ -219,7 +219,7 @@ read_only_correct_dicts = { 'full.flac': { 'length': 1.0, - 'bitrate': 705600, + 'bitrate': 175120, 'format': 'FLAC', }, @@ -237,13 +237,13 @@ read_only_correct_dicts = { 'full.ape': { 'length': 1.0, - 'bitrate': 705600, + 'bitrate': 111640, 'format': 'APE', }, 'full.wv': { 'length': 1.0, - 'bitrate': 0, + 'bitrate': 108344, 'format': 'WavPack', },