Package: similar-vid
Similar VidSimilar-vid is a library for finding similar frames between videos. It is written as a thin wrapper aroung the Decord and OpenCV libraries.
It was inspired by Netflix's "Skip Intro" feature which allows users to skip intro portions of a tv show.Table of ContentsDependenciesInstallationUsageToDoDependenciesSimilar-vid depends on the following:pillownumpydecordimagehashopencv-pythonFortunately, there's a Pipfile that contains virtual environment configurations as will be explained below.InstallationThe most straightforward way to install the library is via pipenv:Clone the repositorycd to the repository and install the dependencies using pipenvactivate the directorygit clone https://github.com/jahwi/similar-vid.git
cd similar-vid
(optionally install pipenv) pip install pipenv
pipenv install
pipenv shellAlternatively, you can install the dependencies above manually using pip.pip install pillow numpy decord opencv-python imagehashUsageUsing the CLIUsing Similar-vid within other python projectsLoading and MatchingSaving hashes and match data for future useLoading saved hashes into fieldsUsing AliasesThe CLIWithin the project is also a cli wrapper around the library. It is the most straightforward way to use Similar-vid.similar_cli.py "path_to_refrence_video_or_hash" "path_to_other_video another_file_path yet_another_video_file_path"Using Similar-Vid within other python projects1. Loading and MatchingTheSimilarclass'matchmethod compares frames between a reference video and an array of at least one other video.# import the classfromsimilar_vid.similar_secsimportSimilarif__name__=="__main__":# The library uses multiprocessing, so protect the entry point# load videosvideo_task=Similar(ref=path_to_reference_video,comp_arr=[path_to_other_video_1,path_to_other_video_2,path_to_other_video_3])# match videos in comp_arr against reference videovideo_task.match()# print matchesprint(video_task.matches)2. Saving hashes and match data for future useThe library also provides asavefunction, which is a wrapper around thejson.dumpsmethod of thejsonlibrary. It allows saving fields of theSimilarclass to a json file for future use. These can then be reloaded as will be discussed in3. Loading saved hashes into fields.# import the classfromsimilar_vid.similar_secsimportSimilar,saveif__name__=="__main__":# load videosvideo_task=Similar(ref=path_to_reference_video,comp_arr=[path_to_other_video_1,path_to_other_video_2,path_to_other_video_3])# save the video's fields for future usesave(video_task.ref,path_to_output_file.json)# field holds the reference video hashsave(video_task.comp,path_to_another_output_file.json)# field holds the hashes of the comparision array3. Loading saved hashes into fieldsAfter saving fields using thesavefunction, theloadfunction allows loading saved hashes into fields.# import the classfromsimilar_vid.similar_secsimportSimilar,loadif__name__=="__main__":# load videos via hashesvideo_task=Similar()# first, declare an empty instancevideo_task.ref=load(path_to_ref_video_hash.json)# then edit the fields directlyvideo_task.comp=load(path_to_comp_videos_hash.json)# It can then be matched, as usualvideo_task.match()print(video_task.matches)# You can also add individual hashfiles to the comp_arrayvideo_task.comp.append(load(path_to_a_hashed_video.json))4. Using AliasesThe library assigns aliases to videos. The reference video has an alias namedref, while the videos to be compared against are namedcompare_n, wherenis the zero-indexed position of the video in the array. The library provides a methodget_by_aliaswhich allows selecting class objects by their aliases. Additionally, the class has a field, namedaliaseswhich shows the list of aliases in use for that instance.# import the classfromsimilar_vid.similar_secsimportSimilarif__name__=="__main__":# load videosvideo_task=Similar(ref=path_to_reference_video,comp_arr=[path_to_other_video_1,path_to_other_video_2,path_to_other_video_3])reference_by_alias=video_task.get_by_alias("ref")# selects the reference video object, if it exists.# The above is equivalent to:reference_directly=video_task.ref# list aliases, if anyprint(video_task.aliases)TODOsAdd ability to compare videos files to hashes directly..