I'm reading a video from YouTube(for testing purpose. real case would be from a video camera feed) and take each frame and inject a logo on it and create another video using those frames. Also I need to save these frames as images as well(which is already works for me). I tried the following,
img = cv2.imread('logo.png')
img_height, img_width, _ = img.shape
url = "https://www.youtube.com/watch?v=vDHtypVwbHQ"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
frame_no = 1
width = 1280
hieght = 720
fps = 30
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
videoW = cv2.VideoWriter('image_to_video.mp4', fourcc, float(fps), (width, hieght))
while True:
_, frame = video.read()
frame[y:y img_height , x:x img_width ] = img
videoW.write(frame)
frame_no = 1
This writes a video but it says the video corrupted or incorrect extension. What would be the best way to write these frames into a new video in Python with OpenCV?
CodePudding user response:
There are many illogical things in the implementation such as "video" is a pafy.Stream that does not have a read method.
What you should do use the Stream url together with VideoCapture to obtain the frames, copy the pixels of the logo, and write it with VideoWriter.
import cv2
import pafy
def apply_logo(url, logo, filename):
video = pafy.new(url)
best = video.getbest(preftype="mp4")
reader = cv2.VideoCapture(best.url)
if not reader.isOpened():
return False
fourcc = cv2.VideoWriter_fourcc(*"MP4V")
writer = cv2.VideoWriter(filename, fourcc, 60.0, best.dimensions)
logo_width, logo_height = [min(x, y) for x, y in zip(best.dimensions, logo.shape)]
i = 0
while True:
ret, frame = reader.read()
if ret:
frame[:logo_width, :logo_height] = logo[:logo_width, :logo_height]
writer.write(frame)
i = 1
print(i)
else:
break
reader.release()
writer.release()
return True
url = "https://www.youtube.com/watch?v=vDHtypVwbHQ"
logo = cv2.imread("logo.png")
apply_logo(url, logo, "output.mp4")