def convert_audio_file_if_necessary(aft): file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(aft) # Check that audio is in the right format command = [ 'ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', tmp_file ] p = Popen(command, stdin=PIPE, stdout=PIPE) output, errors = p.communicate() results = ast.literal_eval(output) convert = False for stream in results['streams']: if stream["codec_type"] in 'audio': if stream["codec_name"] not in "aac mp3 wav": convert = True if stream["channels"] > 2: convert = True if convert: new_file = '.'.join(tmp_file.split('.')[:-1]) + '.m4a' logger.debug(new_file) command = [ 'ffmpeg', '-i', tmp_file, '-ar', '44100', '-ac', '1', '-c:a', 'aac', new_file ] logger.debug(command) p = Popen(command, stdin=PIPE, stdout=PIPE) output, errors = p.communicate() if not errors: aft.audio_file.save( new_file.split('/').pop(), File(open(new_file))) aft.save()
def create_and_return_transcription_segments(aft): ''' Creates the transcription segments from an AudioFileTranscription model. ''' convert_audio_file_if_necessary(aft) # We should delete all segments if we're going to create more! deleted = TranscriptionSegment.objects.filter(parent=aft).delete() file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(aft) segments = wahi_korero_segmenter(tmp_file, aft) # segments = dummy_segme nter(tmp_file) logger.debug(segments) ts_segments = [] for segment in segments: start = segment['start'] end = segment['end'] ts, created = TranscriptionSegment.objects.get_or_create(start=start, end=end, parent=aft) ts_segments.append(ts) return ts_segments
def get_media_duration(obj): ''' Returns a media objects duration in seconds. Assumes the object has a `audio_file_field` ''' file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(obj) code = \ "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {0}".format( tmp_file) data = commands.getstatusoutput(code) return float(data[1])
def transcribe_segment(ts): try: file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(ts.parent) except Exception as e: return "Error creating temporary environment. {0}".format(e) tmp_seg_file = tmp_stor_dir + '/ts_{0}.wav'.format(ts.pk) command = \ ['ffmpeg', '-i', tmp_file, '-ss', '{0:.2f}'.format(ts.start/100.0), '-to', '{0:.2f}'.format(ts.end/100.0), '-ar', '16000', '-ac', '1', # '-f', 's16le', tmp_seg_file] logger.debug("COMMAND: {0}".format(' '.join(command))) p = Popen(command, stdin=PIPE, stdout=PIPE) output, errors = p.communicate() # result = transcribe_audio_sphinx(output) result = transcribe_audio_sphinx(None, continuous=True, file_path=tmp_seg_file) if result['success']: # ts.text = parse_sphinx_transcription(result['transcription']) ts.text = result['transcription'].strip() ts.transcriber_log = result # Get or create a source for the API source, created = Source.objects.get_or_create( source_name='Transcription API', author="{0}".format(result['model_version']), source_type='M', source_url=result['API_URL']) ts.source = source ts.save() else: ts.transcriber_log = result ts.save()
def slice_audio(aft, start, stop): try: file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(aft) except Exception as e: return "Error creating temporary environment. {0}".format(e) tmp_seg_file = tmp_stor_dir + '/sliced_{0}_{1}.wav'.format(start, stop) command = \ ['ffmpeg', '-i', tmp_file, '-ss', '{0:.2f}'.format(start/100.0), '-to', '{0:.2f}'.format(stop/100.0), # '-ar', '16000', '-ac', '1', # '-f', 's16le', tmp_seg_file] logger.debug("COMMAND: {0}".format(' '.join(command))) p = Popen(command, stdin=PIPE, stdout=PIPE) output, errors = p.communicate() return tmp_seg_file
def transcribe_segment(ts): if not check_to_transcribe_segment(ts): return 'Not transcribing segment. Likely segment too long.' try: file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(ts.parent) except Exception as e: return "Error creating temporary environment. {0}".format(e) tmp_seg_file = tmp_stor_dir + '/ts_{0}.wav'.format(ts.pk) command = \ ['ffmpeg', '-i', tmp_file, '-ss', '{0:.2f}'.format(ts.start/100.0), '-to', '{0:.2f}'.format(ts.end/100.0), '-ar', '16000', '-ac', '1', # '-f', 's16le', tmp_seg_file] logger.debug("COMMAND: {0}".format(' '.join(command))) p = Popen(command, stdin=PIPE, stdout=PIPE) output, errors = p.communicate() # result = transcribe_audio_sphinx(output) result = transcribe_audio_sphinx( None, continuous=True, file_path=tmp_seg_file) if result['success']: # ts.text = parse_sphinx_transcription(result['transcription']) ts.text = result['transcription'].strip() result['status'] = unicode(_('Done')) ts.transcriber_log = result # Get or create a source for the API source, created = Source.objects.get_or_create( source_name='Transcription API', author="{0}".format(result['model_version']), source_type='M', source_url=result['API_URL']) ts.source = source if ts.text is '' or ts.text is ' ': ts.no_speech_detected = True ts.save() else: result['status'] = unicode(_('Error')) if ts.transcriber_log: if 'retry' in ts.transcriber_log.keys(): ts.transcriber_log.update(result) ts.transcriber_log['retry'] = False else: ts.transcriber_log['retry'] = True else: ts.transcriber_log = result ts.save() os.remove(tmp_seg_file) return result
def encode_audio(obj, test=False, codec='aac'): codecs = { 'mp3': ['libmp3lame', 'mp3'], 'aac': ['aac', 'm4a', 44100, 1], 'wav': ['pcm_s16le', 'wav', 16000, 1] } file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(obj) # If a video doesn't have audio this will fail. command = 'ffprobe -v quiet -show_entries stream -print_format json ' + \ tmp_file data = ast.literal_eval(commands.getoutput(command)) streams = data['streams'] audio = False for stream in streams: if stream['codec_type'] in 'audio': audio = True if audio: file_name = obj.get_file_name() + '_x' extension = codecs[codec][1] if codec in 'wav': code = "ffmpeg -i {0} -vn -acodec {1} -ar {2} -ac {3} {4}/{5}.{6}".format( tmp_file, codecs[codec][0], codecs[codec][2], codecs[codec][3], tmp_stor_dir, file_name, extension) elif codec in 'aac': code = \ "ffmpeg -i {0} -vn -acodec {1} -ar {5} -ac {6} {7} {2}/{3}.{4}".format( tmp_file, codecs[codec][0], tmp_stor_dir, file_name, extension, codecs[codec][2], codecs[codec][3], "-c:a aac -b:a 64k") # -profile:a aac_he logger.debug('Running: ' + code) data = commands.getstatusoutput(code) logger.debug(data[1]) logger.debug(u'FILE FILENAME: \t{0}'.format(file_name)) if file_name is None: file_name = 'audio' if 'aac' in codec: obj.audio_file_aac.save( file_name + '.' + extension, File( open(tmp_stor_dir + '/{0}.{1}'.format(file_name, extension)))) elif 'wav' in codec: obj.audio_file_wav.save( file_name + '.' + extension, File( open(tmp_stor_dir + '/{0}.{1}'.format(file_name, extension)))) code = 'rm ' + tmp_stor_dir + '/{0}.{1}'.format(file_name, extension) logger.debug('Running: ' + code) data = commands.getstatusoutput(code) logger.debug(data[1]) if not audio: logger.debug('No audio stream found.') return False # Need a better way to check this! data = commands.getstatusoutput('rm ' + tmp_file) logger.debug('Removed tmp file %s' % (tmp_file)) data = commands.getstatusoutput('rm -r ' + tmp_stor_dir) logger.debug('Removed tmp stor dir %s' % (tmp_stor_dir)) set_s3_content_deposition(obj) return "Encoded {0}".format(obj)
def encode_audio(recording, test=False, codec='aac'): ''' Encode audio into required formats. Also sets recording duration. ''' if not isinstance(codec, list): codec_list = [codec] # Backwards compatibility else: codec_list = codec codecs = { 'mp3': ['libmp3lame', 'mp3'], 'aac': ['aac', 'm4a'], 'wav': ['pcm_s16le', 'wav', 16000, 1] } file_path, tmp_stor_dir, tmp_file, absolute_directory = \ prepare_temporary_environment(recording) # If a video doesn't have audio this will fail. command = 'ffprobe -v quiet -show_entries stream -print_format json ' + \ tmp_file data = ast.literal_eval(commands.getoutput(command)) streams = data['streams'] audio = False for stream in streams: if stream['codec_type'] in 'audio': audio = True if audio: file_name = recording.get_recording_file_name() code = \ "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {0}".format( tmp_file) data = commands.getstatusoutput(code) recording.duration = float(data[1]) for codec in codec_list: if codec in 'wav': file_name = file_name + '_16kHz' extension = codecs[codec][1] if codec in 'wav': code = "ffmpeg -i {0} -vn -acodec {1} -ar {2} -ac {3} {4}/{5}.{6}".format( tmp_file, codecs[codec][0], codecs[codec][2], codecs[codec][3], tmp_stor_dir, file_name, extension) else: code = "ffmpeg -i {0} -vn -acodec {1} {2}/{3}.{4}".format( tmp_file, codecs[codec][0], tmp_stor_dir, file_name, extension) logger.debug('Running: '+code) data = commands.getstatusoutput(code) logger.debug(data[1]) logger.debug(u'FILE FILENAME: \t{0}'.format(file_name)) if file_name is None: file_name = 'audio' if 'aac' in codec: recording.audio_file_aac.save( file_name+'.'+extension, File(open(tmp_stor_dir+'/{0}.{1}'.format( file_name, extension)))) elif 'wav' in codec: recording.audio_file_wav.save( file_name+'.'+extension, File(open(tmp_stor_dir+'/{0}.{1}'.format( file_name, extension)))) code = 'rm '+tmp_stor_dir+'/{0}.{1}'.format(file_name, extension) logger.debug('Running: '+code) data = commands.getstatusoutput(code) logger.debug(data[1]) if not audio: logger.debug('No audio stream found.') return False data = commands.getstatusoutput('rm ' + tmp_file) logger.debug('Removed tmp file %s' % (tmp_file)) data = commands.getstatusoutput('rm -r ' + tmp_stor_dir) logger.debug('Removed tmp stor dir %s' % (tmp_stor_dir)) set_s3_content_deposition(recording) return "Encoded {0}".format(recording)