Reputation: 183
(Using OpenCV 4.1)
I am trying to capture screenshots from videos. My intention is to have the script capture a frame every five minutes up to 20 captures.
My test video is 20 minutes long. Once the script loops 4 times, I want it to quit. However, it loops a 5th time and captures 2 seconds from the end of the video. Then it loops a 6th time and captures the same frame as the 4th loop. It keeps repeating these last two loops until there are 20 frames captured.
How do I get the script to recognize that it has reached the end of the video and stop?
Note: the last frame captured may not be the last frame in the video. For example, if the video is 23 minutes long, the last frame captured should be near the 20-minute mark.
import datetime
import sys
import time
from cv2 import cv2
def milsec_to_hr_min_sec(milliseconds): # Returned from CAP_PROP_POS_MSEC
ms = int(milliseconds)
seconds = str(int((ms / 1000) % 60))
minutes = str(int((ms / (1000 * 60)) % 60))
hours = str(int((ms / (1000 * 60 * 60)) % 24))
return hours, minutes, seconds
def FrameCapture(path): # Extract frame
cap = cv2.VideoCapture(path)
framerate = cap.get(cv2.CAP_PROP_FPS)
count = 1
framecount = 0
# checks whether frames were extracted
while True:
while count < 21 and framecount < cap.get(cv2.CAP_PROP_FRAME_COUNT):
# Capture frame every 5 minutes
framecount = count * framerate * 60 * 5
cap.set(1, framecount)
# capture frame at timestamp
success, image = cap.read()
if success:
cv2.imwrite(
path + " (screencap #%d).jpg" % count, image,
)
# Convert timestamp to hr:min:sec
hours, minutes, seconds = milsec_to_hr_min_sec(
cap.get(cv2.CAP_PROP_POS_MSEC)
)
print(
str(success)
+ " "
+ "Captured: screencap #{} at timestamp ".format(count)
+ hours
+ "h "
+ minutes
+ "m "
+ seconds
+ "s"
)
count += 1
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
print("Finished capture")
# Driver Code
if __name__ == "__main__":
# Calling the function
fn = "\\full\path\to\file"
FrameCapture(fn)
Please forgive the hack-y nature of my scripts. I pieced them together with parts found from searches.
Upvotes: 2
Views: 8295
Reputation: 1
A simple way is:
sucess, img = cap.read()
if img is None:
print(' Successful process ')
break
You just have to add this line and process will be ended if 'cap' is empty
Upvotes: 0
Reputation: 71
At the beginning of the "while" loop you may use the following code:
ret, frames = cap.read()
if frames is None:
break
Upvotes: 2
Reputation: 1
This code will get all frames from your video
def get_list_frame_by_video(file_path_video):
vs = cv2.VideoCapture(file_path_video)
list_frame = []
print("____start load video____")
len_frames = int(vs.get(cv2.CAP_PROP_FRAME_COUNT))
while True:
is_cap, frame = vs.read()
if frame is None:
continue
list_frame.append(frame)
if len_frames == len(list_frame):
break
print("____complete load video____")
return list_frame
Upvotes: 0
Reputation: 19
There are two ways of doing it:
while(true)
loop and break
when frame.empty()
.int nFrames = vid_cap.get(CAP_PROP_FRAME_COUNT); //Get the number of frames avaiable in the video
and use a for_loop
to loop through the frames. Upvotes: 0