I had a problem using winrt.windows.graphics.capture!
Lookforworld opened this issue · 16 comments
My code like this:
from winrt.windows.graphics.capture import GraphicsCapturePicker
async def get_item():
picker = GraphicsCapturePicker()
item = await picker.pick_single_item_async()
return item
When I want to use get_item(), it doesn't pop up any window for me to select something!
Am I using it wrong? @dlech
To expand on this issue, GraphicsCapturePicker().pick_single_item_async()
throws a RuntimeError
.
Reproduction Code:
import asyncio
from winrt.windows.graphics.capture import Direct3D11CaptureFramePool, Direct3D11CaptureFrame, GraphicsCaptureSession, \
GraphicsCaptureItem, GraphicsCapturePicker
if not GraphicsCaptureSession.is_supported():
print('Not supported.')
else:
print('Supported.')
async def getGraphicsCaptureItem():
picker: GraphicsCapturePicker = GraphicsCapturePicker()
item: GraphicsCaptureItem = await picker.pick_single_item_async()
asyncio.run(getGraphicsCaptureItem())
Is there possibly going to be a fix for this?
I don't know anything about these APIs or how they are supposed to be used, but if you use one of my builds, it should give a more descriptive OSError
instead of a RuntimeError
that may help narrow down the problem.
I don't know anything about these APIs or how they are supposed to be used, but if you use one of my builds, it should give a more descriptive
OSError
instead of aRuntimeError
that may help narrow down the problem.
Sorry if I'm mistaken, but aren't your builds failing? That's what I see according to the CI. 🤔
I don't know anything about these APIs or how they are supposed to be used, but if you use one of my builds, it should give a more descriptive
OSError
instead of aRuntimeError
that may help narrow down the problem.
Still no ideas......My head is buzzing!I have read the official documents for countless times and still can't find the problem!
I don't know anything about these APIs or how they are supposed to be used, but if you use one of my builds, it should give a more descriptive
OSError
instead of aRuntimeError
that may help narrow down the problem.Still no ideas......My head is buzzing!I have read the official documents for countless times and still can't find the problem!
I'm pretty sure the issue in the lack of response from the API is the way we're using it in Python.
@dlech I think you're better to investigate this issue as per my analysis, it is caused by a lack of property setting I believe.
As per: Microsoft's Docs, there needs to be a property set called "Graphics Capture" as indicated in the application manifest. I believe that's causing the Runtime error as Windows doesn't believe the Python application should have such capability to request it. Maybe have Python/WinRT set it?
Please let me know once you've reviewed. The documents further show how the API is meant to be used (if you want to understand).
Checking to see if any progress is made regarding this issue. Please do share any information you have (even if they're temporary fixes).
Hi, may I ask if you found any solution ?
I am trying to make a simple code working, doing nothing else just capturing a window based on its HWND (without picker), but I could not make it work, most probably, because I am dummie.
Any help would be VERY much appreciated.
I encountered the same problem. I think the picker need to be initialize with a handle of new window. (GraphicsCapturePicker Constructor and IInitializeWithWindow::Initialize method )
but IInitializeWithWindow interface is not implemented in any python libraries.
Can anyone fix the picker so that it can be initialized with a hwnd?
Nice find. I guess we could implement a helper method like C#
from winrt._winrt import intialize_with_window
picker = GraphicsPicker()
intialize_with_window(picker, tkinter_window.winfo_id())
...
Or if we can detect this interface in the WinRT metadata, we could have the bindings generator create a
def with_hwnd(self: Self, hwnd: int) -> Self:
...
method that could be used in a chained sort of way:
picker = GraphicsCapturePicker().with_hwnd(tkinter_window.winfo_id())
...
I just pushed a fix to my branch. Tested working with:
import turtle
from winrt._winrt import initialize_with_window
from winrt.windows.foundation import IAsyncOperation, AsyncStatus
from winrt.windows.graphics.capture import GraphicsCapturePicker, GraphicsCaptureItem
def on_pick_completed(op: IAsyncOperation, status: AsyncStatus) -> None:
if status == AsyncStatus.ERROR:
print("error: ", status.error_code.value)
elif status == AsyncStatus.CANCELED:
# this is programatically, canceled, not user canceled
print("operation canceled")
elif status == AsyncStatus.COMPLETED:
result: Optional[GraphicsCaptureItem] = op.get_results()
if result:
print("result:", result.display_name)
else:
print("user canceled")
op.close()
picker = GraphicsCapturePicker()
initialize_with_window(picker, turtle.getcanvas().winfo_id())
op = picker.pick_single_item_async()
op.completed = on_pick_completed
turtle.mainloop()
It can be used with async/await of course, but this was a quick hack to test it using only the standard library.
I just pushed a fix to my branch. Tested working with:
import turtle from winrt._winrt import initialize_with_window from winrt.windows.foundation import IAsyncOperation, AsyncStatus from winrt.windows.graphics.capture import GraphicsCapturePicker, GraphicsCaptureItem def on_pick_completed(op: IAsyncOperation, status: AsyncStatus) -> None: if status == AsyncStatus.ERROR: print("error: ", status.error_code.value) elif status == AsyncStatus.CANCELED: # this is programatically, canceled, not user canceled print("operation canceled") elif status == AsyncStatus.COMPLETED: result: Optional[GraphicsCaptureItem] = op.get_results() if result: print("result:", result.display_name) else: print("user canceled") op.close() picker = GraphicsCapturePicker() initialize_with_window(picker, turtle.getcanvas().winfo_id()) op = picker.pick_single_item_async() op.completed = on_pick_completed turtle.mainloop()It can be used with async/await of course, but this was a quick hack to test it using only the standard library.
It works, thanks, at least it pops up the picker dialogs.
I got ImportError: cannot import name 'initialize_with_window' from 'winrt._winrt'
in winrt latest 1.0.21033.1. Any solution for this? Thanks.
This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.
import turtle
from winsdk._winrt import initialize_with_window
from winsdk.windows.foundation import IAsyncOperation, AsyncStatus
from winsdk.windows.graphics.capture import GraphicsCapturePicker, GraphicsCaptureItem
def on_pick_completed(op: IAsyncOperation, status: AsyncStatus) -> None:
if status == AsyncStatus.ERROR:
print("error: ", status.error_code.value)
elif status == AsyncStatus.CANCELED:
# this is programatically, canceled, not user canceled
print("operation canceled")
elif status == AsyncStatus.COMPLETED:
result: Optional[GraphicsCaptureItem] = op.get_results()
if result:
print("result:", result.display_name)
else:
print("user canceled")
op.close()
picker = GraphicsCapturePicker()
initialize_with_window(picker, turtle.getcanvas().winfo_id())
op = picker.pick_single_item_async()
op.completed = on_pick_completed
turtle.mainloop()
When I applied the above code, the window selection screen appears, but after selecting the window I want to capture, nothing is displayed on the screen. Is there a way to resolve this issue?