|
@@ -0,0 +1,103 @@
|
|
|
+import cv2
|
|
|
+import numpy as np
|
|
|
+import subprocess
|
|
|
+import json
|
|
|
+import time
|
|
|
+
|
|
|
+
|
|
|
+def get_video_dimensions(video_path):
|
|
|
+ """ 获取视频的宽高信息 """
|
|
|
+ command = [
|
|
|
+ 'ffprobe',
|
|
|
+ '-v', 'error',
|
|
|
+ '-select_streams', 'v:0',
|
|
|
+ '-show_entries', 'stream=width,height',
|
|
|
+ '-of', 'json',
|
|
|
+ video_path
|
|
|
+ ]
|
|
|
+ result = subprocess.run(command, capture_output=True, text=True)
|
|
|
+ info = json.loads(result.stdout)
|
|
|
+ width = info['streams'][0]['width']
|
|
|
+ height = info['streams'][0]['height']
|
|
|
+ return width, height
|
|
|
+
|
|
|
+
|
|
|
+def get_video_fps(video_path):
|
|
|
+ command = [
|
|
|
+ 'ffprobe',
|
|
|
+ '-v', 'error',
|
|
|
+ '-select_streams', 'v:0',
|
|
|
+ '-show_entries', 'stream=r_frame_rate',
|
|
|
+ '-of', 'json',
|
|
|
+ video_path
|
|
|
+ ]
|
|
|
+ result = subprocess.run(command, capture_output=True, text=True)
|
|
|
+ info = json.loads(result.stdout)
|
|
|
+ rate = info['streams'][0]['r_frame_rate']
|
|
|
+ num, denom = map(int, rate.split('/'))
|
|
|
+ return num / denom
|
|
|
+
|
|
|
+
|
|
|
+def decode_and_display_video_with_ffmpeg(video_path):
|
|
|
+ width, height = get_video_dimensions(video_path)
|
|
|
+ frame_size = width * height * 3
|
|
|
+ fps = get_video_fps(video_path)
|
|
|
+ frame_delay = 1.0 / fps
|
|
|
+
|
|
|
+ command = [
|
|
|
+ 'ffmpeg',
|
|
|
+ '-hwaccel', 'cuda',
|
|
|
+ '-i', video_path,
|
|
|
+ '-f', 'rawvideo',
|
|
|
+ '-pix_fmt', 'bgr24',
|
|
|
+ '-vsync', '2',
|
|
|
+ '-'
|
|
|
+ ]
|
|
|
+
|
|
|
+ print("Starting FFmpeg process...")
|
|
|
+ video_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=10 ** 8)
|
|
|
+
|
|
|
+ try:
|
|
|
+ last_frame_time = time.time()
|
|
|
+ while True:
|
|
|
+ start_time = time.time()
|
|
|
+
|
|
|
+ in_bytes = video_process.stdout.read(frame_size)
|
|
|
+ if not in_bytes:
|
|
|
+ print("Video ended.")
|
|
|
+ break
|
|
|
+
|
|
|
+ frame = np.frombuffer(in_bytes, np.uint8).reshape((height, width, 3))
|
|
|
+ cv2.imshow('Video', frame)
|
|
|
+
|
|
|
+ current_time = time.time()
|
|
|
+ elapsed_time = current_time - last_frame_time
|
|
|
+ delay = frame_delay - elapsed_time
|
|
|
+
|
|
|
+ if delay > 0:
|
|
|
+ time.sleep(delay)
|
|
|
+
|
|
|
+ processing_time = time.time() - start_time
|
|
|
+ print(f"Processing time for the frame: {processing_time:.4f} seconds")
|
|
|
+
|
|
|
+ last_frame_time = current_time
|
|
|
+
|
|
|
+ # Check for 'q' key press
|
|
|
+ key = cv2.waitKey(1)
|
|
|
+ if key & 0xFF == ord('q'):
|
|
|
+ print("Exiting on user request.")
|
|
|
+ break
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f"An error occurred: {e}")
|
|
|
+
|
|
|
+ finally:
|
|
|
+ video_process.stdout.close()
|
|
|
+ video_process.stderr.close()
|
|
|
+ video_process.terminate()
|
|
|
+ video_process.wait()
|
|
|
+ cv2.destroyAllWindows()
|
|
|
+
|
|
|
+
|
|
|
+video_path = 'E:/BaiduNetdiskDownload/out.avi'
|
|
|
+decode_and_display_video_with_ffmpeg(video_path)
|