def test_model_conversion(self): original = Path(Path.cwd() / 'static/videos/archive/panorama_augusti_1944.mp4') assert original.exists() output_directory = Path.cwd() / "interim" video_path = ffmpeg.slice( original, '00:00:30', '00:00:02', output_directory, overwrite=True ) assert video_path.exists() root_output_directory = Path.cwd() / "interim" fps = extract_fingerprint_collection(video_path, root_output_directory) # Convert the fingerprint into our database representation and back # again, compare for equality fpc = fps[0] assert fpc.orb is not None model = FingerprintCollectionModel.from_fingerprint_collection(fpc) restored = model.to_fingerprint_collection() self.assertTrue(np.array_equal(fpc.thumbnail.image, restored.thumbnail.image)) cc_similarity = fpc.color_correlation.similar_to(restored.color_correlation) self.assertTrue(cc_similarity == 1.0) self.assertEqual(fpc.video_name, restored.video_name) self.assertEqual(fpc.segment_id, restored.segment_id) self.assertTrue(fpc.orb.similar_to(restored.orb) > 0.99)
# To discern how long it takes to segment a single video, we utilise the profiling utility `timeit`, # %% from video_reuse_detector.profiling import timeit from video_reuse_detector.segment import segment import video_reuse_detector.ffmpeg as ffmpeg @timeit def __segment__(input_video, output_directory): return segment(input_video, output_directory / input_video.stem) # As this is merely to showcase how to benchmark the segment function, we extract a # short video to cut down on execution time. OUTPUT_DIRECTORY = Path(os.environ['OUTPUT_DIRECTORY']) INTERIM_DIRECTORY = Path(os.environ['INTERIM_DIRECTORY']) example_video = ffmpeg.slice(videos[0], "00:00:00", "00:00:05", OUTPUT_DIRECTORY) _, execution_time = __segment__(example_video, INTERIM_DIRECTORY) execution_time # %% [markdown] # Then, to record the time it takes to segment each video we have, # %% def benchmark_segmentation(videos, segment_length): benchmarks = {} videos_benchmarked = 1 for video_path in videos: print(f'Segmenting {video_path} ({videos_benchmarked}/{len(videos)})')
VIDEO_DIRECTORY = Path(os.environ['VIDEO_DIRECTORY']) assert (VIDEO_DIRECTORY.exists()) print(f'VIDEO_DIRECTORY={VIDEO_DIRECTORY}') # %% [markdown] # And then have a look at our reference video, # %% from IPython.display import Video import video_reuse_detector.ffmpeg as ffmpeg reference_video_path = VIDEO_DIRECTORY / 'ATW-644.mp4' assert (reference_video_path.exists()) OUTPUT_DIRECTORY = Path(os.environ['OUTPUT_DIRECTORY']) reference_video_path = ffmpeg.slice(reference_video_path, "00:00:30", "00:00:05", OUTPUT_DIRECTORY) assert (reference_video_path.exists()) print(f'reference_video_path={reference_video_path}') # Video expects a relative path in relation to the notebook rel_path = reference_video_path.relative_to(Path.cwd()) Video(str(rel_path)) # %% [markdown] # And use the same video as our query video, # %% query_video_path = reference_video_path assert (query_video_path.exists()) print(f'query_video_path={query_video_path}') assert (query_video_path == reference_video_path)
# We begin first by loading a video that we can perform our operations on, # %% import os from pathlib import Path from IPython.display import Video import video_reuse_detector.ffmpeg as ffmpeg VIDEO_DIRECTORY = Path(os.environ['VIDEO_DIRECTORY']) video_path = VIDEO_DIRECTORY / 'panorama_augusti_1944.mp4' assert(video_path.exists()) OUTPUT_DIRECTORY = Path(os.environ['OUTPUT_DIRECTORY']) video_path = ffmpeg.slice(video_path, "00:01:30", "00:01:00", OUTPUT_DIRECTORY) assert(video_path.exists()) # Video expects a relative path in relation to the notebook Video(str(video_path.relative_to(Path.cwd()))) # %% [markdown] # Regardless of segmenting the video or not, we want that the frames we extract to be evenly distributed from each second of video. To see that we accomplish this, we extract all the frames from the video, # %% import cv2 vidcap = cv2.VideoCapture(str(video_path)) success, image = vidcap.read() frame_index = 0
video_selection = video_selector(default=str(VIDEO_DIRECTORY / 'panorama_augusti_1944.mp4')) display(video_selection) # %% [markdown] # To make the output of the remaining steps easy to grasp we extract a slice of the input video # %% import video_reuse_detector.ffmpeg as ffmpeg input_file = Path(video_selection.value) assert (input_file.exists()) OUTPUT_DIRECTORY = Path(os.environ['OUTPUT_DIRECTORY']) input_file = ffmpeg.slice(input_file, "00:00:30", "00:00:10", OUTPUT_DIRECTORY) assert (input_file.exists()) # %% [markdown] # And in-case something goes wrong, we output some information about the input file to make debugging/error-reporting easy, # %% from video_reuse_detector.ffmpeg import get_video_duration, get_video_dimensions import math video_duration = get_video_duration(input_file) print(video_duration) print(get_video_dimensions(input_file)) # %% [markdown] # The extracted video segments are downsampled by extracting individual frames from it,
# Uploading a file will trigger fingerprint computation eventually, and # assuming the application is not under load, it will happen immediately VIDEO_DIRECTORY = Path(os.environ['VIDEO_DIRECTORY']) assert VIDEO_DIRECTORY.exists() print(f"VIDEO_DIRECTORY={VIDEO_DIRECTORY}") OUTPUT_DIRECTORY = Path(os.environ['OUTPUT_DIRECTORY']) print(f"OUTPUT_DIRECTORY={OUTPUT_DIRECTORY}") # This video might be uploaded already, so we should create a copy with a different name. # This is because the backend checks for "uniqueness" of videos by referring to the # filename (post-sanitation) reference_video_path = VIDEO_DIRECTORY / 'panorama_augusti_1944.mp4' assert (reference_video_path.exists()) to_benchmark = ffmpeg.slice(reference_video_path, "00:01:30", "00:02:00", OUTPUT_DIRECTORY) assert (to_benchmark.exists()) extension = reference_video_path.suffix # contains the leading "." before the extension print(f"extension={extension}") timestamp = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M') print(f"timestamp={timestamp}") # We'll store the copy there, this is the target path to_be_uploaded = OUTPUT_DIRECTORY / f"{to_benchmark.stem}_{timestamp}{extension}" # Copy the file from the original path to the target path shutil.copy(str(to_benchmark), str(to_be_uploaded)) # %% [markdown]