Skip to content

Instantly share code, notes, and snippets.

@otakbeku
Last active August 24, 2021 17:36
Show Gist options
  • Select an option

  • Save otakbeku/896165e19da80415bc764611aa438cce to your computer and use it in GitHub Desktop.

Select an option

Save otakbeku/896165e19da80415bc764611aa438cce to your computer and use it in GitHub Desktop.
Video frame extractor
import cv2
from datetime import timedelta
import time
# Manual timestamp extractor
def get_frame_from_timestamp(filepath, timestamp):
str_timestamp = time.strptime(timestamp,'%H:%M:%S')
exact_time = timedelta(hours=str_timestamp.tm_hour,minutes=str_timestamp.tm_min,seconds=str_timestamp.tm_sec).total_seconds()
cap = cv2.VideoCapture(filepath)
camtime = cap.get(cv2.CAP_PROP_POS_MSEC)/1000
frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)
duration = frame_count/fps
assert exact_time<duration, '[Exceed Video Duration Error] The given timestamp is longer than the actual length of the video'
frame_skipping = (exact_time)*fps
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_skipping)
while camtime <= exact_time:
ret, frame = cap.read()
# Capture frame in milliseconds
camtime = cap.get(cv2.CAP_PROP_POS_MSEC)/1000
return ret, frame
# Constant timeskip extractor
def get_constant_interval_frame(filepath, step, start_timestamp, end_timestamp):
start_timestamp = time.strptime(start_timestamp,'%H:%M:%S')
end_timestamp = time.strptime(end_timestamp,'%H:%M:%S')
exact_start_time = timedelta(hours=start_timestamp.tm_hour,minutes=start_timestamp.tm_min,seconds=start_timestamp.tm_sec).total_seconds()
exact_end_time = timedelta(hours=end_timestamp.tm_hour,minutes=end_timestamp.tm_min,seconds=end_timestamp.tm_sec).total_seconds()
assert start_timestamp<end_timestamp, '[Start Timestamp Error] The start timestamp exceed end timestamp'
cap = cv2.VideoCapture(filepath)
camtime = cap.get(cv2.CAP_PROP_POS_MSEC)/1000
frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)
duration = frame_count/fps
assert exact_end_time<duration, '[Exceed Video Duration Error] The given timestamp is longer than the actual length of the video'
frame_skipping = (exact_start_time)*fps
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_skipping)
frames = []
duration_time = str(timedelta(seconds=duration))
print(f'Total duration: {duration:.2f} sec ({duration_time})')
while camtime <= exact_end_time:
ret, frame = cap.read()
# Capture frame in milliseconds
camtime = cap.get(cv2.CAP_PROP_POS_MSEC)/1000
video_timestamp = str(timedelta(seconds=camtime))
frames.append((ret, frame, video_timestamp))
step_frame_skipping = (camtime+step)*fps
cap.set(cv2.CAP_PROP_POS_FRAMES, step_frame_skipping)
return frames
@otakbeku
Copy link
Author

otakbeku commented Aug 24, 2021

get_frame_from_timestamp: return ret & frame. Ret: metadata true/false. frame: opencv image format
get_constant_interval_frame: return list, contains ret, frame, and video_timestamp.

@otakbeku
Copy link
Author

Example:
step: in seconds
timestamp format: HH:MM:SS
frames = get_constant_interval_frame(long_filepath, 10, '00:00:00', '00:10:00')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment