Added never_convert_lossy_files option to convert plugin

When set to true, this config option chooses copying over converting when the
source file is in a lossy format. At the moment, everything except ape, flac,
alac and wav is considered lossy.
This commit is contained in:
Simon Kohlmeyer 2014-09-13 19:07:25 +02:00
parent 7328a09644
commit 9d55179d2d
3 changed files with 47 additions and 0 deletions

View file

@ -37,6 +37,8 @@ ALIASES = {
u'vorbis': u'ogg',
}
LOSSLESS_FORMATS = ['ape', 'flac', 'alac', 'wav']
def replace_ext(path, ext):
"""Return the path with its extension replaced by `ext`.
@ -128,6 +130,8 @@ def should_transcode(item, format):
"""Determine whether the item should be transcoded as part of
conversion (i.e., its bitrate is high or it has the wrong format).
"""
if config['convert']['never_convert_lossy_files'] and not (item.format.lower() in LOSSLESS_FORMATS):
return False
maxbr = config['convert']['max_bitrate'].get(int)
return format.lower() != item.format.lower() or \
item.bitrate >= 1000 * maxbr
@ -308,6 +312,7 @@ class ConvertPlugin(BeetsPlugin):
u'quiet': False,
u'embed': True,
u'paths': {},
u'never_convert_lossy_files': False,
})
self.import_stages = [self.auto_convert]

View file

@ -67,6 +67,10 @@ The plugin offers several configuration options, all of which live under the
adding them to your library.
* ``quiet`` mode prevents the plugin from announcing every file it processes.
Default: false.
* ``never_convert_lossy_files`` means that lossy codecs, such as mp3, ogg vorbis,
etc, are never converted, as converting lossy files to other lossy codecs will
decrease quality further. If set to true, lossy files are always copied.
Default: false
* ``paths`` lets you specify the directory structure and naming scheme for the
converted files. Use the same format as the top-level ``paths`` section (see
:ref:`path-format-config`). By default, the plugin reuses your top-level

View file

@ -124,6 +124,44 @@ class ConvertCliTest(unittest.TestCase, TestHelper):
mediafile = MediaFile(converted)
self.assertEqual(mediafile.images[0].data, image_data)
class NeverConvertLossyFilesTest(unittest.TestCase, TestHelper):
def setUp(self):
self.setup_beets(disk=True) # Converter is threaded
self.album_ogg = self.add_album_fixture(ext='ogg')
self.album_flac = self.add_album_fixture(ext='flac')
self.load_plugins('convert')
self.convert_dest = os.path.join(self.temp_dir, 'convert_dest')
self.config['convert'] = {
'dest': self.convert_dest,
'paths': {'default': 'converted'},
'never_convert_lossy_files': False,
'format': 'mp3',
'formats': {
'mp3': 'cp $source $dest',
'opus': {
'command': 'cp $source $dest',
'extension': 'ops',
}
}
}
def tearDown(self):
self.unload_plugins()
self.teardown_beets()
def test_convert_flac_to_mp3_works(self):
with control_stdin('y'):
self.run_command('convert', self.album_flac.items()[0].path)
converted = os.path.join(self.convert_dest, 'converted.mp3')
self.assertTrue(os.path.isfile(converted))
def test_convert_ogg_to_mp3_prevented(self):
with control_stdin('y'):
self.run_command('convert', self.album_ogg.items()[0].path)
converted = os.path.join(self.convert_dest, 'converted.mp3')
self.assertTrue(os.path.isfile(converted))
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)