Fix audio thumbnailing once and for all.
authorBen Sturmfels <ben@sturm.com.au>
Wed, 1 Apr 2020 05:52:05 +0000 (16:52 +1100)
committerBen Sturmfels <ben@sturm.com.au>
Wed, 1 Apr 2020 05:52:05 +0000 (16:52 +1100)
This change adds a Python 3-specific audio thumbnailer that side-steps the
bundled Python 2-only `audioprocessing` module. Instead of an audio spectrogram,
Python 3 users will get a static image.

This also allows me to remove my ineffective customisations to
`audioprocessing`, returning it to the upstream version as should always be the
case for vendored code in "extlib".

extlib/freesound/audioprocessing.py
mediagoblin/media_types/audio/transcoders.py

index b9a96a970e3e0596c1ccb670e6504100c721d39a..b002ff8aa4123ec68b9d3af334bc425d4a800f25 100644 (file)
@@ -43,32 +43,7 @@ def get_sound_type(input_filename):
 try:
     import scikits.audiolab as audiolab
 except ImportError:
-    print("WARNING: audiolab is not installed so wav2png will not work")
-
-    # Hack to prevent errors when uploading audio files. The issue is that
-    # scikits.audiolab does not support Python 3. By replacing it with a mock
-    # implementation here, we can accept audio files, but we won't get the nice
-    # waveform image.
-    import six
-    if six.PY3:
-        class MockSndfile(object):
-            def __init__(self, *args, **kwargs):
-                self.nframes = 0
-                self.channels = 1
-                self.samplerate = 44100
-
-            def read_frames(self, *args):
-                return []
-
-            def seek(self, *args):
-                return
-
-            def close(self):
-                return
-        import unittest.mock as mock
-        audiolab = mock.Mock()
-        audiolab.Sndfile = MockSndfile
-
+    print "WARNING: audiolab is not installed so wav2png will not work"
 import subprocess
 
 class AudioProcessingException(Exception):
index f86528dee3d6f6e72a532eac0547d83026299218..f78cbf288a941af376f9e925a7c8f19b8f4bf7b7 100644 (file)
@@ -20,8 +20,6 @@ try:
 except ImportError:
     import Image
 
-from mediagoblin.media_types.audio import audioprocessing
-
 _log = logging.getLogger(__name__)
 
 CPU_COUNT = 2  # Just assuming for now
@@ -46,13 +44,17 @@ from gi.repository import GObject, Gst
 Gst.init(None)
 
 import numpy
+import six
 
 
-class AudioThumbnailer(object):
+class Python2AudioThumbnailer(object):
     def __init__(self):
         _log.info('Initializing {0}'.format(self.__class__.__name__))
 
     def spectrogram(self, src, dst, **kw):
+        # This third-party bundled module is Python 2-only.
+        from mediagoblin.media_types.audio import audioprocessing
+
         width = kw['width']
         height = int(kw.get('height', float(width) * 0.3))
         fft_size = kw.get('fft_size', 2048)
@@ -111,6 +113,25 @@ class AudioThumbnailer(object):
         th.save(dst)
 
 
+class Python3AudioThumbnailer(Python2AudioThumbnailer):
+    """Dummy thumbnailer for Python 3.
+
+    The Python package used for audio spectrograms, "scikits.audiolab", does not
+    support Python 3 and is a constant source of problems for people installing
+    MediaGoblin. Until the feature is rewritten, this thumbnailer class simply
+    provides a generic image.
+
+    """
+    def spectrogram(self, src, dst, **kw):
+        # Using PIL here in case someone wants to swap out the image for a PNG.
+        # This will convert to JPEG, where simply copying the file won't.
+        img = Image.open('mediagoblin/static/images/media_thumbs/video.jpg')
+        img.save(dst)
+
+
+AudioThumbnailer = Python3AudioThumbnailer if six.PY3 else Python2AudioThumbnailer
+
+
 class AudioTranscoder(object):
     def __init__(self):
         _log.info('Initializing {0}'.format(self.__class__.__name__))