繁体   English   中英

Python 多线程求助! 视频显示/捕捉

[英]Python Multithreading Help! Video Display/Capture

我正在尝试同时:

  1. 在屏幕上显示保存的视频(持续时间 60 秒)
  2. 捕获计算机网络摄像头视频并保存到文件。 (持续时间 60 秒,从保存的视频开始播放到屏幕开始)

我曾尝试使用多线程来处理这个问题,但遇到了一个问题,即 Thread1 (func1) 立即将视频广播到屏幕上,而 Thread 2 (func2) 可能需要 10-20 秒(由于某种原因而有所不同)才能开始捕获视频。 (a sleep() function 由于不可预测性而无济于事)。 认为我需要暂停/恢复第一个线程以等待第二个线程开始捕获视频。 或者,让第二个线程触发第一个线程。

import pyglet
import numpy as np
import cv2
import time
from threading import Thread

from screeninfo import get_monitors

for monitor in get_monitors():
    width = monitor.width
    height = monitor.height

def func1():
    vid_path='path/to/video'
    window= pyglet.window.Window(width, height, fullscreen=True)
    player = pyglet.media.Player()
    source = pyglet.media.StreamingSource()
    MediaLoad = pyglet.media.load(vid_path)
    
    player.queue(MediaLoad)
    player.play()
    @window.event
    def on_draw():
        if player.source and player.source.video_format:
            player.get_texture().blit(0,0)
    pyglet.app.run()

def func2():
    capture_duration = 60                                         #This portion of code
    cap = cv2.VideoCapture(0)                                     #takes about 10 seconds to 
    fourcc = cv2.VideoWriter_fourcc(*'XVID')                      #execute causing a time dif
    out = cv2.VideoWriter('output.avi',fourcc, 30.0, (640,480))   #btw video play and 
    start_time = time.time()                                      #capture
    while( int(time.time() - start_time) < capture_duration ):
        ret, frame = cap.read()
        if ret==True:
            out.write(frame)
        else:
            break

    # Release everything if job is finished
    cap.release()
    out.release()
    cv2.destroyAllWindows()
    
if __name__ == '__main__':
    Thread(target = func1).start()
    Thread(target = func2).start()

只需使用threading.Event来同步两个线程。

  1. 创建threading.Event实例
  2. 将实例传递给两个线程
  3. 在等待侧调用.wait() ,在另一侧调用.set()

例子:

import threading
import time


def takes_long(event: threading.Event):
    time.sleep(5)
    print("[Long ] Started!")
    event.set()


def takes_short(event: threading.Event):
    print("[Short] Waiting for other thread!")
    event.wait()
    print("[Short] Started!")


event_ = threading.Event()
threading.Thread(target=takes_long, args=[event_]).start()
threading.Thread(target=takes_short, args=[event_]).start()
[Short] Waiting for other thread!
[Long ] Started!
[Short] Started!

应用代码:

import time
import threading

import pyglet
import cv2


# hard-coding for simplification
WIDTH, HEIGHT = 2560, 1440
DURATION = 10

# source / output path
SOURCE_PATH = "./sample.mp4"
OUTPUT_PATH = "X:/Temp/output.avi"


def func1(started_event: threading.Event):
    """Waits for func2 then plays the video for fixed duration"""

    window = pyglet.window.Window(WIDTH, HEIGHT, fullscreen=True)
    player = pyglet.media.Player()
    media = pyglet.media.load(SOURCE_PATH)
    player.queue(media)

    # wait for event then play
    started_event.wait()
    player.play()

    @window.event
    def on_draw():
        if player.source and player.source.video_format:
            player.get_texture().blit(0, 0)

    pyglet.app.run()


def func2(started_event: threading.Event):
    cap = cv2.VideoCapture(0)
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter(OUTPUT_PATH, fourcc, 30.0, (640, 480))

    # now all required steps are done, fire event so video playback can start
    started_event.set()

    # now start capturing
    start_time = time.time()

    while (time.time() - start_time) < DURATION:
        ret, frame = cap.read()
        if ret:
            out.write(frame)
        else:
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()
    pyglet.app.exit()


if __name__ == '__main__':
    event = threading.Event()

    threading.Thread(target=func1, args=(event,)).start()
    threading.Thread(target=func2, args=(event,)).start()

这应该等到它准备好,并在捕获后退出 pyglet。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM