@@ -37,9 +37,6 @@ def video_info(video_path: str) -> Tuple[int, int, int]:
37
37
38
38
def extract_frames (video_file : str , timestamps_df : pd .DataFrame , output_dir : str ):
39
39
40
- #_, _, num_frames = video_info(video_file)
41
- #print("NUM:", num_frames, len(timestamps_df))
42
-
43
40
# Open the video file
44
41
cap = cv2 .VideoCapture (video_file )
45
42
if not cap .isOpened ():
@@ -50,20 +47,57 @@ def extract_frames(video_file: str, timestamps_df: pd.DataFrame, output_dir: str
50
47
51
48
# Loop over each timestamp in the CSV file
52
49
for fnum , timestamp in enumerate (timestamps ):
53
- # Extract the frame using OpenCV
54
- #cap.set(cv2.CAP_PROP_POS_MSEC, timestamp * 1000)
50
+ # Extract the next frame
55
51
ret , frame = cap .read ()
56
52
if ret :
57
53
frame_path = os .path .join (output_dir , str (timestamp ) + ".jpg" )
58
54
cv2 .imwrite (frame_path , frame )
55
+
59
56
else :
60
57
print (f"At frame { fnum } , no more frames to extract from video '{ video_file } '. Expected { len (timestamps )} frames." )
61
- #raise Exception(f"At frame {fnum}, no more frames to extract from video '{video_file}'. Expected {len(timestamps)} frames.")
62
-
58
+
63
59
# Release the video file
64
60
cap .release ()
65
61
66
62
63
+ def extract_frames_ffmpeg (video_file : str , timestamps_df : pd .DataFrame , output_dir : str ):
64
+ video_w , video_h , _ = video_info (video_file )
65
+
66
+ ffmpeg_read_process = (
67
+ ffmpeg
68
+ .input (video_file )
69
+ .output ('pipe:' , format = 'rawvideo' , pix_fmt = 'rgb24' )
70
+ .run_async (pipe_stdout = True )
71
+ )
72
+
73
+ first_col_name = timestamps_df .columns [0 ]
74
+ timestamps : pd .Series = timestamps_df [first_col_name ]
75
+
76
+ # Loop over each timestamp in the CSV file
77
+ for fnum , timestamp in enumerate (timestamps ):
78
+ in_bytes = ffmpeg_read_process .stdout .read (video_w * video_h * 3 )
79
+ if in_bytes :
80
+
81
+ in_frame = (
82
+ np
83
+ .frombuffer (in_bytes , np .uint8 )
84
+ .reshape ([video_h , video_w , 3 ])
85
+ )
86
+
87
+ frame_path = os .path .join (output_dir , str (timestamp ) + ".jpg" )
88
+ in_frame = cv2 .cvtColor (in_frame , cv2 .COLOR_RGB2BGR )
89
+ cv2 .imwrite (frame_path , in_frame )
90
+ #PIL.Image.fromarray(in_frame, 'RGB').save(frame_path)
91
+
92
+ else :
93
+ print (f"At frame { fnum } , no more frames to extract from video '{ video_file } '. Expected { len (timestamps )} frames." )
94
+
95
+ if ffmpeg_read_process is not None :
96
+ ffmpeg_read_process .stdout .close ()
97
+ ffmpeg_read_process .wait ()
98
+ ffmpeg_read_process = None
99
+
100
+
67
101
def rebuild_video (dir : Path , frames : pd .DataFrame , outfile : Path ) -> None :
68
102
69
103
# We don't know the target video size, yet.
@@ -102,7 +136,6 @@ def rebuild_video(dir: Path, frames: pd.DataFrame, outfile: Path) -> None:
102
136
#x=50, y=50,
103
137
x = "(w-tw)/2" , y = "h-(2*lh)" ,
104
138
fontfile = "Arial.ttf" , fontsize = font_width , fontcolor = "white" ,
105
- #boxcolor="0x00000099",
106
139
box = 1 ,
boxborderw = 2 ,
boxcolor = "[email protected] " )
107
140
108
141
.output (str (outfile ), pix_fmt = 'yuv420p' )
0 commit comments