Python中AioRTC单向视频通话报错求助:ValueError: None is not in list
嗨,我看了你遇到的这个问题,这个ValueError: None is not in list的报错其实是因为你手动设置视频轨道的direction时干扰了aiortc的内部逻辑导致的,咱们一步步来把问题解决掉:
一、错误根源分析
报错出现在await pc.setLocalDescription(answer)这一步,原因是你手动给video_track.direction = "sendrecv",而aiortc的VideoStreamTrack对象并不需要开发者手动设置direction——当你把track添加到RTCPeerConnection时,aiortc会自动根据连接的上下文去处理direction参数,手动赋值反而会让内部逻辑计算出None,触发了那个列表查找的错误。
二、具体修改方案
1. 移除手动设置direction的代码
直接删掉这行代码:
video_track.direction = "sendrecv"
这是解决当前ValueError的核心步骤。
2. 修正摄像头检查逻辑,避免资源泄漏
你当前在offer函数里重复创建了一个cv2.VideoCapture(0)实例但没有释放,可能会导致后续真正初始化OpenCVVideoStreamTrack时摄像头被占用。把这段代码替换成:
# 替换原有的摄像头检查代码 temp_cap = cv2.VideoCapture(0) if not temp_cap.isOpened(): temp_cap.release() return web.Response(status=500, text="Eroare la inițializarea camerei. Camera nu este disponibilă.") temp_cap.release() # 释放临时占用的摄像头资源 video_track = OpenCVVideoStreamTrack() pc.addTrack(video_track)
3. 修复Track返回值格式问题
你当前的_get_frame方法返回的是numpy数组,但aiortc的VideoStreamTrack要求返回MediaFrame对象,否则前端接收不到正确的视频流。修改OpenCVVideoStreamTrack的代码:
首先导入MediaFrame:
from aiortc import MediaFrame, VideoStreamTrack
然后修改_get_frame方法:
def _get_frame(self): ret, frame = self.cap.read() if not ret: raise RuntimeError("Eroare la capturarea cadrelor video.") frame = cv2.resize(frame, (640, 480)) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 将numpy数组转换为aiortc要求的MediaFrame return MediaFrame.from_ndarray(frame, format="rgb24")
4. 修复前端CORS问题
你前端代码里设置了mode: "no-cors",这会导致浏览器禁止你读取响应的JSON内容(no-cors模式下响应是opaque的),根本没法解析后端返回的answer。正确的做法是给后端添加CORS支持:
- 先安装aiohttp-cors:
pip install aiohttp-cors
- 然后修改后端的app配置:
from aiohttp_cors import setup, ResourceOptions # 原有的app创建代码 app = web.Application() # 配置全局CORS支持 cors = setup(app, defaults={ "*": ResourceOptions( allow_credentials=True, expose_headers="*", allow_headers="*", ) }) # 给offer路由添加CORS支持 resource = app.router.add_post("/offer", offer) cors.add(resource)
- 最后把前端代码里的
mode: "no-cors"删掉,这样前端就能正常解析后端的JSON响应了。
三、修改后的完整测试
按照上面的步骤修改完后,重新启动后端,复制ngrok生成的URL替换前端的serverUrl,然后打开web.html,应该就能正常建立WebRTC连接并看到摄像头的实时视频流了。
备注:内容来源于stack exchange,提问作者Andrei Arseni

