Fixes #65, fixes #60, merges #64

This commit is contained in:
Will Drevo 2014-12-15 21:30:33 -05:00
parent 99f4e35672
commit ece1c8b22e
3 changed files with 26 additions and 23 deletions

View file

@ -1,5 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
import os
import sys import sys
import json import json
import warnings import warnings
@ -12,15 +13,15 @@ from argparse import RawTextHelpFormatter
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
DEFAULT_CONFIG_FILE = "dejavu.cnf" DEFAULT_CONFIG_FILE = "dejavu.cnf.SAMPLE"
def init(config_file): def init(configpath):
""" Load config from a JSON file """
or anything outputting a python dictionary Load config from a JSON file
""" """
try: try:
with open(config_file) as f: with open(configpath) as f:
config = json.load(f) config = json.load(f)
except IOError as err: except IOError as err:
print("Cannot open configuration: %s. Exiting" % (str(err))) print("Cannot open configuration: %s. Exiting" % (str(err)))
@ -31,15 +32,13 @@ def init(config_file):
if __name__ == '__main__': if __name__ == '__main__':
""" If running from terminal.
"""
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Audio Fingerprinting library", description="Dejavu: Audio Fingerprinting library",
formatter_class=RawTextHelpFormatter) formatter_class=RawTextHelpFormatter)
parser.add_argument('-c', '--config', nargs='?', parser.add_argument('-c', '--config', nargs='?',
help='Path to configuration file\n' help='Path to configuration file\n'
'Usages: \n' 'Usages: \n'
'--config /path/to/congfile\n') '--config /path/to/config-file\n')
parser.add_argument('-f', '--fingerprint', nargs='*', parser.add_argument('-f', '--fingerprint', nargs='*',
help='Fingerprint files in a directory\n' help='Fingerprint files in a directory\n'
'Usages: \n' 'Usages: \n'
@ -54,7 +53,7 @@ if __name__ == '__main__':
args = parser.parse_args() args = parser.parse_args()
if not args.fingerprint and not args.recognize: if not args.fingerprint and not args.recognize:
print("No arguments") parser.print_help()
sys.exit(0) sys.exit(0)
config_file = args.config config_file = args.config
@ -65,15 +64,18 @@ if __name__ == '__main__':
djv = init(config_file) djv = init(config_file)
if args.fingerprint: if args.fingerprint:
# Fingerprint all files in a directory # Fingerprint all files in a directory
if 2 == len(args.fingerprint): if len(args.fingerprint) == 2:
directory = args.fingerprint[0] directory = args.fingerprint[0]
extension = args.fingerprint[1] extension = args.fingerprint[1]
print("Fingerprinting all .%s files in the %s directory" print("Fingerprinting all .%s files in the %s directory"
% (extension, directory)) % (extension, directory))
djv.fingerprint_directory(directory, ["." + extension], 4) djv.fingerprint_directory(directory, ["." + extension], 4)
elif 1 == len(args.fingerprint): elif len(args.fingerprint) == 1:
filepath = args.fingerprint[0] filepath = args.fingerprint[0]
if os.path.isdir(filepath):
print("Please specify an extension if you'd like to fingerprint a directory!")
sys.exit(1)
djv.fingerprint_file(filepath) djv.fingerprint_file(filepath)
elif args.recognize: elif args.recognize:

View file

@ -136,26 +136,20 @@ def generate_hashes(peaks, fan_value=DEFAULT_FAN_VALUE):
sha1_hash[0:20] time_offset sha1_hash[0:20] time_offset
[(e05b341a9b77a51fd26, 32), ... ] [(e05b341a9b77a51fd26, 32), ... ]
""" """
fingerprinted = set() # to avoid rehashing same pairs
if PEAK_SORT: if PEAK_SORT:
peaks.sort(key=itemgetter(1)) peaks.sort(key=itemgetter(1))
for i in range(len(peaks)): for i in range(len(peaks)):
for j in range(1, fan_value): for j in range(1, fan_value):
if (i + j) < len(peaks) and not (i, i + j) in fingerprinted: if (i + j) < len(peaks):
freq1 = peaks[i][IDX_FREQ_I] freq1 = peaks[i][IDX_FREQ_I]
freq2 = peaks[i + j][IDX_FREQ_I] freq2 = peaks[i + j][IDX_FREQ_I]
t1 = peaks[i][IDX_TIME_J] t1 = peaks[i][IDX_TIME_J]
t2 = peaks[i + j][IDX_TIME_J] t2 = peaks[i + j][IDX_TIME_J]
t_delta = t2 - t1 t_delta = t2 - t1
if t_delta >= MIN_HASH_TIME_DELTA and t_delta <= MAX_HASH_TIME_DELTA: if t_delta >= MIN_HASH_TIME_DELTA and t_delta <= MAX_HASH_TIME_DELTA:
h = hashlib.sha1( h = hashlib.sha1(
"%s|%s|%s" % (str(freq1), str(freq2), str(t_delta))) "%s|%s|%s" % (str(freq1), str(freq2), str(t_delta)))
yield (h.hexdigest()[0:FINGERPRINT_REDUCTION], t1) yield (h.hexdigest()[0:FINGERPRINT_REDUCTION], t1)
# ensure we don't repeat hashing
fingerprinted.add((i, i + j))

View file

@ -16,12 +16,19 @@ djv.fingerprint_directory("mp3", [".mp3"])
# Recognize audio from a file # Recognize audio from a file
from dejavu.recognize import FileRecognizer from dejavu.recognize import FileRecognizer
song = djv.recognize(FileRecognizer, "mp3/Sean-Fournier--Falling-For-You.mp3") song = djv.recognize(FileRecognizer, "mp3/Sean-Fournier--Falling-For-You.mp3")
print "From file we recognized: %s\n" % song
# Or recognize audio from your microphone for 10 seconds # Or recognize audio from your microphone for `secs` seconds
from dejavu.recognize import MicrophoneRecognizer from dejavu.recognize import MicrophoneRecognizer
song = djv.recognize(MicrophoneRecognizer, seconds=2) secs = 5
song = djv.recognize(MicrophoneRecognizer, seconds=secs)
if song is None:
print "Nothing recognized -- did you play the song out loud so your mic could hear it? :)"
else:
print "From mic with %d seconds we recognized: %s\n" % (secs, song)
# Or use a recognizer without the shortcut, in anyway you would like # Or use a recognizer without the shortcut, in anyway you would like
from dejavu.recognize import FileRecognizer from dejavu.recognize import FileRecognizer
recognizer = FileRecognizer(djv) recognizer = FileRecognizer(djv)
song = recognizer.recognize_file("mp3/Josh-Woodward--I-Want-To-Destroy-Something-Beautiful.mp3") song = recognizer.recognize_file("mp3/Josh-Woodward--I-Want-To-Destroy-Something-Beautiful.mp3")
print "No shortcut, we recognized: %s\n" % song