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

调用my_channel.send致windows-capture与aiortc协同异常问题

解决windows-capture回调中调用aiortc DataChannel.send导致的阻塞与协程未等待问题

问题根源

  • windows-capture的on_frame_arrived是同步阻塞回调,运行在专属的回调线程中。
  • aiortc的DataChannel.send()是异步方法,调用后会返回协程对象。直接在同步回调里调用该方法而不await,会触发RuntimeWarning: coroutine 'RTCSctpTransport._data_channel_flush' was never awaited错误,同时未被调度的协程会阻塞回调线程,导致后续帧回调无法触发(FPS打印停止),仅能发送一次消息。

解决方案

方案一:将异步send操作提交到aiortc的事件循环中

先保存aiortc运行的事件循环对象,在同步回调里通过线程安全的方法将send协程提交到事件循环执行,避免阻塞回调线程。

示例代码:

import asyncio
from windows_capture import WindowsCapture, Frame
from aiortc import RTCPeerConnection, RTCDataChannel

# 保存aiortc依赖的事件循环
main_loop = asyncio.get_event_loop()
data_channel: RTCDataChannel = None

def on_frame_arrived(frame: Frame):
    global data_channel
    # 仅在通道就绪时发送消息
    if data_channel and data_channel.readyState == "open":
        # 线程安全地将协程提交到主事件循环执行
        asyncio.run_coroutine_threadsafe(
            data_channel.send("data sent from on_frame_arrived"),
            main_loop
        )
    # 原有FPS打印逻辑
    ...

# 初始化windows-capture捕获
capture = WindowsCapture(
    on_frame_arrived=on_frame_arrived,
    capture_target=...  # 你的捕获目标配置
)
capture.start()

# aiortc连接处理逻辑
async def setup_peer_connection():
    global data_channel
    pc = RTCPeerConnection()
    data_channel = pc.createDataChannel("frame_data")
    # 发送初始消息
    await data_channel.send("Hello from Python aiortc server!")
    # 后续ICE协商等逻辑
    ...

main_loop.run_until_complete(setup_peer_connection())
main_loop.run_forever()

方案二:改用异步回调(若库支持)

如果windows-capture提供异步回调模式,可直接将on_frame_arrived定义为异步函数,在内部await data_channel.send()即可。但需先确认库是否支持该模式,若不支持则优先使用方案一。

注意事项

  • 必须确保提交协程的事件循环是aiortc正在使用的主事件循环,不要在回调中新建事件循环。
  • 每次发送前检查DataChannel的readyState,避免在通道未打开/已关闭时发送消息。
  • 高帧率场景下可适当控制消息发送频率,避免网络拥塞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:24:55