当我尝试播放.mp4文件时,VideoWriter创建的.mp4文件会出现错误,说“此文件不可播放。这可能是因为文件类型不受支持,文件扩展名不正确,或者文件已损坏。
我试着将我的VideoWriter设置移动到我的其他文件,只是为了看看,我有同样的结果。我是OpenCV和Numpy的新手,所以我不知道该怎么做。
这是我的main.py文件中的代码:
import cv2 as cv
import numpy as np
from time import time
import datetime
from windowcapture import WindowCapture
wincap = WindowCapture('Geometry Dash')
time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
fourcc = cv.VideoWriter_fourcc('m', 'p', '4', 'v')
file_name = f'{time_stamp}.mp4'
captured_video = cv.VideoWriter(file_name, fourcc, 60.0, (800, 600))
loop_time = time()
while True:
screenshot = wincap.get_screenshot()
# prints the video fps
print('FPS {:.2f}'.format(1 / (time() - loop_time)))
loop_time = time()
cv.imshow('Screen Capture', screenshot)
captured_video.write(screenshot)
# press 'q' with output window focused to close window
# waits 1ms every loop to process if q is pressed
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
print('q pressed // window closing')
这是我的windowcapture.py文件中的代码:
import numpy as np
import win32gui, win32ui, win32con
class WindowCapture:
# properties
w = 0
h = 0
hwnd = None
cropped_x = 0
cropped_y = 0
offset_x = 0
offset_y = 0
# constructor
def __init__(self, window_name):
self.hwnd = win32gui.FindWindow(None, window_name)
if not self.hwnd:
raise Exception('Window not found "{}"'.format(window_name))
# get window size
window_rect = win32gui.GetWindowRect(self.hwnd)
self.w = window_rect[2] - window_rect[0]
self.h = window_rect[3] - window_rect[1]
# account for window border and titlebar and cut them off
border_pixels = 8
titlebar_pixels = 30
self.w = self.w - (border_pixels * 2)
self.h = self.h - titlebar_pixels - border_pixels
self.cropped_x = border_pixels
self.cropped_y = titlebar_pixels
# set the cropped coordinates offset so we can translate screenshot
# images into actual screen positions
self.offset_x = window_rect[0] + self.cropped_x
self.offset_y = window_rect[1] + self.cropped_y
def get_screenshot(self):
# get the window image data
wDC = win32gui.GetWindowDC(self.hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)
# saves the screenshot
#dataBitMap.SaveBitmapFile(cDC, 'debug.bmp')
signedIntsArray = dataBitMap.GetBitmapBits(True)
img = np.frombuffer(signedIntsArray, dtype='uint8')
img.shape = (self.h, self.w, 4)
# Free Resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(self.hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
# make image C_CONTIGUOUS to avoid errors like:
# File ... in draw_rectangles
# TypeError: an integer is required (got type tuple)
# github discussion:
# https://github.com/opencv/opencv/issues/14866#issuecomment-580207109
img = np.array(img)
return img
# find the name of the window you're interested in.
# once you have it, update window_capture()
# https://stackoverflow.com/questions/55547940/how-to-get-a-list-of-the-name-of-every-open-window
def list_window_names(self):
def winEnumHandler(hwnd, ctx):
if win32gui.IsWindowVisible(hwnd):
print(hex(hwnd), win32gui.GetWindowText(hwnd))
win32gui.EnumWindows(winEnumHandler, None)
#list_window_names()
# translate a pixel position on a screenshot image to a pixel position on the screen.
# pos = (x,y)
# WARNING: if you move the window being captured after execution is started, this will
# return incorrect coordinates, because the window position is only calculated in
# the __init__ constructor.
def get_screen_position(self, pos):
return (pos[0] + self.offset_x, pos[1] + self.offset_y)
'''
I have no problem viewing my video when I have my game open it plays perfectly fine in the window that pops up from opencv but when I try to save this video to mp4 the video does not work.
1条答案
按热度按时间gc0ot86w1#
这可能是对我的问题的一个暂时的回答,因为这并不是真正感觉到解决这个问题的“正确”方法,但这就是我所做的。
在我的main.py我改变了
我已经将此代码更改为
然后在我的windowcapture.py文件中,
现在我把它改成了
剩下的代码我已经离开了,我现在得到我的mp4文件播放。第一个变化,我注意到从我做的测试是我需要设置我的VideoWriter正确的屏幕大小,因为我有它在800,600时,窗口是1600,900。第二个变化是颜色转换如果我只转换到BGR的代码工作,但显然我不希望它在BGR我希望它在RGB,所以我必须转换回来,但如果我不这样做至少一个转换的mp4将无法播放。