def main(args): # process all files so the user can use wildcards like *.wav for input_file in args.files: output_file_w = input_file + "_w.png" output_file_s = input_file + "_s.jpg" this_args = (input_file, output_file_w, output_file_s, args.width, args.height, args.fft_size, progress_callback, args.color_scheme) print("processing file %s:\n\t" % input_file, end="") if not args.profile: try: create_wave_images(*this_args) except AudioProcessingException as e: print("Error running wav2png: %s" % e) else: from hotshot import stats import hotshot prof = hotshot.Profile("stats") prof.runcall(create_wave_images, *this_args) prof.close() print("\n---------- profiling information ----------\n") s = stats.load("stats") s.strip_dirs() s.sort_stats("time") s.print_stats(30) print("")
failure("unhandled exception", e) cleanup(to_cleanup) return False success("created ogg: " + ogg_path) # create waveform images M waveform_path_m = sound.locations("display.wave.M.path") spectral_path_m = sound.locations("display.spectral.M.path") try: os.makedirs(os.path.dirname(waveform_path_m)) except OSError: pass try: audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_m, spectral_path_m, 120, 71, 2048) except AudioProcessingException, e: cleanup(to_cleanup) failure("creation of images (M) has failed", e) return False except Exception, e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("created previews, medium") # create waveform images L waveform_path_l = sound.locations("display.wave.L.path") spectral_path_l = sound.locations("display.spectral.L.path") try: audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_l, spectral_path_l, 900, 201, 2048)
failure("unhandled exception", e) cleanup(to_cleanup) return False success("created ogg: " + ogg_path) # create waveform images M waveform_path_m = sound.locations("display.wave.M.path") spectral_path_m = sound.locations("display.spectral.M.path") try: os.makedirs(os.path.dirname(waveform_path_m)) except OSError: pass try: audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_m, spectral_path_m, 120, 71, 2048) except AudioProcessingException, e: cleanup(to_cleanup) failure("creation of images (M) has failed", e) return False except Exception, e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("created previews, medium") # create waveform images L waveform_path_l = sound.locations("display.wave.L.path") spectral_path_l = sound.locations("display.spectral.L.path") try: audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_l,
def process(sound): def write_log(message): logger.info("[%d] %i: %s" % (os.getpid(), sound.id, message)) sys.stdout.write(str(message) + '\n') sys.stdout.flush() def failure(message, error=None): sound.set_processing_ongoing_state("FI") sound.change_processing_state("FA", use_set_instead_of_save=True) logging_message = "Failed to process sound with id %s\n" % sound.id logging_message += "\tmessage: %s\n" % message if error: logging_message += "\terror: %s\n" % str(error) write_log(logging_message) def success(message): write_log(message) def cleanup(files): success("cleaning up files after processing: " + ", ".join(files)) for filename in files: try: os.unlink(filename) except: pass # not saving the date of the processing attempt anymore sound.set_processing_ongoing_state("PR") new_path = sound.locations('path') # Is the file at its new location? if not os.path.exists(new_path): # Is the file at its old location? if not sound.original_path or not os.path.exists(sound.original_path): failure( "The file to be processed can't be found at its FS1 nor at its FS2 location." ) return False else: success("Found the file at its FS1 location: %s" % sound.original_path) if not sound.original_path.startswith('/mnt/freesound-data/'): failure( "The file appears to be in a weird location and not in '/mnt/freesound-data/'!." ) return False success("Copying file from %s to %s" % (sound.original_path, new_path)) dest_dir = os.path.dirname(new_path) if not os.path.exists(dest_dir): try: os.makedirs(dest_dir) except: failure("Could not create destination directory %s" % dest_dir) return False shutil.copy(sound.original_path, new_path) sound.set_original_path(new_path) success("Copied file from its FS1 to FS2 location.") else: success("Found the file at its FS2 location: %s" % new_path) if sound.original_path != new_path: sound.set_original_path(new_path) # convert to pcm to_cleanup = [] try: tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id)) except IOError as e: # Could not create tmp file failure("could not create tmp file", e) try: if not audioprocessing.convert_to_pcm(sound.original_path, tmp_wavefile): tmp_wavefile = sound.original_path success("no need to convert, this file is already pcm data") else: to_cleanup.append(tmp_wavefile) success("converted to pcm: " + tmp_wavefile) except AudioProcessingException as e: failure("conversion to pcm has failed, trying ffmpeg", e) try: audioprocessing.convert_using_ffmpeg(sound.original_path, tmp_wavefile) to_cleanup.append(tmp_wavefile) success("converted to pcm: " + tmp_wavefile) except AudioProcessingException as e: failure("conversion to pcm with ffmpeg failed", e) return False except Exception as e: failure("unhandled exception", e) cleanup(to_cleanup) return False tmp_wavefile2 = tempfile.mktemp(suffix=".wav", prefix=str(sound.id)) try: info = audioprocessing.stereofy_and_find_info(settings.STEREOFY_PATH, tmp_wavefile, tmp_wavefile2) to_cleanup.append(tmp_wavefile2) except AudioProcessingException as e: failure("stereofy has failed, trying ffmpeg first", e) try: audioprocessing.convert_using_ffmpeg(sound.original_path, tmp_wavefile) info = audioprocessing.stereofy_and_find_info( settings.STEREOFY_PATH, tmp_wavefile, tmp_wavefile2) #if tmp_wavefile not in to_cleanup: to_cleanup.append(tmp_wavefile) to_cleanup.append(tmp_wavefile2) except AudioProcessingException as e: failure("ffmpeg + stereofy failed", e) cleanup(to_cleanup) return False except Exception as e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("got sound info and stereofied: " + tmp_wavefile2) if sound.type in ["mp3", "ogg", "m4a"]: info['bitdepth'] = 0 # mp3 and ogg don't have bitdepth try: sound.set_audio_info_fields(info) except Exception as e: # Could not catch a more specific exception failure("failed writting audio info fields to db", e) for mp3_path, quality in [(sound.locations("preview.LQ.mp3.path"), 70), (sound.locations("preview.HQ.mp3.path"), 192)]: # create preview try: os.makedirs(os.path.dirname(mp3_path)) except OSError: pass try: audioprocessing.convert_to_mp3(tmp_wavefile2, mp3_path, quality) except AudioProcessingException as e: cleanup(to_cleanup) failure("conversion to mp3 (preview) has failed", e) return False except Exception as e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("created mp3: " + mp3_path) for ogg_path, quality in [(sound.locations("preview.LQ.ogg.path"), 1), (sound.locations("preview.HQ.ogg.path"), 6)]: # create preview try: os.makedirs(os.path.dirname(ogg_path)) except OSError: pass try: audioprocessing.convert_to_ogg(tmp_wavefile2, ogg_path, quality) except AudioProcessingException as e: cleanup(to_cleanup) failure("conversion to ogg (preview) has failed", e) return False except Exception as e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("created ogg: " + ogg_path) # create waveform images M waveform_path_m = sound.locations("display.wave.M.path") spectral_path_m = sound.locations("display.spectral.M.path") try: os.makedirs(os.path.dirname(waveform_path_m)) except OSError: pass try: audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_m, spectral_path_m, 120, 71, 2048) except AudioProcessingException as e: cleanup(to_cleanup) failure("creation of images (M) has failed", e) return False except Exception as e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("created previews, medium") # create waveform images L waveform_path_l = sound.locations("display.wave.L.path") spectral_path_l = sound.locations("display.spectral.L.path") try: audioprocessing.create_wave_images(tmp_wavefile2, waveform_path_l, spectral_path_l, 900, 201, 2048) except AudioProcessingException as e: cleanup(to_cleanup) failure("creation of images (L) has failed", e) return False except Exception as e: failure("unhandled exception", e) cleanup(to_cleanup) return False success("created previews, large") cleanup(to_cleanup) sound.set_processing_ongoing_state("FI") sound.change_processing_state("OK", use_set_instead_of_save=True) # Copy previews and display files to mirror locations copy_previews_to_mirror_locations(sound) copy_displays_to_mirror_locations(sound) return True
def process(self, skip_previews=False, skip_displays=False): with TemporaryDirectory( prefix='processing_%s_' % self.sound.id, dir=settings.PROCESSING_TEMP_DIR) as tmp_directory: # Change ongoing processing state to "processing" in Sound model self.sound.set_processing_ongoing_state("PR") # Get the path of the original sound and convert to PCM try: sound_path = self.get_sound_path() tmp_wavefile = self.convert_to_pcm(sound_path, tmp_directory) except AudioProcessingException as e: self.set_failure(e) return False # Now get info about the file, stereofy it and save new stereofied PCM version in `tmp_wavefile2` try: fh, tmp_wavefile2 = tempfile.mkstemp(suffix=".wav", prefix="%i_" % self.sound.id, dir=tmp_directory) # Close file handler as we don't use it from Python os.close(fh) info = audioprocessing.stereofy_and_find_info(settings.STEREOFY_PATH, tmp_wavefile, tmp_wavefile2) except IOError as e: # Could not create tmp file self.set_failure("could not create tmp_wavefile2 file", e) return False except OSError as e: self.set_failure("stereofy has failed, " "make stereofy sure executable exists at %s: %s" % (settings.SOUNDS_PATH, e)) return False except AudioProcessingException as e: if "File contains data in an unknown format" in str(e): # Stereofy failed most probably because PCM file is corrupted. This can happen if "convert_to_pcm" # above is skipped because the file is already PCM but it has wrong format. It can also happen in # other occasions where "convert_to_pcm" generates bad PCM files. In this case we try to re-create # the PCM file using ffmpeg and try re-running stereofy self.log_info("stereofy failed, trying re-creating PCM file with ffmpeg and re-running stereofy") try: tmp_wavefile = self.convert_to_pcm(sound_path, tmp_directory, force_use_ffmpeg=True) info = audioprocessing.stereofy_and_find_info(settings.STEREOFY_PATH, tmp_wavefile, tmp_wavefile2) except AudioProcessingException as e: self.set_failure("re-run of stereofy with ffmpeg conversion has failed", str(e)) return False except Exception as e: self.set_failure("unhandled exception while re-running stereofy with ffmpeg conversion", e) return False else: self.set_failure("stereofy has failed", str(e)) return False except Exception as e: self.set_failure("unhandled exception while getting info and running stereofy", e) return False self.log_info("got sound info and stereofied: " + tmp_wavefile2) # Fill audio information fields in Sound object try: if self.sound.type in ["mp3", "ogg", "m4a"]: info['bitdepth'] = 0 # mp3 and ogg don't have bitdepth self.sound.set_audio_info_fields(**info) except Exception as e: # Could not catch a more specific exception self.set_failure("failed writting audio info fields to db", e) return False # Generate MP3 and OGG previews if not skip_previews: # Create directory to store previews (if it does not exist) # Same directory is used for all MP3 and OGG previews of a given sound so we only need to run this once try: create_directories(os.path.dirname(self.sound.locations("preview.LQ.mp3.path"))) except OSError: self.set_failure("could not create directory for previews") return False # Generate MP3 previews for mp3_path, quality in [(self.sound.locations("preview.LQ.mp3.path"), 70), (self.sound.locations("preview.HQ.mp3.path"), 192)]: try: audioprocessing.convert_to_mp3(tmp_wavefile2, mp3_path, quality) except OSError as e: self.set_failure("conversion to mp3 (preview) has failed, " "make sure that lame executable exists: %s" % e) return False except AudioProcessingException as e: self.set_failure("conversion to mp3 (preview) has failed", e) return False except Exception as e: self.set_failure("unhandled exception generating MP3 previews", e) return False self.log_info("created mp3: " + mp3_path) # Generate OGG previews for ogg_path, quality in [(self.sound.locations("preview.LQ.ogg.path"), 1), (self.sound.locations("preview.HQ.ogg.path"), 6)]: try: audioprocessing.convert_to_ogg(tmp_wavefile2, ogg_path, quality) except OSError as e: self.set_failure("conversion to ogg (preview) has failed, " "make sure that oggenc executable exists: %s" % e) return False except AudioProcessingException as e: self.set_failure("conversion to ogg (preview) has failed", e) return False except Exception as e: self.set_failure("unhandled exception generating OGG previews", e) return False self.log_info("created ogg: " + ogg_path) # Generate display images for different sizes and colour scheme front-ends if not skip_displays: # Create directory to store display images (if it does not exist) # Same directory is used for all displays of a given sound so we only need to run this once try: create_directories(os.path.dirname(self.sound.locations("display.wave.M.path"))) except OSError: self.set_failure("could not create directory for displays") return False # Generate display images, M and L sizes for NG and BW front-ends for width, height, color_scheme, waveform_path, spectral_path in [ (120, 71, color_schemes.FREESOUND2_COLOR_SCHEME, self.sound.locations("display.wave.M.path"), self.sound.locations("display.spectral.M.path")), (500, 201, color_schemes.BEASTWHOOSH_COLOR_SCHEME, self.sound.locations("display.wave_bw.M.path"), self.sound.locations("display.spectral_bw.M.path")), (900, 201, color_schemes.FREESOUND2_COLOR_SCHEME, self.sound.locations("display.wave.L.path"), self.sound.locations("display.spectral.L.path")), (1500, 401, color_schemes.BEASTWHOOSH_COLOR_SCHEME, self.sound.locations("display.wave_bw.L.path"), self.sound.locations("display.spectral_bw.L.path")) ]: try: fft_size = 2048 audioprocessing.create_wave_images(tmp_wavefile2, waveform_path, spectral_path, width, height, fft_size, color_scheme=color_scheme) self.log_info("created wave and spectrogram images: %s, %s" % (waveform_path, spectral_path)) except AudioProcessingException as e: self.set_failure("creation of display images has failed", e) return False except Exception as e: self.set_failure("unhandled exception while generating displays", e) return False # Change processing state and processing ongoing state in Sound model self.sound.set_processing_ongoing_state("FI") self.sound.change_processing_state("OK", processing_log=self.work_log) # Copy previews and display files to mirror locations copy_previews_to_mirror_locations(self.sound) copy_displays_to_mirror_locations(self.sound) return True
def process(sound, skip_previews=False, skip_displays=False): def write_log(message): sys.stdout.write(str(message) + '\n') sys.stdout.flush() logger.info("[%d] %i: %s" % (os.getpid(), sound.id, message)) def create_directory(path): try: os.makedirs(path) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(path): # Directory already exists pass else: # Directory could not be created, raise exception raise def cleanup(files): success("cleaning up processing files: " + ", ".join(files)) for filename in files: try: os.unlink(filename) except: pass def failure(message, error=None): sound.set_processing_ongoing_state("FI") sound.change_processing_state("FA", use_set_instead_of_save=True) logging_message = "ERROR: Failed to process sound with id %s\n" % sound.id logging_message += "\tmessage: %s\n" % message if error: logging_message += "\terror: %s" % str(error) write_log(logging_message) cleanup(to_cleanup) def success(message): write_log('- ' + message) to_cleanup = [ ] # This will hold a list of files to cleanup after processing # Change ongoing processing state to "processing" in Sound model sound.set_processing_ongoing_state("PR") # Get the path of the original sound sound_path = sound.locations('path') if settings.USE_PREVIEWS_WHEN_ORIGINAL_FILES_MISSING and not os.path.exists( sound_path): sound_path = sound.locations('preview.LQ.mp3.path') if not os.path.exists(sound_path): failure("can't process sound as file does not exist") return False success("file to process found in " + sound_path) # Convert to PCM and save PCM version in `tmp_wavefile` try: tmp_wavefile = tempfile.mktemp(suffix=".wav", prefix=str(sound.id)) if not audioprocessing.convert_to_pcm(sound_path, tmp_wavefile): tmp_wavefile = sound_path success("no need to convert, this file is already PCM data") else: to_cleanup.append(tmp_wavefile) success("converted to pcm: " + tmp_wavefile) except IOError as e: # Could not create tmp file failure("could not create tmp_wavefile file", e) return False except AudioProcessingException as e: try: audioprocessing.convert_using_ffmpeg(sound_path, tmp_wavefile) to_cleanup.append(tmp_wavefile) success("converted to PCM: " + tmp_wavefile) except AudioProcessingException as e: failure("conversion to PCM failed", e) return False except Exception as e: failure("unhandled exception while converting to PCM", e) return False # Now get info about the file, stereofy it and save new stereofied PCM version in `tmp_wavefile2` try: tmp_wavefile2 = tempfile.mktemp(suffix=".wav", prefix=str(sound.id)) to_cleanup.append(tmp_wavefile2) info = audioprocessing.stereofy_and_find_info(settings.STEREOFY_PATH, tmp_wavefile, tmp_wavefile2) if sound.type in ["mp3", "ogg", "m4a"]: info['bitdepth'] = 0 # mp3 and ogg don't have bitdepth success("got sound info and stereofied: " + tmp_wavefile2) except IOError as e: # Could not create tmp file failure("could not create tmp_wavefile2 file", e) return False except AudioProcessingException as e: failure("stereofy has failed", e) return False except Exception as e: failure("unhandled exception while getting info and running stereofy", e) return False # Fill audio information fields in Sound object try: sound.set_audio_info_fields(info) except Exception as e: # Could not catch a more specific exception failure("failed writting audio info fields to db", e) return False # Generate MP3 and OGG previews if not skip_previews: # Create directory to store previews (if it does not exist) # Same directory is used for all MP3 and OGG previews of a given sound so we only need to run this once try: create_directory( os.path.dirname(sound.locations("preview.LQ.mp3.path"))) except OSError: failure("could not create directory for previews") return False # Generate MP3 previews for mp3_path, quality in [(sound.locations("preview.LQ.mp3.path"), 70), (sound.locations("preview.HQ.mp3.path"), 192) ]: try: audioprocessing.convert_to_mp3(tmp_wavefile2, mp3_path, quality) except AudioProcessingException as e: failure("conversion to mp3 (preview) has failed", e) return False except Exception as e: failure("unhandled exception generating MP3 previews", e) return False success("created mp3: " + mp3_path) # Generate OGG previews for ogg_path, quality in [(sound.locations("preview.LQ.ogg.path"), 1), (sound.locations("preview.HQ.ogg.path"), 6)]: try: audioprocessing.convert_to_ogg(tmp_wavefile2, ogg_path, quality) except AudioProcessingException as e: failure("conversion to ogg (preview) has failed", e) return False except Exception as e: failure("unhandled exception generating OGG previews", e) return False success("created ogg: " + ogg_path) # Generate display images for different sizes and colour scheme front-ends if not skip_displays: # Create directory to store display images (if it does not exist) # Same directory is used for all displays of a given sound so we only need to run this once try: create_directory( os.path.dirname(sound.locations("display.wave.M.path"))) except OSError: failure("could not create directory for displays") return False # Generate display images, M and L sizes for NG and BW front-ends for width, height, color_scheme, waveform_path, spectral_path in [ (120, 71, color_schemes.FREESOUND2_COLOR_SCHEME, sound.locations("display.wave.M.path"), sound.locations("display.spectral.M.path")), (500, 201, color_schemes.BEASTWHOOSH_COLOR_SCHEME, sound.locations("display.wave_bw.M.path"), sound.locations("display.spectral_bw.M.path")), (900, 201, color_schemes.FREESOUND2_COLOR_SCHEME, sound.locations("display.wave.L.path"), sound.locations("display.spectral.L.path")), (1500, 401, color_schemes.BEASTWHOOSH_COLOR_SCHEME, sound.locations("display.wave_bw.L.path"), sound.locations("display.spectral_bw.L.path")) ]: try: fft_size = 2048 audioprocessing.create_wave_images(tmp_wavefile2, waveform_path, spectral_path, width, height, fft_size, color_scheme=color_scheme) success("created wave and spectrogram images: %s, %s" % (waveform_path, spectral_path)) except AudioProcessingException as e: failure("creation of display images has failed", e) return False except Exception as e: failure("unhandled exception while generating displays", e) return False # Clean up temp files cleanup(to_cleanup) # Change processing state and processing ongoing state in Sound model sound.set_processing_ongoing_state("FI") sound.change_processing_state("OK", use_set_instead_of_save=True) # Copy previews and display files to mirror locations copy_previews_to_mirror_locations(sound) copy_displays_to_mirror_locations(sound) return True