diff options
author | Rodney Ewing <ewing.rj@gmail.com> | 2013-08-13 09:57:35 -0700 |
---|---|---|
committer | Rodney Ewing <ewing.rj@gmail.com> | 2013-08-16 15:30:18 -0700 |
commit | 5ac1fe806483de28656a056f10314ecc6a10aed4 (patch) | |
tree | 187faa1ecc254ba2038a0651d269abdeb9e1db5a | |
parent | 36c17b85c12546076067e039e5f55c7780dc54f3 (diff) | |
download | mediagoblin-5ac1fe806483de28656a056f10314ecc6a10aed4.tar.lz mediagoblin-5ac1fe806483de28656a056f10314ecc6a10aed4.tar.xz mediagoblin-5ac1fe806483de28656a056f10314ecc6a10aed4.zip |
Audio Initial Processor
-rw-r--r-- | mediagoblin/gmg_commands/reprocess.py | 3 | ||||
-rw-r--r-- | mediagoblin/media_types/audio/__init__.py | 5 | ||||
-rw-r--r-- | mediagoblin/media_types/audio/processing.py | 201 |
3 files changed, 202 insertions, 7 deletions
diff --git a/mediagoblin/gmg_commands/reprocess.py b/mediagoblin/gmg_commands/reprocess.py index 5285942e..375d9ff2 100644 --- a/mediagoblin/gmg_commands/reprocess.py +++ b/mediagoblin/gmg_commands/reprocess.py @@ -245,7 +245,8 @@ def thumbs(args): # prepare filetype and size to be passed into reprocess_parser if args.size: - extra_args = 'thumb --size {0} {1}'.format(args.size[0], args.size[1]) + extra_args = 'thumb --size {0} {1}'.format(args.size[0], + args.size[1]) else: extra_args = 'thumb' diff --git a/mediagoblin/media_types/audio/__init__.py b/mediagoblin/media_types/audio/__init__.py index c7ed8d2d..6ad473c8 100644 --- a/mediagoblin/media_types/audio/__init__.py +++ b/mediagoblin/media_types/audio/__init__.py @@ -15,7 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from mediagoblin.media_types import MediaManagerBase -from mediagoblin.media_types.audio.processing import process_audio, \ +from mediagoblin.media_types.audio.processing import AudioProcessingManager, \ sniff_handler from mediagoblin.tools import pluginapi @@ -32,8 +32,8 @@ def setup_plugin(): class AudioMediaManager(MediaManagerBase): human_readable = "Audio" - processor = staticmethod(process_audio) display_template = "mediagoblin/media_displays/audio.html" + default_thumb = "images/media_thumbs/image.png" def get_media_type_and_manager(ext): @@ -45,4 +45,5 @@ hooks = { 'get_media_type_and_manager': get_media_type_and_manager, 'sniff_handler': sniff_handler, ('media_manager', MEDIA_TYPE): lambda: AudioMediaManager, + ('reprocess_manager', MEDIA_TYPE): lambda: AudioProcessingManager, } diff --git a/mediagoblin/media_types/audio/processing.py b/mediagoblin/media_types/audio/processing.py index 22383bc1..3299c72d 100644 --- a/mediagoblin/media_types/audio/processing.py +++ b/mediagoblin/media_types/audio/processing.py @@ -14,16 +14,20 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import argparse import logging from tempfile import NamedTemporaryFile import os from mediagoblin import mg_globals as mgg -from mediagoblin.processing import (create_pub_filepath, BadMediaFail, - FilenameBuilder, ProgressCallback) +from mediagoblin.processing import ( + create_pub_filepath, BadMediaFail, FilenameBuilder, + ProgressCallback, MediaProcessor, ProcessingManager, + request_from_args, get_orig_filename, + store_public, copy_original) -from mediagoblin.media_types.audio.transcoders import (AudioTranscoder, - AudioThumbnailer) +from mediagoblin.media_types.audio.transcoders import ( + AudioTranscoder,AudioThumbnailer) _log = logging.getLogger(__name__) @@ -157,3 +161,192 @@ def process_audio(proc_state): mgg.queue_store.delete_file(queued_filepath) # rm file mgg.queue_store.delete_dir(queued_filepath[:-1]) # rm dir entry.queued_media_file = [] + + +class CommonAudioProcessor(MediaProcessor): + """ + Provides a base for various audio processing steps + """ + + def common_setup(self): + """ + """ + self.audio_config = mgg \ + .global_config['media_type:mediagoblin.media_types.audio'] + + # Pull down and set up the original file + self.orig_filename = get_orig_filename( + self.entry, self.workbench) + self.name_builder = FilenameBuilder(self.orig_filename) + + self.spectrogram_tmp = os.path.join(self.workbench.dir, + self.name_builder.fill( + '{basename}-spectrogram.jpg')) + + self.transcoder = AudioTranscoder() + self.thumbnailer = AudioThumbnailer() + + def copy_original(self): + if self.audio_config['keep_original']: + copy_original( + self.entry, self.orig_filename, + self.name_builder.fill('{basename}{ext}')) + + def transcode(self, quality=None): + if not quality: + quality = self.audio_config['quality'] + + progress_callback = ProgressCallback(self.entry) + webm_audio_tmp = os.path.join(self.workbench.dir, + self.name_builder.fill( + '{basename}{ext}')) + + webm_audio_filepath = create_pub_filepath( + self.entry, + '{original}.webm'.format( + original=os.path.splitext( + self.orig_filename[-1])[0])) + + self.transcoder.transcode( + self.orig_filename, + webm_audio_tmp, + quality=quality, + progress_callback=progress_callback) + + self.transcoder.discover(webm_audio_tmp) + + _log.debug('Saving medium...') + store_public(self.entry, 'medium', webm_audio_tmp, + webm_audio_filepath) + + def create_spectrogram(self, quality=None, max_width=None, fft_size=None): + if not quality: + quality = self.audio_config['quality'] + if not max_width: + max_width = mgg.global_config['media:medium']['max_width'] + if not fft_size: + fft_size = self.audio_config['spectrogram_fft_size'] + + spectrogram_filepath = create_pub_filepath( + self.entry, + '{original}-spectrogram.jpg'.format( + original=os.path.splitext( + self.orig_filename[-1])[0])) + + wav_tmp = os.path.join(self.workbench.dir, self.name_builder.fill( + '{basename}.ogg')) + + _log.info('Creating OGG source for spectrogram') + self.transcoder.transcode( + self.orig_filename, + wav_tmp, + mux_string='vorbisenc quality={0} ! oggmux'.format(quality)) + + self.thumbnailer.spectrogram( + wav_tmp, + self.spectrogram_tmp, + width=max_width, + fft_size=fft_size) + + _log.debug('Saving spectrogram...') + store_public(self.entry, 'spectrogram', self.spectrogram_tmp, + spectrogram_filepath) + + def generate_thumb(self, size=None): + if not size: + max_width = mgg.global_config['medium:thumb']['max_width'] + max_height = mgg.global_config['medium:thumb']['max_height'] + size = (max_width, max_height) + + thumb_tmp = os.path.join(self.workbench.dir, self.name_builder.fill( + '{basename}-thumbnail.jpg')) + + self.thumbnailer.thumbnail_spectrogram( + self.spectrogram_tmp, + thumb_tmp, + size) + + thumb_filepath = create_pub_filepath( + self.entry, + '{original}-thumbnail.jpg'.format( + original=os.path.splitext( + self.orig_filename[-1])[0])) + + store_public(self.entry, 'thumb', thumb_tmp, thumb_filepath) + + +class InitialProcessor(CommonAudioProcessor): + """ + Initial processing steps for new audio + """ + name = "initial" + description = "Initial processing" + + @classmethod + def media_is_eligible(cls, entry=None, state=None): + """ + Determine if this media type is eligible for processing + """ + if not state: + state = entry.state + return state in ( + "unprocessed", "failed") + + @classmethod + def generate_parser(cls): + parser = argparse.ArgumentParser( + description=cls.description, + prog=cls.name) + + parser.add_argument( + '--quality', + help='vorbisenc quality') + + parser.add_argument( + '--fft_size', + type=int, + help='spectrogram fft size') + + parser.add_argument( + '--thumb_size', + metavar=('max_width', 'max_height'), + type=int) + + parser.add_argument( + '--medium_width', + type=int, + help='The width of the spectogram') + + parser.add_argument( + '--create_spectrogram', + action='store_true', + help='Create spectogram and thumbnail') + + return parser + + @classmethod + def args_to_request(cls, args): + return request_from_args( + args, ['create_spectrogram', 'quality', 'fft_size', + 'thumb_size', 'medium_width']) + + def process(self, quality=None, fft_size=None, thumb_size=None, + create_spectrogram=None, medium_width=None): + if not create_spectrogram: + create_spectrogram = self.audio_config['create_spectrogram'] + + self.common_setup() + self.transcode(quality=quality) + self.copy_original() + + if create_spectrogram: + self.create_spectrogram(quality=quality, max_width=medium_width, + fft_size=fft_size) + self.generate_thumb(size=thumb_size) + self.delete_queue_file() + + +class AudioProcessingManager(ProcessingManager): + def __init__(self): + super(self.__class__, self).__init__() + self.add_processor(InitialProcessor) |