keplerlab / katna

Tool for automating common video key-frame extraction, video compression and Image Auto-crop/Image-resize tasks
https://katna.readthedocs.io/
MIT License
313 stars 59 forks source link

Timestamp support for extracted frames #27

Open TheCodeYoda opened 2 years ago

TheCodeYoda commented 2 years ago

Is it possible to compute timestamp for extracted frames as frame metadata?

OB42 commented 12 months ago

up

ashiq-firoz commented 4 months ago

I have came up with a solution for this issue. What I did was to create a simple Writer class which will store timestamps in a writer object in place of saving the frames.

Remember this snippet from Katna Docs View Docs

# initialize diskwriter to save data at desired location
diskwriter = KeyFrameDiskWriter(location="selectedframes")

vd.extract_video_keyframes(
     no_of_frames=no_of_frames_to_returned, file_path=video_file_path,
     writer=diskwriter
)

I just replaced writer=diskwriter with my DummyWriter object.

And later when I need to use timestamps, I will call dummywriter.getTimeStamps() which will return timestamp list.

This is my DummyWriter Class which I used

class DummyWriter:
    def __init__(self):
        self.timestamps = []
        pass

    def write(self, path, frames):
        self.timestamps = get_timestamps_for_selected_frames(path, frames)
        # Could add code to save the frame

    def getTimeStamps(self):
        return self.timestamps

    def get_frame_timestamps(video_path):
        # Open the video file
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            print("Error: Could not open video.")
            return []

        # Get video properties
        fps = cap.get(cv2.CAP_PROP_FPS)
        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

        # Calculate timestamps
        timestamps = []
        for i in range(total_frames):
            timestamp = i / fps
            timestamps.append(timestamp)

        cap.release()
        return timestamps

    def get_timestamps_for_selected_frames(video_path, img_final):
        # Get timestamps for all frames in the video
        all_timestamps = get_frame_timestamps(video_path)

        # Open the video file again to read the frames
        cap = cv2.VideoCapture(video_path)
        selected_timestamps = []
        frame_index = 0

        for img in img_final:
            while cap.isOpened():
                ret, frame = cap.read()
                if not ret:
                    break
                if frame_index < len(all_timestamps) and (frame == img).all():
                    selected_timestamps.append(all_timestamps[frame_index])
                    break
                frame_index += 1

        cap.release()
        return selected_timestamps

# Sample usage with Katna
dummywriter = DummyWriter()

vd.extract_video_keyframes(
     no_of_frames=no_of_frames_to_returned, file_path=video_file_path,
     writer=dummywriter
)

print(f'Timestamps : {dummywriter.getTimeStamps()}')

Hope this is helpful 😇

31 #27