该文章的原创地址: https://bbs.huaweicloud.com/blogs/444240
1. 安装 opencv-python
pip install opencv-python
2. 代码逻辑
- 使用 opencv 读取视频文件
import cv2
import sys
# 使用 cv 打开视频文件
cap = cv2.VideoCapture("./test.mp4")
# 检查视频文件是否呈贡打开
if not cap.isOpened():
print("failed to open the video file", file=sys.stderr)
sys.exit(1)
# 持续读取视频每一帧
while True:
# ret 是读取结果, frame 是视频的每一帧
ret, frame = cap.read()
# 如果读取失败
if not ret:
print("read video file to end", file=sys.stderr)
break
# 显示视频
# 第一个参数是窗口名称, 第二个参数是视频帧
cv2.imshow("test.mp4", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
- 获取视频属性
# 获取视频 FPS
fps = cap.get(cv2.CAP_PROP_FPS)
# 获取视频尺寸
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 获取视频总帧数
total_frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 获取当前帧的时间, 毫秒
current_frame_time = (cap.get(cv2.CAP_PROP_POS_MSEC))
- 获取视频总时长
def get_total_video_time(frame_count, fps):
(frame_count / fps) * 1000
- 转换帧时间为字符串
def milliseconds_to_time_str(milliseconds)
# 将毫秒转换为秒
seconds = milliseconds / 1000
# 计算小时数
hours = int(seconds // 3600)
seconds %= 3600
# 计算分钟数
minutes = int(seconds // 60)
seconds %= 60
# 返回格式化的时间字符串
return f"{hours:02}:{minutes:02}:{seconds:06.3f}"
- 绘制水印
# 总视频时长
total_video_time = get_total_video_time(total_frame_count, fps)
# 总视频时长字符串
total_video_time_str = milliseconds_to_time_str(total_video_time)
# 当前视频时间字符串
current_frame_time_str = milliseconds_to_time_str(current_frame_time)
# 绘制一个背景
rect_pos_1 = (0, frame_height)
rect_pos_2 = (460, frame_height - 70)
cv2.rectangle(frame, rect_pos_1, rect_pos_2, (25, 25, 25), cv2.FILLED)
# 绘制帧进度
text_pos_1 = (5, frame_height - 40)
text = f"{frame_count:05}/{total_frame_count}"
cv2.putText(frame, text, text_pos_1, cv2.FONT_HERSHEY_DUPLEX ,1, (255, 255, 255), 1)
# 绘制时间进度
text_pos_2 = (5, frame_height - 5)
text = f"{time_str}/{total_time_str}"
cv2.putText(frame, text, text_pos_2, cv2.FONT_HERSHEY_DUPLEX ,1, (255, 255, 255), 1)
- 保存视频
# 打开视频写
writer = cv2.VideoWriter("./output.mp4")
# 写出帧到视频文件
writer.write(frame)
# 释放写
writer.release()
3. 完整代码
import cv2
import sys
def get_total_video_time(frame_count, fps):
return (frame_count / fps) * 1000
def milliseconds_to_time_str(milliseconds):
# 将毫秒转换为秒
seconds = milliseconds / 1000
# 计算小时数
hours = int(seconds // 3600)
seconds %= 3600
# 计算分钟数
minutes = int(seconds // 60)
seconds %= 60
# 返回格式化的时间字符串
return f"{hours:02}:{minutes:02}:{seconds:06.3f}"
def main(input_video, output_video):
cap = cv2.VideoCapture(input_video)
if not cap.isOpened():
print(f"failed to open the video file, video_file={input_video}", file=sys.stderr)
sys.exit(1)
fps = cap.get(cv2.CAP_PROP_FPS)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
total_frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
total_video_time = get_total_video_time(total_frame_count, fps)
total_video_time_str = milliseconds_to_time_str(total_video_time)
frame_index = 0
text_pos_1 = (5, frame_height - 40)
text_pos_2 = (5, frame_height - 5)
rect_pos_1 = (0, frame_height)
rect_pos_2 = (460, frame_height - 70)
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
writer = cv2.VideoWriter(output_video, fourcc, fps, (frame_width, frame_height))
while True:
ret, frame = cap.read()
if not ret:
print("read to end of video", file=sys.stderr)
sys.exit(1)
frame_index += 1
current_time = cap.get(cv2.CAP_PROP_POS_MSEC)
current_time_str = milliseconds_to_time_str(current_time)
cv2.rectangle(frame, rect_pos_1, rect_pos_2, (25, 25, 25), cv2.FILLED)
text = f"{frame_index:05}/{total_frame_count}"
cv2.putText(frame, text, text_pos_1, cv2.FONT_HERSHEY_DUPLEX, 1, (255, 255, 255), 1)
text = f"{current_time_str}/{total_video_time_str}"
cv2.putText(frame, text, text_pos_2, cv2.FONT_HERSHEY_DUPLEX, 1, (255, 255, 255), 1)
writer.write(frame)
writer.release()
cap.release()
cv2.destroyAllWindows()
标签:视频,frame,cap,cv2,水印,OpenCV,video,time,total
From: https://www.cnblogs.com/Annlix/p/18645934/add_video_watermark_use_opencv