该文章的原创地址: 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 sysdef get_total_video_time(frame_count, fps):return (frame_count / fps) * 1000def 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 = 0text_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 += 1current_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()