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

Windows下Python提取媒体缩略图时open_read_async()调用卡住

解决_winsdk_Windows_Storage_Streams.IRandomAccessStream.open_read_async()调用卡住的问题

以下是针对你遇到的问题的可行解决方案:

1. 等待异步读取操作完成

你的read_stream_into_buffer函数中,readable_stream.read_async()是异步方法但未使用await等待其完成,这会导致缓冲区未被正确填充,甚至引发异步上下文冲突。修改后的函数如下:

async def read_stream_into_buffer(stream_ref, buffer):
    readable_stream = await stream_ref.open_read_async()
    # 添加await等待读取完成
    await readable_stream.read_async(buffer, buffer.capacity, InputStreamOptions.READ_AHEAD)

2. 统一事件循环上下文

连续调用asyncio.run()会创建多个独立的事件循环,WinRT异步操作依赖统一的上下文环境。将整个流程合并到单个异步函数中,仅调用一次asyncio.run():

import winsdk.windows.media.control as wmc
import asyncio
from winsdk.windows.storage.streams import DataReader, Buffer, InputStreamOptions

async def __getMediaSession():
    sessions = await wmc.GlobalSystemMediaTransportControlsSessionManager.request_async()
    session = sessions.get_current_session()
    return session

async def __get_media_info():
    current_session = await __getMediaSession()
    if current_session:
        info = await current_session.try_get_media_properties_async()
        info_dict = {song_attr: info.__getattribute__(song_attr) for song_attr in dir(info) if song_attr[0] != '_'}
        info_dict['genres'] = list(info_dict['genres'])
        return info_dict
    raise Exception('TARGET_PROGRAM is not the current media session')

async def read_stream_into_buffer(stream_ref, buffer):
    readable_stream = await stream_ref.open_read_async()
    await readable_stream.read_async(buffer, buffer.capacity, InputStreamOptions.READ_AHEAD)

async def main():
    media_info = await __get_media_info()
    thumb_stream_ref = media_info['thumbnail']
    
    # 先检查缩略图流是否有效
    if not thumb_stream_ref:
        print("未获取到有效的缩略图流")
        return
        
    thumb_read_buffer = Buffer(5000000)
    await read_stream_into_buffer(thumb_stream_ref, thumb_read_buffer)

    buffer_reader = DataReader.from_buffer(thumb_read_buffer)
    byte_buffer = buffer_reader.read_bytes(thumb_read_buffer.length)

    with open('icon.jpg', 'wb+') as f:
        f.write(bytearray(byte_buffer))

if __name__ == "__main__":
    asyncio.run(main())

3. 验证缩略图流有效性

部分媒体会话可能返回空的缩略图流,在调用异步方法前先判断流是否存在,避免无效调用导致卡住。

4. 适配事件循环兼容性

Python 3.10的asyncio与WinRT的交互可能存在上下文问题,可尝试使用显式事件循环替代asyncio.run():

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

此外,确保winsdk包为最新版本,执行pip install --upgrade winsdk更新依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:04:49