mkogg.py: Update to Python 3
authorW. Trevor King <wking@tremily.us>
Mon, 13 Jul 2015 16:46:00 +0000 (09:46 -0700)
committerW. Trevor King <wking@tremily.us>
Mon, 13 Jul 2015 16:46:00 +0000 (09:46 -0700)
Five years after the initial request [1], the Mutagen folks have added
Python 3 support (in v1.25, 2014-10-03 [2]).  In this commit, I also
catch up on the m4a -> mp4 transition (from v1.9, 2006-12-09 [3]).

[1]: https://bitbucket.org/lazka/mutagen/issues/27
[2]: http://mutagen.readthedocs.org/en/latest/changelog.html#id6
[3]: http://mutagen.readthedocs.org/en/latest/changelog.html#id23

posts/mkogg/mkogg.py

index 7ab66cfeaa9f4ae8922b5da5d16e6d597140108d..07ef572f522aed5381816927ef558c77b7ec62c9 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2009-2012 W. Trevor King <wking@drexel.edu>
+# Copyright (C) 2009-2015 W. Trevor King <wking@drexel.edu>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as
@@ -21,7 +21,7 @@
 Conversion between any of the following formats are supported:
 
 * flac
-* m4a (decoding only)
+* mp4 (decoding only)
 * mp3
 * ogg (Vorbis)
 * wav
@@ -54,14 +54,15 @@ try:
     import mutagen as _mutagen
     import mutagen.flac as _mutagen_flac
     import mutagen.id3 as _mutagen_id3
-    import mutagen.m4a as _mutagen_m4a
+    import mutagen.mp4 as _mutagen_mp4
     import mutagen.mp3 as _mutagen_mp3
     import mutagen.oggvorbis as _mutagen_oggvorbis
-except ImportError as _mutagen_import_error:
+except ImportError as error:
     _mutagen = None
+    _mutagen_import_error = error
 
 
-__version__ = '0.4'
+__version__ = '0.5'
 
 
 def invoke(args, stdin=None, expect=(0,)):
@@ -106,7 +107,7 @@ class Converter (object):
         'tyer': 'date',
         }
 
-    m4a_to_vorbis_keys = {
+    mp4_to_vorbis_keys = {
         '\xa9cmt': 'comment',
         '\xa9alb': 'album',
         #'tcom': 'composer',
@@ -125,7 +126,7 @@ class Converter (object):
                  cache_file=None, hash=True, ignore_function=None):
         self.source_dir = source_dir
         self.target_dir = target_dir
-        self._source_extensions = ['flac', 'm4a', 'mp3', 'ogg', 'wav']
+        self._source_extensions = ['flac', 'm4a', 'mp3', 'mp4', 'ogg', 'wav']
         self._target_extension = target_extension
         self._cache_file = cache_file
         self._cache = self._read_cache()
@@ -165,7 +166,7 @@ class Converter (object):
             return
         with open(self._cache_file, 'w') as f:
             f.write('# mkogg cache version: {}\n'.format(__version__))
-            for key,value in self._cache.iteritems():
+            for key,value in self._cache.items():
                 f.write('{} -> {}\n'.format(key, value))
 
     def run(self):
@@ -331,6 +332,9 @@ class Converter (object):
     def convert_mp3_to_wav(self, source, target):
         invoke(['mpg123',  '-w', target, source])
 
+    def convert_mp4_to_wav(self, source, target):
+        invoke(['faad', '-o', target, source])
+
     def convert_ogg_to_wav(self, source, target):
         self.convert_flac_to_wav(source, target)
 
@@ -349,27 +353,7 @@ class Converter (object):
         return _mutagen_flac.FLAC(source)
 
     def get_m4a_metadata(self, source):
-        if _mutagen is None:
-            raise _mutagen_import_error
-        m4a = _mutagen_m4a.M4A(source)
-        metadata = {}
-        for key,value in m4a.items():
-            try:
-                vorbis_key = self.m4a_to_vorbis_keys[key.lower()]
-            except KeyError:
-                continue
-            if vorbis_key == 'tracknumber':
-                tracknumber,tracktotal = value
-                value = tracknumber
-                if tracktotal:
-                    metadata['tracktotal'] = [str(tracktotal)]
-            elif vorbis_key == 'part of set':
-                disknumber,disktotal = value
-                value = disknumber
-                if disktotal:
-                    metadata['set total'] = [str(disktotal)]
-            metadata[vorbis_key] = [str(value)]
-        return metadata
+        return self.get_mp4_metadata(self, source)
 
     def get_mp3_metadata(self, source):
         if _mutagen is None:
@@ -391,6 +375,32 @@ class Converter (object):
             metadata[vorbis_key] = v
         return metadata
 
+    def get_mp4_metadata(self, source):
+        if _mutagen is None:
+            raise _mutagen_import_error
+        mp4 = _mutagen_mp4.MP4(source)
+        metadata = {}
+        for key,value in mp4.items():
+            try:
+                vorbis_key = self.mp4_to_vorbis_keys[key.lower()]
+            except KeyError:
+                continue
+            if vorbis_key == 'tracknumber':
+                tracknumber,tracktotal = value
+                value = tracknumber
+                if tracktotal:
+                    metadata['tracktotal'] = [str(tracktotal)]
+            elif vorbis_key == 'part of set':
+                disknumber,disktotal = value
+                value = disknumber
+                if disktotal:
+                    metadata['set total'] = [str(disktotal)]
+            try:
+                metadata[vorbis_key] = [str(value)]
+            except UnicodeEncodeError:
+                metadata[vorbis_key] = [value]
+        return metadata
+
     def get_ogg_metadata(self, source):
         if _mutagen is None:
             raise _mutagen_import_error