I have a mp4/avi videos with duration 10 minutes and FPS 30. I want to reduce duration to 5 mins but FPS still 30. It means that the new videos will drop a half of frame (for example, f0 f2 f4
compare with original video f0 f1 f2 f3 f4
). How can I do it on opencv? This is current code to get duration and FPS of the video.
# import module
import cv2
import datetime
# create video capture object
data = cv2.VideoCapture('C:/Users/Asus/Documents/videoDuration.mp4')
# count the number of frames
frames = data.get(cv2.CAP_PROP_FRAME_COUNT)
fps = data.get(cv2.CAP_PROP_FPS)
# calculate duration of the video
seconds = round(frames / fps)
video_time = datetime.timedelta(seconds=seconds)
print(f"duration in seconds: {seconds}")
print(f"video time: {video_time}")
CodePudding user response:
Read frames from the capture, keeping track of how many you've read, and write only every Nth frame, like so:
from itertools import count
import cv2
in_video = cv2.VideoCapture("example.mp4")
frames = int(in_video.get(cv2.CAP_PROP_FRAME_COUNT))
fps = in_video.get(cv2.CAP_PROP_FPS)
w = int(in_video.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(in_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"{frames=}, {fps=}, {w=}, {h=}")
out_video = cv2.VideoWriter("out.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
frames_written = 0
every_nth = 2
for frame_num in count(0):
ret, frame = in_video.read()
if not ret: # out of frames
break
if frame_num % every_nth == 0:
out_video.write(frame)
frames_written = 1
print(f"{frames_written=}")
CodePudding user response:
This code will read the input video file, frame by frame, and write every other frame to the output video file. As a result, the output video will have half the number of frames as the input video and therefore, half the duration.
import cv2
# Open the input video file
cap = cv2.VideoCapture("input.mp4")
# Check if the video is opened successfully
if not cap.isOpened():
print("Error opening video file")
# Read the video's width, height, and frame rate
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
# Create the output video file
out = cv2.VideoWriter("output.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
# Read the frames from the input video and write them to the output video,
# skipping every other frame
while True:
ret, frame = cap.read()
if not ret:
break
cap.grab()
out.write(frame)
# Release the video capture and video write objects
cap.release()
out.release()