# Fingerprinting POC using Dejavu

## Reading
Article: https://willdrevo.com/fingerprinting-and-audio-recognition-with-python/

Original Repo: https://github.com/worldveil/dejavu

Other articles:
* Original Shazam Paper: http://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf
* https://medium.com/intrasonics/a-fingerprint-for-audio-3b337551a671
* Chromaprint: https://oxygene.sk/2011/01/how-does-chromaprint-work/
* https://medium.com/@treycoopermusic/how-shazam-works-d97135fb4582

## Dejavu
I had to modify the libraries in a few ways:
* added an S3 object wrapper to act like a proper file
* fix a bug where the paramters were not correctly sent to `fingerprint_file`
* removed the loading of audio file hashes on instantiation
* checking for duplicates happens in the `submit_fingerprinting_jobs scripts` where the list of unique filenames are loaded on start
* increased the batch size for the MySQL queries from 100 to 5000
* removed the logic that deletes rows with the `fingerprinted` colum set to 0 to allow parallel processing.
* modified `fingerprint_directory` to `fingerprint_files` that uses t

## Lambda
The code / packages required for Dejavu are too large to fit in a lambda. The initial effort to have a lambda generate fingerprints for a single S3 object was abandonned

## ECS workers
After ambadonning the Lambda option, ECS worker were a good fit for this. Dejavu supports fingeprinting a list of files using multiprocessing. This gave us the inclination to invoke a single ECS task
to process a number of files, like 25 to 100. This allowed for some horizontal scaling and multiple tasks can fingerprint a set of files. This presented a challenge in queueing these tasks and ensuring they work on a set of files that another task does no work on.
It proved difficult to determine a list of unfingerprinted files by just traversing a list of objects on S3 and checking that they dont exist in the songs table.
In addition it is not possible to invoke a fargate task with specific parameters from cloudwatch.
100 files were a lot and the task would run of memory.
25 files were ok but all the files used a single connection to dump all the fingerprints.
Also, i had to wait until the task started to upload a new txt file that would start a new task (s3 cloudwatch trigger)
`generate_batch.py` was the hack for creating txt files

## AWS Batch
Horizontal scaling: each task fingerprints a single file. hundreds of tracks per minute 
No need for cloudwatch trigger, as we can submit batch jobs via boto3


## example ISRC issues
The label was Worldwide Records Inc. (Label ID: 18867), examples below. I need to look into why this label is still active because I believe they were supposed to be terminated.

* ISRC USV291450337 / 888831823278 - audio segments from a film start at the 5:00 min mark.
* ISRC US8VY1457260 / UPC 888831392804 - audio segments from a film are featured at the beginning and end of the track. 
* ISRC US8VY1457491 / UPC 888831631934 - audio segments from a film start at the beginning of the track. 