You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现流畅全屏视频播放并同步执行代码

解决Python视频全屏播放卡顿、画面裁剪及同步执行代码问题

问题根源

  • 画面裁剪:cv2的cv2.namedWindow默认拉伸画面,未保持视频原比例;moviepy的preview逻辑未做比例适配,导致画面边缘被裁切。
  • 播放卡顿:单线程环境下视频渲染与代码执行互相阻塞,且cv2的waitKey帧率控制精度不足。
  • 同步执行:默认视频播放为阻塞式逻辑,必须通过多线程/多进程分离播放与业务代码。

解决方案(cv2+多线程)

核心思路

  1. 获取屏幕分辨率,计算视频适配后的全屏尺寸(保持原比例,用黑边填充空白区域)
  2. 用多线程分离视频播放与业务代码,实现同步运行

完整代码示例

import cv2
import threading
import ctypes
import numpy as np

# 获取屏幕分辨率
user32 = ctypes.windll.user32
screen_width = user32.GetSystemMetrics(0)
screen_height = user32.GetSystemMetrics(1)

def play_video_fullscreen(video_path):
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        print("无法打开视频文件")
        return
    
    # 获取视频基础参数
    video_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    video_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = cap.get(cv2.CAP_PROP_FPS)
    delay = int(1000 / fps) if fps > 0 else 30

    # 计算适配屏幕的尺寸(保持原比例,避免裁剪)
    scale = min(screen_width / video_width, screen_height / video_height)
    display_width = int(video_width * scale)
    display_height = int(video_height * scale)

    # 创建全屏窗口
    cv2.namedWindow("Video", cv2.WND_PROP_FULLSCREEN)
    cv2.setWindowProperty("Video", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        
        # 调整画面尺寸并居中填充黑边
        frame_resized = cv2.resize(frame, (display_width, display_height))
        top_pad = (screen_height - display_height) // 2
        left_pad = (screen_width - display_width) // 2
        full_frame = np.zeros((screen_height, screen_width, 3), dtype=np.uint8)
        full_frame[top_pad:top_pad+display_height, left_pad:left_pad+display_width] = frame_resized
        
        cv2.imshow("Video", full_frame)
        # 精准控制帧率,避免卡顿
        if cv2.waitKey(delay) & 0xFF == ord('q'):
            break
    
    cap.release()
    cv2.destroyAllWindows()

# 启动视频播放线程(守护线程,主程序结束自动退出)
video_thread = threading.Thread(target=play_video_fullscreen, args=("你的视频路径.mp4",))
video_thread.daemon = True
video_thread.start()

# 主线程同步执行业务代码
while True:
    print("hi")

关键优化点

  • 无裁剪全屏:通过比例计算+黑边填充,保持视频原画面比例,避免边缘裁切
  • 流畅播放:根据视频实际帧率设置waitKey延迟,精准控制播放速度
  • 同步执行:多线程分离播放逻辑与业务代码,两者互不阻塞

替代方案(pygame)

若cv2仍有卡顿,pygame对Windows视频播放兼容性更好,同样用多线程实现:

import pygame
import threading
import time

def play_video_pygame(video_path):
    pygame.init()
    screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
    screen_width, screen_height = screen.get_size()
    
    video = pygame.movie.Movie(video_path)
    video_width, video_height = video.get_size()
    
    # 计算适配比例
    scale = min(screen_width/video_width, screen_height/video_height)
    display_size = (int(video_width*scale), int(video_height*scale))
    # 设置视频显示位置(居中)
    video.set_display(screen, ((screen_width-display_size[0])//2, (screen_height-display_size[1])//2, display_size[0], display_size[1]))
    
    video.play()
    while video.get_busy():
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN and event.key == pygame.K_q:
                video.stop()
                pygame.quit()
                return
        time.sleep(0.01)
    pygame.quit()

# 启动播放线程
video_thread = threading.Thread(target=play_video_pygame, args=("你的视频路径.mp4",))
video_thread.daemon = True
video_thread.start()

# 主线程同步执行代码
while True:
    print("hi")

内容的提问来源于stack exchange,提问作者mrithul e

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:42:54