def maybe_create_ad_db(): if os.path.exists(ads_db_path): return print 'Create fingerprint db...' item_paths = [] for item in os.listdir(AD_EXAMPLES_DIR_PATH): item_path = os.path.join(AD_EXAMPLES_DIR_PATH, item) try: audio.get_audio_length(item_path) except: print "maybe_create_ad_db: skip item: %s" % item_path continue item_paths.append(item_path) txt_paths_file_path = os.path.join(TMP_DIR_PATH, 'ad_examples_paths.txt') txt = open(txt_paths_file_path, 'w') txt.write('\n'.join(item_paths)) txt.close() # create db p = subprocess.Popen( "venv/bin/python " + audfprint_script_path + " new" + " --dbase "+ads_db_path + " --density 150" + " --shifts 1" + " --samplerate 11025" + " --list "+txt_paths_file_path, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() print out if p.returncode != 0: raise Exception("failed ads db creating: "+err)
def get_regions_to_cut(wav_path): fngpt_regions = audio_fingerprint_finder.find_audio_from_db(wav_path) intrmttnt_regions = audio_intermittent_segmentation.get_commertial_intervals(wav_path) intrmttnt_regions = [r for r in intrmttnt_regions if r[2] == 1] print "Fingerprint regions:" print_regions(fngpt_regions) print "Audio_intermittent regions:" print_regions(intrmttnt_regions) print "---------" regions_to_cut = [] used_fngpt_regions = [] for ir in intrmttnt_regions: print "for region %s" % region_str(ir) # find close to end intro #print "for time %s" % str(datetime.timedelta(seconds=ir[1])) start = ir[0] end = ir[1] intro_r = find_region_near_time(end, fngpt_regions, 30) if intro_r: print "found fngpt region %s" % region_str(intro_r) end = intro_r[1] if intro_r[0] < start: start = intro_r[0] used_fngpt_regions.append(intro_r) regions_to_cut.append((start, end, 'commertial')) else: # didnt find intro finishing commertial # accept it only if its in the end # and cut till the end total_duration = audio.get_audio_length(wav_path) if abs(end - total_duration) < 20: end = total_duration regions_to_cut.append((start, end, 'commertial')) print "=======" # also add unused intermittent regions to cut just intro not_used_fngpt_regions = [r for r in fngpt_regions if not any([x[0] == r[0] for x in used_fngpt_regions])] regions_to_cut.extend(not_used_fngpt_regions) if len(not_used_fngpt_regions) > 0: print('also added %i not used fingerprint regions' % len(not_used_fngpt_regions)) print "commertial regions: " print_regions(regions_to_cut) return regions_to_cut
def inject_noise_sample(self, data, noise_path, noise_level): noise_len = get_audio_length(noise_path) data_len = len(data) / self.sample_rate noise_start = np.random.rand() * (noise_len - data_len) noise_end = noise_start + data_len noise_dst = audio_with_sox( noise_path, self.sample_rate, noise_start, noise_end) assert len(data) == len(noise_dst) noise_energy = np.sqrt(noise_dst.dot(noise_dst) / noise_dst.size) data_energy = np.sqrt(data.dot(data) / data.size) data += noise_level * noise_dst * data_energy / noise_energy return data
def get_regions_to_save(input_file): total_duration = audio.get_audio_length(input_file) regions_to_cut = get_regions_to_cut(input_file) save_regions = [] for i, region in enumerate(regions_to_cut): region_start = 0 if i == 0 else regions_to_cut[i-1][1] region_end = region[0] region_duration = region_end - region_start if region_duration < 5: continue save_regions.append((region_start, region_end, 'save')) # add last region if len(regions_to_cut) > 0: region_start = regions_to_cut[-1][1] region_end = total_duration region_duration = region_end - region_start if not(region_duration < 5): save_regions.append((region_start, region_end, 'save')) else: save_regions.append((0, total_duration, 'save')) print '%i save regions: %s' % (len(save_regions), str(save_regions)) return save_regions
def find_audio_from_db(input_path): maybe_create_ad_db() precomputed_path = precompute(input_path) print 'Finding audio from fingerprint db in %s...' % input_path print 'using db %s' % ads_db_path matches_file_path = os.path.join(TMP_DIR_PATH, os.path.basename(input_path)+'_matches.txt') if not os.path.exists(matches_file_path): print 'Matching...' p = subprocess.Popen( "venv/bin/python " + audfprint_script_path + " match" + ' --find-time-range' + ' --max-matches 25' + " --dbase " + ads_db_path + " --ncores 1" + ' --sortbytime' + ' ' + precomputed_path, #+ ' --opfile ' + map_file_path, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() print out if p.returncode != 0: raise Exception("failed matching: "+err) # write to file txt = open(matches_file_path, 'w') txt.write(out) txt.close() print 'Wrote matches from cache %s' % matches_file_path # read cached print 'Read matches from cache %s' % matches_file_path txt = open(matches_file_path, 'r') out = txt.read() txt.close() # match results regexp = re.compile(r'Matched[\s]*(?P<matched_duration>[0-9\.]+).*starting at[\s]*(?P<start_target>[0-9\.]*).*to time[\s]*(?P<start_piece>[0-9\.]*).*in.*\/(?P<ad_type>.*)\..*with[\s]*(?P<hashes_matched>[0-9]*).*of[\s]*(?P<hashes_total>[0-9]*)') groups = [m.groupdict() for m in regexp.finditer(out)] # collect regions regions = [] pointer = 0 total_duration = audio.get_audio_length(input_path) while pointer < len(groups): m = groups[pointer] start = float(m['start_target']) end = float(m['start_target']) + float(m['matched_duration']) if 'intro' in m['ad_type']: if len(regions) == 0 and start < 2*60: # if first and not so far from beginning - cut from 0 to ad end # (case where there are ads in beginning and then headpiece) regions.append(( 0, end+1, # + 1 cause specific intro sound m['ad_type'] )) else: # else - just cut matched ad regions.append(( start, end+1, # + 1 cause specific intro sound m['ad_type'] )) pointer += 1 else: raise Exception('WARNING: undefined ad type "%s"' % ad['type']) print 'fingerptited audio regions: %s' % str(regions) return regions